GHSA-q9pw-vmhh-384g CVE-2026-44335 PYSEC-2026-2950
PraisonAI has an SSRF bypass
- Severity
- 0.0 / 10
- Critical · CVSS 4.0
- Exploit chance (EPSS)
- 0.38%
- Chance of exploitation in the next 30 days. Higher than 31.91% of scored vulnerabilities.
- Known exploited
- No
- Not in CISA's catalog
- Weakness
- CWE-918 Server-Side Request Forgery (SSRF)
- Fix
1.6.32- Upgrade praisonaiagents to this version or later
Description
Summary
The URL checking logic in PraisonAI has a logical flaw that could be bypassed by attackers, leading to SSRF attacks.
Details
The current PraisonAI project uses _validate_url to validate the input URL. The main logic is to perform security checks on the host portion of the URL extracted by urlparse to prevent SSRF attacks.
<img width="1290" height="1145" alt="QQ20260424-151256-24-1" src="https://github.com/user-attachments/assets/d5f16b74-5ad2-444f-8600-b05f78a4b769" />
However, there are indeed differences in parsing between urlparse and the library that actually sends the request. Currently, almost all application scenarios in this project involve first using _validate_url for URL validation, and then using _get_session().get to send the request.
<img width="1143" height="740" alt="QQ20260424-151437-24-2" src="https://github.com/user-attachments/assets/b1bf6ec2-d32a-4dac-b814-da819e8d3c83" />
In reality, its underlying mechanism is requests.get.
<img width="1042" height="576" alt="QQ20260424-151645-24-3" src="https://github.com/user-attachments/assets/e17352c3-4205-44d6-ab6e-75566480215b" />
The core issue: urlparse() and requests disagree on which host a URL like http://127.0.0.1:6666\@1.1.1.1 points to:
urlparse()treats\as a regular character and@as the userinfo-host delimiter, so it extracts hostname as1.1.1.1(public)requeststreats\as a path character, connecting to127.0.0.1(internal)
Below is a test code I wrote following the code.
import sys
from pathlib import Path
from pprint import pprint
sys.path.insert(0, str(Path(r"D:/BaiduNetdiskDownload/PraisonAI-main/PraisonAI-main/src/praisonai-agents")))
from praisonaiagents.tools import spider_tools
# url = "http://127.0.0.1:6666\@1.1.1.1"
url = "http://127.0.0.1:6666"
result = spider_tools.scrape_page(url)
if isinstance(result, dict) and "error" in result:
print("scrape failed:", result["error"])
else:
pprint(result)
When an attacker uses http://127.0.0.1:6666/, the existing detection logic can detect that this is an internal network address and block it.
<img width="1068" height="128" alt="QQ20260424-152007-24-4" src="https://github.com/user-attachments/assets/294bff10-2af6-4960-bf69-dbf3340b1e9b" />
However, when an attacker uses http://127.0.0.1:6666\@1.1.1.1, the detection logic resolves the host to 1.1.1.1, which is a public IP address, thus passing the verification. But in the actual request process, this URL is forwarded by requests.get to http://127.0.0.1:6666, bypassing the detection and achieving an SSRF attack.
<img width="2089" height="324" alt="QQ20260424-152123-24-5" src="https://github.com/user-attachments/assets/4421ce42-e47b-48de-a97a-56ce56a2bbc9" />
PoC
http://127.0.0.1:6666\@1.1.1.1
Impact
SSRF
Affected versions
PyPI
| Package | Vulnerable | Fixed in |
|---|---|---|
| praisonaiagents | < 1.6.32 |
1.6.32 |
How to fix
Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.
praisonaiagents PyPI → 1.6.32
- pip
pip install --upgrade "praisonaiagents>=1.6.32"- poetry
poetry add "praisonaiagents>=1.6.32"- uv
uv add "praisonaiagents>=1.6.32"
Severity breakdown
CVSS 4.0 0.0
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N/E:P
- Attack vector
- Network
- Attack complexity
- Low
- Attack requirements
- None
- Privileges required
- None
- User interaction
- None
- Confidentiality (vulnerable system)
- None
- Integrity (vulnerable system)
- High
- Availability (vulnerable system)
- None
- Confidentiality (subsequent systems)
- None
- Integrity (subsequent systems)
- None
- Availability (subsequent systems)
- None
- Exploit maturity
- Proof of concept
CVSS 3.1 9.8
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
- Attack vector
- Network
- Attack complexity
- Low
- Privileges required
- None
- User interaction
- None
- Scope
- Unchanged
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Weakness
CWE-918: Server-Side Request Forgery (SSRF)
The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.
References
Advisories
Packages
Other links
Timeline
- Published
- Last updated by the source
- Latest EPSS score
Related advisories
| Advisory | Severity | Why it's related |
|---|---|---|
| GHSA-gxmw-5f7x-6g22 praisonaiagents vulnerable to arbitrary file write via unsanitized `user_id` in `FileMemory.__init__()` — path traversal to any writable location | High | Also affects praisonaiagents |
| GHSA-cfxv-8fw8-rwpv praisonaiagents: ast_grep_rewrite rewrites arbitrary files without the @require_approval gate enforced on every sibling mutation tool | Medium | Also affects praisonaiagents |
| GHSA-x44h-65qv-cw74 praisonaiagents has an SSRF protection bypass in `spider_tools._host_is_blocked()` via DNS-resolved hostnames (`127.0.0.1.nip.io`) | High | Also affects praisonaiagents |
| GHSA-7g3p-92qq-8wvh praisonaiagents: AgentServer declares auth_token but never enforces it on any route | High | Also affects praisonaiagents |
| GHSA-5r34-2g38-6569 praisonaiagents web_crawl vulnerable to SSRF via redirect-following | High | Also affects praisonaiagents |
| GHSA-vg6p-v9vm-6fgj praisonaiagents vulnerable to SSRF in web_crawl tool via redirect-following and DNS rebinding (validate-then-fetch gap) | High | Also affects praisonaiagents |
| GHSA-8hjw-25cg-g52h praisonaiagents has a `web_crawl` SSRF protection bypass via unchecked redirect targets | High | Also affects praisonaiagents |
| GHSA-hxmv-c4g6-5fqc PraisonAI workflow include bypasses tools.py autoload opt-in and executes included recipe code | High | Also affects praisonaiagents |
MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.
Check your repos with MergeHarbor