~/f4n6 $ grep -r "praisonaiagents has a `web_crawl` SSRF protection bypass via unchecked redirect targets" ./investigations/ --include="*.md"

praisonaiagents has a `web_crawl` SSRF protection bypass via unchecked redirect targets

Jeff Davies 25 Aug 2026 8 min read

1. Executive summary

GitHub published GHSA-8hjw-25cg-g52h, identified there as CVE-2026-55523, describing a server-side request forgery bypass in praisonaiagents.web_crawl() caused by unchecked HTTP redirect targets. The reporter validated praisonaiagents 1.5.128, 1.6.40, 1.6.56 and repository commit 095653d78a01cc6c80ff5b2dd20a8e5619686ddc as affected; no patched release was known at submission. The supplied verified reference applies to the underlying published SSRF class, CVE-2026-40160: CVSS 7.1 HIGH, NOT in CISA KEV, EPSS 0%, CWE-918; no verified score or KEV state was supplied for CVE-2026-55523, so those values must not be transferred to it. An attacker able to influence a model-callable crawl target can redirect the PraisonAI runtime to loopback, private-network or cloud-metadata HTTP services and return the response body into the agent context. No in-the-wild exploitation, RCE, authentication bypass, threat-actor attribution or live cloud-credential theft is established by the supplied material.

2. Regulatory framing

No specific DORA/NIS2 article is directly engaged by this item. The supplied material establishes a vulnerability and local proof of vulnerability, not an operational incident, reportable impact or service disruption establishing an item-specific UK NIS 2018 trigger.

3. Technical analysis & attack chain

The relevant verified classification for the underlying SSRF class is CVE-2026-40160 — CVSS 7.1 HIGH — NOT in CISA KEV — EPSS 0% — CWE-918. The primary advisory identifies the redirect bypass as CVE-2026-55523 and describes it as an incomplete fix or patch bypass for CVE-2026-40160. These identifiers are related but not interchangeable.

Confirmed attack chain

  1. Invocation prerequisite: web_crawl() is called with an attacker-influenced HTTP or HTTPS URL. The influence may be direct through an agent task or indirect through prompt-injected content, but invocation of the tool is required; the flaw does not independently provide remote initial access.
  2. Initial validation: web_crawl() extracts the initial hostname, resolves it once with socket.gethostbyname() and checks that result. Unless ALLOW_LOCAL_CRAWL=true, loopback, private, link-local, multicast and unspecified destinations are rejected.
  3. Allowed first hop: A public-looking attacker-controlled URL resolves to an address accepted by the initial check. The server then returns an HTTP 302 response whose Location points to a restricted destination such as 127.0.0.1, a private-network service or 169.254.169.254.
  4. Unchecked redirect: _crawl_with_httpx() creates httpx.Client(follow_redirects=True, timeout=30.0) and calls client.get(url). Neither intermediate nor final redirect destinations are passed through the SSRF validator.
  5. Internal request and disclosure: The PraisonAI host requests the internal destination using its own network position. The response body is placed in the content field returned by web_crawl() and can consequently enter agent context, tool logs or downstream processing.
  6. Control confirmation: The local proof of vulnerability showed a direct request to loopback being blocked, while a public-looking first hop redirecting to the same loopback service returned INTERNAL-SECRET-FROM-LOOPBACK. Disabling redirect following allowed the redirector request but prevented the internal-service request.

Affected component and versions

  • Package: praisonaiagents
  • File: src/praisonai-agents/praisonaiagents/tools/web_crawl_tools.py
  • Functions: web_crawl() and _crawl_with_httpx()
  • Validated by the primary report:
  • Package 1.5.128, repository tag v4.5.128
  • Package 1.6.40, repository tag v4.6.40
  • Package 1.6.56, repository tag v4.6.56
  • origin/main commit 095653d78a01cc6c80ff5b2dd20a8e5619686ddc
  • Suggested range: >=1.5.128, <=1.6.56; maintainer confirmation was pending.
  • A related report also reproduces the redirect condition against 1.6.52 and reports that httpx is the default provider on a standard installation.

The reporter used:

env PYTHONPATH=src/praisonai-agents uv run --with httpx poc_web_crawl_redirect_ssrf.py

Root cause

The security decision applies only to the initial URL:

ip_str = socket.gethostbyname(hostname)
ip = ipaddress.ip_address(ip_str)

The fetch sink subsequently follows redirects without enforcing the same decision:

with httpx.Client(follow_redirects=True, timeout=30.0) as client:
    response = client.get(url)

This creates a validation/fetch mismatch: the address approved by the guard is not necessarily the address contacted. socket.gethostbyname() also does not bind the later connection to the validated address.

A separate related advisory reports that the urllib.request.urlopen() fallback also follows redirects and that the independent resolution performed at connection time permits DNS rebinding. Those additional paths are single-sourced and were not exercised by the primary redirect PoV; verify before enforcement.

Capability and impact boundaries

  • Data access: Confirmed locally for an unauthenticated loopback HTTP resource. Private services and cloud metadata are reachable only where network routing and target-side controls permit them.
  • Data return: Confirmed; internal response content is returned by web_crawl().
  • Reconnaissance: The primitive can probe internal HTTP services, although the supplied sources do not demonstrate an automated scanner.
  • Credential access: Cloud metadata credentials are a plausible deployment-specific target, but no live credential theft was demonstrated.
  • Persistence, privilege escalation, malware execution, C2 and lateral movement: Not reported.
  • RCE and authentication bypass: Explicitly not claimed.
  • Observed exploitation: No campaign or in-the-wild exploitation evidence was supplied.
  • Attribution: No threat actor is named; no attribution is made.

The exact affected range, repository-state assertion and primary PoV output are single-sourced to GHSA-8hjw-25cg-g52h; verify before enforcement. The redirect mechanism itself is corroborated by multiple supplied GitHub advisory reports.

4. Mitigation & containment

P1 — within 24 hours

  • Inventory every environment containing praisonaiagents, recording the installed package version and whether web_crawl or crawl_web is registered in an agent-accessible toolset. Prioritise deployments that process untrusted prompts, retrieved web content or user-supplied URLs.
  • Remove or disable web_crawl from agent toolsets until a fixed implementation is deployed. Where business use prevents this, restrict inputs to an explicit destination allowlist and require approval before crawling externally supplied URLs.
  • For locally maintained builds, change the client construction in src/praisonai-agents/praisonaiagents/tools/web_crawl_tools.py to:
with httpx.Client(follow_redirects=False, timeout=30.0) as client:

Treat any 3xx response as blocked unless each Location target is separately resolved and validated.

  • Keep ALLOW_LOCAL_CRAWL unset or different from "true". This preserves direct-address blocking but does not remediate the redirect bypass.
  • Enforce runtime egress restrictions preventing the PraisonAI process or container from reaching loopback services, RFC1918 networks, link-local destinations and 169.254.169.254, except for explicitly required destinations. Apply controls at the workload or egress-proxy layer; perimeter-only filtering will not contain loopback access.
  • Preserve agent transcripts, web_crawl results, proxy logs, DNS telemetry and workload network events. Hunt for public crawl requests immediately followed by connections to loopback, private or link-local addresses.

P2 — within 72 hours

  • If redirect support is required, implement manual redirect handling and validate every Location hop before connection. Reject loopback, private, link-local, reserved, multicast, unspecified and cloud-metadata destinations.
  • Replace single-result socket.gethostbyname() validation with socket.getaddrinfo() and reject the destination if any usable A or AAAA result is prohibited.
  • Eliminate the validate-then-resolve gap by binding the connection to the validated address or otherwise verifying the actual socket destination. Apply the same controls to the reported urllib fallback; changing providers alone is not a reliable mitigation.
  • Add regression tests for:
  • Direct loopback rejection
  • Public-to-loopback redirect rejection
  • Public-to-private and public-to-link-local redirect rejection
  • Public-to-public redirects, if supported
  • Multiple DNS answers and DNS changes between validation and connection
  • If retrospective review finds cloud metadata or credential-bearing internal responses in tool output, revoke and rotate the specifically exposed credentials and remove copies from transcripts, logs and downstream stores.

P3 — within seven days

  • Deploy the maintainer’s fixed release when one is identified and validate the corrected redirect and DNS behaviour before restoring the tool. No fixed version was known in the supplied source; do not infer that a later version is safe solely from its number.
  • Route agent web retrieval through a dedicated egress proxy with destination-class enforcement and complete redirect-chain logging.
  • Separate agent runtimes from management interfaces and sensitive internal HTTP services. Require authentication on internal services rather than relying on network location alone.
  • Audit other server-side fetch tools for initial-only validation, automatic redirects and independent DNS resolution. Incorporate these cases into dependency-security and agent-tool acceptance tests.

5. Indicators of compromise

No indicators of compromise available in the source material.

The example hosts, ports, metadata paths and response strings are proof-of-vulnerability artefacts, not observed malicious infrastructure. The exact version range and primary PoV output are single-sourced; verify before enforcement.

Behavioural indicators

behaviour where to observe confidence
A public web_crawl() target returns 302 Location pointing to hxxp://127[.]0[.]0[.]1:<port>/secret, a private address or hxxp://169[.]254[.]169[.]254/latest/meta-data/iam/security-credentials/<role> HTTP proxy logs, packet capture, application HTTP tracing High; mechanism corroborated by multiple supplied reports
The PraisonAI workload connects to loopback, private or link-local HTTP services immediately after crawling a public URL EDR network events, container telemetry, host firewall and egress-proxy logs High when such access is not operationally expected
A result whose initial url is external contains internal-service data in content and reports provider: httpx Agent transcripts, tool-call audit logs and application logs High for the reported code path
Separate validation-time and connection-time DNS lookups return public and private/loopback addresses DNS resolver logs and instrumented application traces Medium; DNS-rebinding path is single-sourced and separate from the primary PoV

6. Detection

The YARA rule is intended for raw HTTP captures or stored proxy artefacts. It detects the two concrete malicious redirect-target forms present in the supplied reports; it does not cover arbitrary internal hostnames.

rule AT_2026_08_25_645_PraisonAI_WebCrawl_SSRF_Redirect
{
    meta:
        author = "Adverse Trace"
        date = "2026-08-25"
        reference = "https://github.com/advisories/GHSA-8hjw-25cg-g52h"
        description = "Detects HTTP redirect headers targeting loopback or cloud metadata paths used in the reported web_crawl SSRF demonstrations"

    strings:
        $redirect_loopback = /Location:[ \t]*http:\/\/127\.0\.0\.1:[0-9]{1,5}\/secret/ ascii nocase
        $redirect_metadata = /Location:[ \t]*http:\/\/169\.254\.169\.254\/latest\/meta-data\/iam\/security-credentials\// ascii nocase

    condition:
        any of them
}

The following Sigma rule requires proxy or HTTP telemetry that records response status and the Location header. Field names may require mapping to the client’s schema.

title: PraisonAI Web Crawl Redirect to Loopback or Cloud Metadata
status: experimental
description: Detects an HTTP 302 response redirecting a client to targets used in the reported web_crawl SSRF bypass.
author: Adverse Trace
date: 2026-08-25
references:

  - https://github.com/advisories/GHSA-8hjw-25cg-g52h
  - https://github.com/advisories/GHSA-5r34-2g38-6569
logsource:
  category: proxy
detection:
  selection_status:
    http.response.status_code: 302
  selection_location:
    http.response.headers.location|startswith:

      - 'http://127.0.0.1:'
      - 'http://169.254.169.254/latest/meta-data/iam/security-credentials/'
  condition: selection_status and selection_location
falsepositives:

  - Authorised local reproduction of the supplied proof of vulnerability
level: high

CVE assessment

1 referenced CVE

CVE CVSS Exploited EPSS Summary
CVE-2026-40160 7.1 High 0% PraisonAIAgents is a multi-agent teams system. Prior to 1.5.128, web_crawl's httpx fallback path passes user-supplied URLs dire…

7. Sources

  • GitHub Advisory Database, “praisonaiagents has a web_crawl SSRF protection bypass via unchecked redirect targets,” https://github.com/advisories/GHSA-8hjw-25cg-g52h, 2026-08-25.
  • GitHub Advisory Database, “praisonaiagents web_crawl vulnerable to SSRF via redirect-following,” https://github.com/advisories/GHSA-5r34-2g38-6569, date not provided in supplied material.
  • GitHub Advisory Database, “praisonaiagents vulnerable to SSRF in web_crawl via redirect-following and DNS rebinding,” https://github.com/advisories/GHSA-vg6p-v9vm-6fgj, date not provided in supplied material.
  • NIST National Vulnerability Database, “CVE-2026-40160,” https://nvd.nist.gov/vuln/detail/CVE-2026-40160, verified reference snapshot supplied 2026-08-25.
  • FIRST, “EPSS record for CVE-2026-40160,” https://api.first.org/data/v1/epss?cve=CVE-2026-40160, verified reference snapshot supplied 2026-08-25.
  • CISA, “Known Exploited Vulnerabilities Catalog,” https://www.cisa.gov/known-exploited-vulnerabilities-catalog, verified reference snapshot supplied 2026-08-25.

8. Adverse Trace position

Adverse Trace retains the authoritative assessment for the underlying CVE-2026-40160 SSRF class: CVSS 7.1 HIGH, NOT in CISA KEV and EPSS 0%. The primary advisory identifies the new bypass as CVE-2026-55523, for which no verified score or exploitation state was supplied; we therefore do not transfer CVE-2026-40160’s score to that identifier. Client exposure is material where web_crawl accepts attacker-influenced URLs, the runtime can reach sensitive internal HTTP services and returned content is retained or surfaced downstream; no active exploitation or actor attribution is established. The precise affected range and PoV results are single-sourced; verify before enforcement. Adverse Trace will monitor for maintainer confirmation, a fixed release, exploitation reporting and changes to KEV or EPSS state.


Read the original source →

Published via PulseTrace — Adverse Trace threat intelligence.

Post this to LinkedIn
Formatting is converted automatically — headings, bullets, a link back & hashtags. Paste straight in.
J
Jeff Davies