PYSEC-2026-468

Vulnerability from pysec - Published: 2026-06-29 11:50 - Updated: 2026-06-29 12:05
VLAI
Details

Summary

OAuthManager.validate_token() returns True for any token not found in its internal store, which is empty by default. Any HTTP request to the MCP server with an arbitrary Bearer token is treated as authenticated, granting full access to all registered tools and agent capabilities.

Details

oauth.py:364 (source) -> oauth.py:374 (loop miss) -> oauth.py:381 (sink)

# source
 def validate_token(self, token: str) -> bool:
    for stored_token in self._tokens.values():
        if stored_token.access_token == token:
            return not stored_token.is_expired()

# sink -- _tokens is empty by default, loop never executes, falls through
    return True

PoC

# install: pip install -e src/praisonai
 # start server: praisonai mcp serve --transport http-stream --port 8080

curl -s -X POST http://127.0.0.1:8080/mcp \
  -H "Authorization: Bearer fake_token_abc123" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"tools/list","id":1}'

# expected output: 200 OK with full tool list (50+ tools)
# including praisonai.agent.run, praisonai.workflow.run, praisonai.containers.file_write
 ```

### Impact

Any unauthenticated attacker with network access to the MCP HTTP server can call all registered tools including agent execution, workflow runs, container file read/write, and skill loading. The server binds to `0.0.0.0` by default with no API key required.

### Suggested Fix
```python
def validate_token(self, token: str) -> bool:
    for stored_token in self._tokens.values():
        if stored_token.access_token == token:
            return not stored_token.is_expired()
    # Unknown tokens must be rejected.
    # For external/JWT tokens, call the introspection endpoint here before returning.
    return False
Impacted products
Name purl
praisonai

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 4.5.96"
      },
      "package": {
        "ecosystem": "PyPI",
        "name": "praisonai"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "4.5.97"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ],
      "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.11",
        "4.5.12",
        "4.5.13",
        "4.5.14",
        "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"
      ]
    }
  ],
  "aliases": [
    "CVE-2026-34953",
    "GHSA-98f9-fqg5-hvq5"
  ],
  "details": "### Summary\n\n`OAuthManager.validate_token()` returns `True` for any token not found in its internal store, which is empty by default. Any HTTP request to the MCP server with an arbitrary Bearer token is treated as authenticated, granting full access to all registered tools and agent capabilities.\n\n### Details\n\n`oauth.py:364` (source) -\u003e `oauth.py:374` (loop miss) -\u003e `oauth.py:381` (sink)\n```python\n# source\n def validate_token(self, token: str) -\u003e bool:\n    for stored_token in self._tokens.values():\n        if stored_token.access_token == token:\n            return not stored_token.is_expired()\n \n# sink -- _tokens is empty by default, loop never executes, falls through\n    return True\n```\n\n### PoC\n```bash\n# install: pip install -e src/praisonai\n # start server: praisonai mcp serve --transport http-stream --port 8080\n\ncurl -s -X POST http://127.0.0.1:8080/mcp \\\n  -H \"Authorization: Bearer fake_token_abc123\" \\\n  -H \"Content-Type: application/json\" \\\n  -d \u0027{\"jsonrpc\":\"2.0\",\"method\":\"tools/list\",\"id\":1}\u0027\n\n# expected output: 200 OK with full tool list (50+ tools)\n# including praisonai.agent.run, praisonai.workflow.run, praisonai.containers.file_write\n ```\n\n### Impact\n\nAny unauthenticated attacker with network access to the MCP HTTP server can call all registered tools including agent execution, workflow runs, container file read/write, and skill loading. The server binds to `0.0.0.0` by default with no API key required.\n\n### Suggested Fix\n```python\ndef validate_token(self, token: str) -\u003e bool:\n    for stored_token in self._tokens.values():\n        if stored_token.access_token == token:\n            return not stored_token.is_expired()\n    # Unknown tokens must be rejected.\n    # For external/JWT tokens, call the introspection endpoint here before returning.\n    return False\n```",
  "id": "PYSEC-2026-468",
  "modified": "2026-06-29T12:05:42.253825Z",
  "published": "2026-06-29T11:50:47.399569Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-98f9-fqg5-hvq5"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-34953"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/MervinPraison/PraisonAI"
    },
    {
      "type": "PACKAGE",
      "url": "https://pypi.org/project/praisonai"
    },
    {
      "type": "ADVISORY",
      "url": "https://github.com/advisories/GHSA-98f9-fqg5-hvq5"
    }
  ],
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "PraisonAI Has Authentication Bypass via OAuthManager.validate_token()"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…