CVE-2026-61429 · GHSA-6g59-gm2v-qhvq
PraisonAI: Crawl4AI/Chromium backend is also affected by the `web_crawl` SSRF validation bypass
- Risk score
- 66/100
- CVSS
- 8.5 v3.1
- Exploit chance (30 days)
- 0.3%
- Published
- 7 Oct 2026
Open in the live forecast Today's forecast
What to know
- What it is
- The DNS-rebinding / redirect SSRF bypass in PRAI-05 is not limited to the httpx/urllib backend. When crawl4ai (headless Chromium via Playwright) is installed, web_crawl auto-selects provider=crawl4ai, and the headless browser re-resolves DNS and follows redirects on its own — with no per-connection SSRF guard. Runtime…
- Affected
- praisonaiagents (pip) <= 1.6.77
- Fix
- Upgrade praisonaiagents to 1.6.78 or later.
- Exploitation
- Public proof of concept
Story map
At a glance
praisonaiagents: Red, act today. CodeAgent._execute_python() executes LLM-generated Python code in a subprocess with the complete parent-process environment (os.environ.copy()), zero AST validation, zero import restrictions, and no sandbox enforcement — even when CodeConfig(sandbox=True) is explicitly set. This allows an attacker who can influence LL…
The flaws
- CVE-2026-61429: PraisonAI: Crawl4AI/Chromium backend is also affected by the `web_crawl` SSRF validation bypass (CVSS 8.5 · EPSS 0%)
- CVE-2026-61447: PraisonAI: CodeAgent Executes LLM-Generated Code Without Sandboxing and Leaks All Environment Secrets (CVSS 10.0 · EPSS 2%)
- CVE-2026-61430: PraisonAI: DNS rebinding bypass in `web_crawl` SSRF protection allows internal response disclosure (CVSS 8.5 · EPSS 0%)
- CVE-2026-61446: PraisonAI: Plugin Auto-Discovery Executes Arbitrary Python Files Without Verification (CVSS 8.4 · EPSS 0%)
The fix
Upgrade praisonaiagents: 1.6.78 or later on your release line
Who is exposed: praisonaiagents (pip) <= 1.6.77
Where it stands
- Public proof of concept
Connects to
- Same weakness: Information disclosure (CWE-200). 195 other warnings in 30 days
Why it is Amber
- CVSS 8.5 high
- Public exploit or proof of concept referenced
- On your watchlist: PyPI
Affected packages
| Package | Ecosystem | Vulnerable | Fixed in |
|---|---|---|---|
| praisonaiagents | pip | <= 1.6.77 | 1.6.78 |
References
- https://github.com/advisories/GHSA-6g59-gm2v-qhvq
- https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-6g59-gm2v-qhvq
- https://nvd.nist.gov/vuln/detail/CVE-2026-61429
- https://www.vulncheck.com/advisories/praisonai-before-ssrf-via-crawl4ai-chromium-backend
- https://github.com/advisories/GHSA-6g59-gm2v-qhvq
Original description
## Summary The DNS-rebinding / redirect SSRF bypass in PRAI-05 is **not limited to the httpx/urllib backend**. When `crawl4ai` (headless Chromium via Playwright) is installed, `web_crawl` auto-selects `provider=crawl4ai`, and the headless browser re-resolves DNS and follows redirects on its own — with no per-connection SSRF guard. Runtime-confirmed read-back of the internal canary via both DNS rebinding and redirect (`provider: "crawl4ai"`). Status: runtime-confirmed addendum to PRAI-05. ## Details ### Affected component - Package `praisonaiagents` 4.6.63. Backend selected when `crawl4ai`+Playwright are installed. - Files: `src/praisonai-agents/praisonaiagents/tools/web_crawl_tools.py` (`_crawl_with_crawl4ai`) and `src/praisonai-agents/praisonaiagents/tools/crawl4ai_tools.py` (standalone crawl wrappers). ### Vulnerable code / root cause Path: `src/praisonai-agents/praisonaiagents/tools/web_crawl_tools.py` Function: `_crawl_with_crawl4ai` Snippet: ```python async with AsyncWebCrawler() as crawler: for url in urls: result = await crawler.arun(url=url) # headless browser: re-resolves DNS, follows redirects ``` Path: `src/praisonai-agents/praisonaiagents/tools/crawl4ai_tools.py` Function: `Crawl4AITools.crawl` / `crawl4ai` Snippet: ```python result = await crawler.arun(url=url, config=config) # no _is_safe_crawl_url / no per-connect validation ``` Issue: the only SSRF check is the single pre-fetch `_is_safe_crawl_url()` on the initial URL string in `web_crawl()` (see PRAI-05). The headless browser then resolves and connects independently and follows redirects in-browser — no resolved-IP pinning, no per-hop/per-connect validation. Input (`urls`) is attacker/agent-controlled; the sink is `crawler.arun(url=...)`; the guard is bypassed by DNS rebinding (TOCTOU) and by redirects (followed in-browser). ### Attack flow / Why bypassed / Security boundary Identical to PRAI-05: TOCTOU between the guard's resolution and the browser's connection; redirects followed in-browser; internal response returned as crawl `content`. See PRAI-05. ## Proof of Concept ### Environment `crawl4ai` + Playwright Chromium installed in a dedicated runtime container (`127.0.0.1:18081`), same controlled internal canary + rebinding DNS. Runnable assets: `PraisonAI-Runtime-Repro\runtime-files\` (`docker-compose.crawl.yml`). ### Steps to reproduce 1. `SSRF-04-01-Crawl4AI-DNS-Rebind-Trigger` → `127.0.0.1:18081`: ```http POST /tool/web_crawl HTTP/1.1 Host: 127.0.0.1:18081 Content-Type: application/json {"url":"http://rebind.lab:8081/secret"} ``` 2. Redirect variant `SSRF-04-03-Crawl4AI-Redirect-Readback`: `{"url":"http://redirector:8082/redirect-to-internal"}`. ### Expected result The crawl backend refuses internal destinations regardless of DNS timing/redirects. ### Actual result HTTP 200, `"provider":"crawl4ai"`, response `content` contains `PRAISONAI_INTERNAL_SECRET_CANARY_7f3a91` + `FAKE_INTERNAL_TOKEN_DO_NOT_USE_7f3a91` for both the DNS-rebinding and the redirect payload. ### Screenshots **Crawl4AI DNS rebinding read-back** The attacker-controlled `rebind.lab` URL is accepted by the Crawl4AI-backed `web_crawl` endpoint. PraisonAI returns the internal canary response body containing `PRAISONAI_INTERNAL_SECRET_CANARY_7f3a91`. <img width="1542" height="763" alt="01-Crawl4AI-Burp-Readback" src="https://github.com/user-attachments/assets/a03b3a1c-e382-4f67-8ea6-b766dceb4a69" /> **Crawl4AI DNS rebinding runtime evidence** The runtime log shows the Crawl4AI/Chromium backend resolving `rebind.lab` to an internal Docker IP during the fetch phase. The internal canary receives `GET /secret` from a headless Chrome user agent. <img width="1659" height="946" alt="02-Crawl4AI-DNS-Log-And-Internal-Hit" src="https://github.com/user-attachments/assets/d93db090-3e39-43d0-af3b-5d1d8f614db8" /> **Crawl4AI redirect read-back** The attacker-controlled redirector URL is accepted by the Crawl4AI-backed endpoint. PraisonAI follows the redirect and returns the internal canary response body. <img width="1544" height="771" alt="03-Crawl4AI-Redirect-Readback" src="https://github.com/user-attachments/assets/7d05c8aa-5bda-45bc-b94c-bef0bdcf055c" /> **Crawl4AI redirect runtime evidence** The controlled redirector returns `302 -> http://internal-canary:8081/secret`, and the internal canary receives `GET /secret` from the Crawl4AI/Chromium backend. <img width="1590" height="920" alt="04-Crawl4AI-Redirect-Internal-Hit-Log" src="https://github.com/user-attachments/assets/dd9c0fec-3583-43ab-b83c-4470fa6aa409" /> ## Impact Same class as PRAI-05: read-back SSRF to internal/metadata services, now on the crawl4ai backend. Broadens the affected surface (the flaw is in the shared validate-without-pinning design, not one backend). ## Suggested remediation Resolve-once + IP-pin + per-connect validation must also cover the crawl4ai backend (constrain the headless browser to the validated IP, or allowlist crawl destinations).
Last activity 7 Oct 2026. Patch Forecast updates every hour.