CVE-2026-55528
praisonaiagents: AgentServer declares auth_token but never enforces it on any route (CWE-862)
PraisonAI is a multi-agent teams system. Prior to praisonaiagents 1.6.58, AgentServer exposes ServerConfig.auth_token but AgentServer._create_app does not check it on any route. A remote caller can subscribe, publish, and perform other actions without a valid bearer token or X-Auth-Token even when authentication is configured. This issue is fixed in version 1.6.58.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- Low
- Integrity
- High
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
8.2
praisonaiagents: AgentServer declares auth_token but never enforces it on any route (CWE-862)
PraisonAI is a multi-agent teams system. Prior to praisonaiagents 1.6.58, AgentServer exposes ServerConfig.auth_token but AgentServer._create_app does not check it on any route. A remote caller can subscribe, publish, and perform other actions without a valid bearer token or X-Auth-Token even when authentication is configured. This issue is fixed in version 1.6.58.
- Record
CVE-2026-55528- CVSS 3.1
- 8.2 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N - Weakness
- CWE-306, CWE-862
- Updated
- 2026-11-02
EUVDEUVD-2026-65497
8.2
PraisonAI is a multi-agent teams system. Prior to praisonaiagents 1.6.58, AgentServer exposes ServerConfig.auth_token but AgentServer._create_app does not check it on any route. A remote caller can subscribe, publish, and perform other actions without a valid bearer token or X-Auth-Token even when authentication is configured. This issue is fixed in version 1.6.58.
- Record
EUVD-2026-65497- CVSS 3.1
- 8.2 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-7g3p-92qq-8wvh
8.2
praisonaiagents: AgentServer declares auth_token but never enforces it on any route
Researcher: Kai Aizen — SnailSploit (@SnailSploit), Adversarial & Offensive Security Research Target: https://github.com/MervinPraison/PraisonAI
Package: praisonaiagents on PyPI
Affected version (empirically tested): 1.6.48
Component: praisonaiagents.server.AgentServer (the bundled HTTP / SSE server)
TL;DR
AgentServer.ServerConfig advertises an auth_token: Optional[str] = None field that operators set when they want to lock down the server. The GET /info endpoint even displays it back as "auth_token": "***" — strongly implying the value is wired into request authentication.
It isn't. AgentServer._create_app never reads auth_token, never adds an authentication middleware, and never decorates any route with a dependency that checks it. Every route — /info, /publish, /events, /health — accepts unauthenticated requests regardless of whether auth_token is configured.
The same package contains a sibling server, praisonaiagents.ui.a2a.A2A, written by the same developer, which implements the bearer-token pattern correctly via FastAPI's Depends(_verify_auth). This rules out the "auth is not yet implemented; operators are expected to add it" reading: the developer knew the pattern but did not apply it to AgentServer.
Root cause
Expected behavior when setting ServerConfig(auth_token="…"):
"Only requests with a matching Authorization header will be
accepted on /publish, /events, /info."
Actual behavior (server/server.py, dist 1.6.48):
- line 31 auth_token: Optional[str] = None # declared
- line 39 "auth_token": "***" if self.auth_token else None # displayed
- lines 122-204: no auth middleware, no Depends, no
request.headers["Authorization"] read,
no comparison to self.config.auth_token.
Impact:
The configuration knob is dead code from the route handlers'
perspective. All routes always run. The operator has no signal
that their auth_token was discarded — /info even confirms it
was received by displaying "***".
Sibling proof — the same package gets it right elsewhere
praisonaiagents/ui/a2a/a2a.py:
# line 163
async def _verify_auth(authorization: Optional[str] = Header(None)):
"""Verify bearer token if auth_token is configured."""
if self.auth_token is None:
return
...
if len(parts) != 2 or parts[0].lower() != "bearer" \
or parts[1] != self.auth_token:
raise HTTPException(status_code=401, ...)
# line 192
from fastapi import Depends
_a2a_deps = [Depends(_verify_auth)] if self.auth_token else []
That is the missing implementation. Porting it to AgentServer — either via Starlette BaseHTTPMiddleware or by switching to FastAPI and adding Depends(_verify_auth) to each route — closes the gap.
Affected routes (empirically tested)
| Route | Method | Accepts unauth requests? | Impact |
|-------------|--------|--------------------------|------------------------------------------------------------------------|
| /info | GET | Yes (200) | Leaks server config; confirms auth_token is set ("***"); reveals client count and CORS config. |
| /publish | POST | Yes (200) | Anyone broadcasts arbitrary {type, data} to every subscribed agent. Event payload is whatever the attacker sends. |
| /events | GET | Yes (200) | Anyone subscribes to the SSE stream and observes every event published by the server (and by any other anonymous attacker). |
| /health | GET | Yes (200) | Leaks live SSE client count. |
Impact
The /publish and /events routes are the load-bearing ones. Together they let an unauthenticated network-adjacent attacker:
- Inject control events…
- Record
GHSA-7g3p-92qq-8wvh- CVSS 3.1
- 8.2 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N - Weakness
- CWE-306, CWE-862
- Updated
- 2026-11-02
NVD
8.2
PraisonAI is a multi-agent teams system. Prior to praisonaiagents 1.6.58, AgentServer exposes ServerConfig.auth_token but AgentServer._create_app does not check it on any route. A remote caller can subscribe, publish, and perform other actions without a valid bearer token or X-Auth-Token even when authentication is configured. This issue is fixed in version 1.6.58.
- Record
CVE-2026-55528- CVSS 3.1
- 8.2 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N - Weakness
- CWE-306, CWE-862
- Updated
- 2026-11-02
OSV
8.2
praisonaiagents: AgentServer declares auth_token but never enforces it on any route (CWE-862)
PraisonAI is a multi-agent teams system. Prior to praisonaiagents 1.6.58, AgentServer exposes ServerConfig.auth_token but AgentServer._create_app does not check it on any route. A remote caller can subscribe, publish, and perform other actions without a valid bearer token or X-Auth-Token even when authentication is configured. This issue is fixed in version 1.6.58.
- Record
CVE-2026-55528- CVSS 3.1
- 8.2 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N - Weakness
- CWE-306, CWE-862
- Updated
- 2026-11-02
OSVGHSA-7g3p-92qq-8wvh
8.2
praisonaiagents: AgentServer declares auth_token but never enforces it on any route
Researcher: Kai Aizen — SnailSploit (@SnailSploit), Adversarial & Offensive Security Research Target: https://github.com/MervinPraison/PraisonAI
Package: praisonaiagents on PyPI
Affected version (empirically tested): 1.6.48
Component: praisonaiagents.server.AgentServer (the bundled HTTP / SSE server)
TL;DR
AgentServer.ServerConfig advertises an auth_token: Optional[str] = None field that operators set when they want to lock down the server. The GET /info endpoint even displays it back as "auth_token": "***" — strongly implying the value is wired into request authentication.
It isn't. AgentServer._create_app never reads auth_token, never adds an authentication middleware, and never decorates any route with a dependency that checks it. Every route — /info, /publish, /events, /health — accepts unauthenticated requests regardless of whether auth_token is configured.
The same package contains a sibling server, praisonaiagents.ui.a2a.A2A, written by the same developer, which implements the bearer-token pattern correctly via FastAPI's Depends(_verify_auth). This rules out the "auth is not yet implemented; operators are expected to add it" reading: the developer knew the pattern but did not apply it to AgentServer.
Root cause
Expected behavior when setting ServerConfig(auth_token="…"):
"Only requests with a matching Authorization header will be
accepted on /publish, /events, /info."
Actual behavior (server/server.py, dist 1.6.48):
- line 31 auth_token: Optional[str] = None # declared
- line 39 "auth_token": "***" if self.auth_token else None # displayed
- lines 122-204: no auth middleware, no Depends, no
request.headers["Authorization"] read,
no comparison to self.config.auth_token.
Impact:
The configuration knob is dead code from the route handlers'
perspective. All routes always run. The operator has no signal
that their auth_token was discarded — /info even confirms it
was received by displaying "***".
Sibling proof — the same package gets it right elsewhere
praisonaiagents/ui/a2a/a2a.py:
# line 163
async def _verify_auth(authorization: Optional[str] = Header(None)):
"""Verify bearer token if auth_token is configured."""
if self.auth_token is None:
return
...
if len(parts) != 2 or parts[0].lower() != "bearer" \
or parts[1] != self.auth_token:
raise HTTPException(status_code=401, ...)
# line 192
from fastapi import Depends
_a2a_deps = [Depends(_verify_auth)] if self.auth_token else []
That is the missing implementation. Porting it to AgentServer — either via Starlette BaseHTTPMiddleware or by switching to FastAPI and adding Depends(_verify_auth) to each route — closes the gap.
Affected routes (empirically tested)
| Route | Method | Accepts unauth requests? | Impact |
|-------------|--------|--------------------------|------------------------------------------------------------------------|
| /info | GET | Yes (200) | Leaks server config; confirms auth_token is set ("***"); reveals client count and CORS config. |
| /publish | POST | Yes (200) | Anyone broadcasts arbitrary {type, data} to every subscribed agent. Event payload is whatever the attacker sends. |
| /events | GET | Yes (200) | Anyone subscribes to the SSE stream and observes every event published by the server (and by any other anonymous attacker). |
| /health | GET | Yes (200) | Leaks live SSE client count. |
Impact
The /publish and /events routes are the load-bearing ones. Together they let an unauthenticated network-adjacent attacker:
- Inject control events…
- Record
GHSA-7g3p-92qq-8wvh- CVSS 3.1
- 8.2 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N - Weakness
- CWE-306, CWE-862
- Updated
- 2026-11-02
OSVPYSEC-2026-3899
8.2
praisonaiagents: AgentServer declares auth_token but never enforces it on any route
Researcher: Kai Aizen — SnailSploit (@SnailSploit), Adversarial & Offensive Security Research Target: https://github.com/MervinPraison/PraisonAI
Package: praisonaiagents on PyPI
Affected version (empirically tested): 1.6.48
Component: praisonaiagents.server.AgentServer (the bundled HTTP / SSE server)
TL;DR
AgentServer.ServerConfig advertises an auth_token: Optional[str] = None field that operators set when they want to lock down the server. The GET /info endpoint even displays it back as "auth_token": "***" — strongly implying the value is wired into request authentication.
It isn't. AgentServer._create_app never reads auth_token, never adds an authentication middleware, and never decorates any route with a dependency that checks it. Every route — /info, /publish, /events, /health — accepts unauthenticated requests regardless of whether auth_token is configured.
The same package contains a sibling server, praisonaiagents.ui.a2a.A2A, written by the same developer, which implements the bearer-token pattern correctly via FastAPI's Depends(_verify_auth). This rules out the "auth is not yet implemented; operators are expected to add it" reading: the developer knew the pattern but did not apply it to AgentServer.
Root cause
Expected behavior when setting ServerConfig(auth_token="…"):
"Only requests with a matching Authorization header will be
accepted on /publish, /events, /info."
Actual behavior (server/server.py, dist 1.6.48):
- line 31 auth_token: Optional[str] = None # declared
- line 39 "auth_token": "***" if self.auth_token else None # displayed
- lines 122-204: no auth middleware, no Depends, no
request.headers["Authorization"] read,
no comparison to self.config.auth_token.
Impact:
The configuration knob is dead code from the route handlers'
perspective. All routes always run. The operator has no signal
that their auth_token was discarded — /info even confirms it
was received by displaying "***".
Sibling proof — the same package gets it right elsewhere
praisonaiagents/ui/a2a/a2a.py:
# line 163
async def _verify_auth(authorization: Optional[str] = Header(None)):
"""Verify bearer token if auth_token is configured."""
if self.auth_token is None:
return
...
if len(parts) != 2 or parts[0].lower() != "bearer" \
or parts[1] != self.auth_token:
raise HTTPException(status_code=401, ...)
# line 192
from fastapi import Depends
_a2a_deps = [Depends(_verify_auth)] if self.auth_token else []
That is the missing implementation. Porting it to AgentServer — either via Starlette BaseHTTPMiddleware or by switching to FastAPI and adding Depends(_verify_auth) to each route — closes the gap.
Affected routes (empirically tested)
| Route | Method | Accepts unauth requests? | Impact |
|-------------|--------|--------------------------|------------------------------------------------------------------------|
| /info | GET | Yes (200) | Leaks server config; confirms auth_token is set ("***"); reveals client count and CORS config. |
| /publish | POST | Yes (200) | Anyone broadcasts arbitrary {type, data} to every subscribed agent. Event payload is whatever the attacker sends. |
| /events | GET | Yes (200) | Anyone subscribes to the SSE stream and observes every event published by the server (and by any other anonymous attacker). |
| /health | GET | Yes (200) | Leaks live SSE client count. |
Impact
The /publish and /events routes are the load-bearing ones. Together they let an unauthenticated network-adjacent attacker:
- Inject control events…
- Record
PYSEC-2026-3899- CVSS 3.1
- 8.2 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N - Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
praisonaiagentsPyPI |
before 1.6.58 | 1.6.58 |
praisonaiagentsPyPI |
before 1.6.58, plus listed versions 0.0.10.0.100.0.1000.0.1010.0.102 Show 45 moreShow less0.0.1030.0.1040.0.1050.0.1060.0.1070.0.1080.0.1090.0.110.0.1100.0.1110.0.1120.0.1130.0.1140.0.1150.0.1160.0.1170.0.1180.0.1190.0.120.0.1200.0.1210.0.1220.0.1230.0.1240.0.1250.0.1260.0.1270.0.1280.0.1290.0.130.0.1300.0.1310.0.1320.0.1330.0.1340.0.1350.0.1360.0.1370.0.1380.0.1390.0.140.0.1400.0.1410.0.1420.0.143 |
1.6.58 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-55528 is a high vulnerability (CVSS 8.2) in Mervinpraison Praisonai, published August 25, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.49%, the 42nd percentile. Fixed in praisonaiagents 1.6.58.
References
github.com/MervinPraison/PraisonAI/security/advisories/GHSA-7g3p-92qq-8wvh
github.com/MervinPraison/PraisonAI/commit/2f9677abb2ea68eab864ee8b6a828fd0141612e1
github.com/MervinPraison/PraisonAI/releases/tag/v4.6.58
github.com/advisories/GHSA-7g3p-92qq-8wvh
github.com/CVEProject/cvelistV5/tree/main/cves/2026/55xxx/CVE-2026-55528.json
nvd.nist.gov/vuln/detail/CVE-2026-55528
github.com/MervinPraison/PraisonAI
pypi.org/project/praisonaiagents
Left out here: 535 versions and the rest of 3 source descriptions. The JSON record has them.