Summary
praisonaiagents vulnerable to SSRF in web_crawl tool via redirect-following and DNS rebinding (validate-then-fetch gap)
The web_crawl tool performs its SSRF check only on the initial URL: it resolves the hostname once
with socket.gethostbyname and rejects private/loopback/link-local results. It then passes the URL to
a fetcher that uses httpx.Client(follow_redirects=True) - or urllib.request.urlopen when httpx is
absent, which also follows redirects - and re-resolves the hostname at connect time, with no further
validation. This validate-here/fetch-there gap is bypassable two independent ways: HTTP redirects and
DNS rebinding.
Affected code: src/praisonai-agents/praisonaiagents/tools/web_crawl_tools.py
- Single-shot validation (lines 229-238):
if os.environ.get("ALLOW_LOCAL_CRAWL") != "true":
ip_str = socket.gethostbyname(hostname) # resolved ONCE, at validation time
ip = ipaddress.ip_address(ip_str)
if ip.is_loopback or ip.is_private or ip.is_link_local or ip.is_multicast or ip.is_unspecified:
continue # rejected
url_list.append(u) - Vulnerable fetch (_crawl_with_httpx, lines 142 / 149): follows redirects, re-resolves DNS, no re-check:
with httpx.Client(follow_redirects=True, timeout=30.0) as client: response = client.get(url)fallback: urllib.request.urlopen(url, timeout=30) (also follows redirects by default) - web_crawl / crawl_web are registered tools (tools/init.py:156-157); httpx is the default fallback
provider (dispatch at web_crawl_tools.py:269).
The two bypasses:
- Redirect: validation approves an attacker domain resolving to a public IP; attacker server replies
302 Location: http://169.254.169.254/... (or any internal host); the fetcher follows it unchecked. - DNS rebinding (TOCTOU): validator's gethostbyname and fetcher's connect-time resolution are
independent; a low-TTL attacker domain answers public to the validator and private/loopback to fetch.
Impact:
An agent with web_crawl - driven by direct input or indirect prompt injection - can be made to read
internal-only HTTP services and cloud instance-metadata endpoints (e.g. IAM credentials), with the
response body returned in the tool output. Scope is Changed because the request pivots into the
internal network.
Proof of concept:
A PoC drives the real web_crawl() (httpx absent -> genuine urllib fallback). It runs a loopback
"internal metadata" service and a loopback attacker redirector, substituting DNS only to stand in
for "attacker owns a public domain" / offline routing - the redirect-following and connect-time
re-resolution are the repo's own behavior. Observed:
CONTROL: web_crawl("http://127.0.0.1:.../meta-data/") -> blocked (validator works)
PoC 1A (redirect): attacker.example approved (public); 302 -> loopback metadata
-> result.content leaks {"AccessKeyId":"ASIA_FAKE_STOLEN_CREDENTIAL_..."}
PoC 1B (rebinding): gethostbyname(rebind.example)->public (allowed); connect->127.0.0.1
-> same secret leaked
The control proves the validator blocks a direct loopback request, so the bypasses are genuine.
Remediation:
Resolve the hostname once, validate that IP, and connect to that exact validated IP (pin it) rather
than re-resolving. Disable redirect following (follow_redirects=False; for urllib use a redirect
handler that re-validates), or re-validate every redirect hop's resolved IP. Apply the deny check to
both the validator and the actual socket target. file_tools.py:364 already uses follow_redirects=False
and is the correct pattern to propagate.
Distinct from prior advisories:
The accepted SSRF advisories concern host-string parsing in different code, alternate loopback
encodings in spider_tools (GHSA-5c6w-wwfq-7qqm) and the CLI @url feature (GHSA-5cxw-77wg-jrf3). This
is in the web_crawl tool, which neither advisory names, and the mechanisms (redirect-following and DNS
rebinding) differ categorically from host-string encoding; the spider_tools _host_is_blocked hardening
does not apply to this tool.
Impact
Untrusted input controls the target URL of a server-initiated request, which may reach internal services not otherwise accessible from outside. Typical impact: access to internal metadata services, internal APIs, or cloud credentials.
CVE-2026-55524 has a CVSS score of 7.5 (High). The vector is network-reachable, no privileges required, and no user interaction. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. A fixed version is available (1.6.58); upgrading removes the vulnerable code path.
Affected versions
Security releases
Kodem intelligence
Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.
Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.
Already deployed Kodem?
See it in your environmentNew to Kodem? Get a demo →Remediation advice
Kodem Kai can prioritize this vulnerability in your dependency tree and generate a fix recommendation.
Frequently Asked Questions
- What is CVE-2026-55524? CVE-2026-55524 is a high-severity server-side request forgery (SSRF) vulnerability in praisonaiagents (pip), affecting versions < 1.6.58. It is fixed in 1.6.58. Untrusted input controls the target URL of a server-initiated request, which may reach internal services not otherwise accessible from outside.
- How severe is CVE-2026-55524? CVE-2026-55524 has a CVSS score of 7.5 (High). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
- Which versions of praisonaiagents are affected by CVE-2026-55524? praisonaiagents (pip) versions < 1.6.58 is affected.
- Is there a fix for CVE-2026-55524? Yes. CVE-2026-55524 is fixed in 1.6.58. Upgrade to this version or later.
- Is CVE-2026-55524 exploitable, and should I be worried? Whether CVE-2026-55524 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
- What actually determines whether CVE-2026-55524 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
- How do I fix CVE-2026-55524? Upgrade
praisonaiagentsto 1.6.58 or later.