GHSA-j4hj-7hfh-g2f4
# praisonai: `recipe serve` authentication middleware silently disables itself when no secret is set **Researcher:** Kai Aizen — SnailSploit (@SnailSploit), Adversarial & Offensive Security Research **Target:** https://github.com/MervinPraison/PraisonAI --- **Package:** `praisonai` on PyPI **Version tested:** 4.6.48. **File:** `praisonai/recipe/serve.py` (sha256 `491bf8f29e399418260810ba4bf0f6802c6e4aa675628e2be68a9726c15d9b23`). --- ## TL;DR `praisonai/recipe/serve.py:312-410` defines two auth middlewares (`APIKeyAuthMiddleware`, `JWTAuthMiddleware`). Both contain the same "fail open when the secret is unset" branch at the top of their `dispatch`: ```python async def dispatch(self, request, call_next): if request.url.path == "/health": return await call_next(request) expected_key = api_key or os.environ.get("PRAISONAI_API_KEY") if not expected_key: # No key configured, allow request return await call_next(request) ... ``` ```python async def dispatch(self, request, call_next): if request.url.path == "/health": return await call_next(request) secret = jwt_secret or os.environ.get("PRAISONAI_JWT_SECRET") if not secret: return await call_next(request) ... ``` The realistic mis-deploy: 1. operator sets `auth: api-key` (or `auth: jwt`) in their recipe YAML, expecting that line alone to enable auth, 2. operator does not set the corresponding `api_key:` / `jwt_secret:` value in the same YAML, AND 3. operator does not export `PRAISONAI_API_KEY` / `PRAISONAI_JWT_SECRET` in the environment. The middleware silently treats every request as authenticated and forwards it to the recipe-execution route. Combined with the praisonai jobs API having zero auth (a separate finding), operators who paid attention to "I have to set `auth: api-key` to lock this down" still don't get auth on the recipe-serve surface unless they also remember the secret. ## Root cause ``` Expected behavior, after setting
Properties
- ghsa_id
- GHSA-j4hj-7hfh-g2f4
- severity
- critical
- summary
- praisonai: recipe serve auth middleware silently disables itself when no secret is set
- cvss_score
- 9.8
- cve_id
- GHSA-j4hj-7hfh-g2f4
- cvss_vector
- CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
- is_ghsa_only
- true
- ghsa_published
- 2026-06-18T13:56:55Z
- source_url
- https://github.com/advisories/GHSA-j4hj-7hfh-g2f4
- ghsa_updated
- 2026-06-18T13:56:55Z
Related Entities (5)
REPORTED_BY (1)
VULNERABLE_TO (1)
AFFECTS (1)
HAS_WEAKNESS (2)
Explore deeper with Ninja Signal's threat intelligence graph