# praisonaiagents has an SSRF protection bypass in `spider_tools._host_is_blocked()` via DNS-resolved hostnames (`127.0.0.1.nip.io`)

spider_tools._host_is_blocked never resolves DNS, so hostnames like 127.0.0.1.nip.io bypass SSRF filtering and let agents fetch internal services and cloud metadata.

- Payout: Research
- Severity: high
- Program: PraisonAI
- Found by: evertrustai
- Disclosed: 2026-08-25
- CVE: CVE-2026-55526
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-x44h-65qv-cw74
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-x44h-65qv-cw74
- Tags: area:ai domain:ai domain:web impact:data-leak impact:internal-access kind:research platform:ghsa sev:high tech:python technique:incomplete-fix technique:source-review vuln:access-control vuln:ssrf

**Target:** LLM-callable web scraping tools (scrape_page, extract_links, crawl, extract_text) in praisonaiagents
**Root cause:** _host_is_blocked() only checks literal aliases and IP-literal parses (ipaddress.ip_address, socket.inet_aton); real hostnames raise and fall through to return False without any DNS resolution, so names resolving to loopback/private IPs are allowed.
**Steps:**
1. Confirm bypass offline: `_host_is_blocked("127.0.0.1.nip.io")` returns False while `_host_is_blocked("127.0.0.1")` returns True; `SpiderTools()._validate_url("http://127.0.0.1.nip.io/")` returns True.
2. Start a local HTTP server on 127.0.0.1:PORT returning secret JSON.
3. Request `http://127.0.0.1.nip.io:PORT/secrets.json` — nip.io wildcard DNS resolves to 127.0.0.1, filter passes, response body returned.
4. Agent-level: register `scrape_page` tool and send prompt `Please fetch and summarize: http://127.0.0.1.nip.io:8080/admin`; agent fetches internal admin panel.
5. Alternate targets: `http://10.0.0.1.nip.io/` for private nets, `http://169-254-169-254.sslip.io/latest/meta-data/iam/security-credentials/` for AWS IMDS.
**How found:** Patch-gap analysis: prior fix commit 004dcfef added DNS resolution to web_crawl_tools.py (socket.gethostbyname) but the same fix was never ported to spider_tools.py; comparing the two implementations revealed the missing resolution check.
**Exploitation:** Attacker supplies a URL using a wildcard-DNS hostname (nip.io/sslip.io) encoding an internal IP; the agent's scrape_page tool validates it as allowed and issues the HTTP request from the server, returning internal service responses (admin panels, secrets) to the attacker. On EC2 with IMDSv1, the same trick reaches the metadata endpoint for IAM credentials.
**Escalation:** Chaining SSRF with cloud metadata (169-254-169-254.sslip.io) yields temporary IAM credentials, escalating from read SSRF to cloud account compromise.
**Insight:** When a project has multiple URL-fetching modules, diff their SSRF guards — fixes are often applied to one copy only. Also note socket.inet_aton only parses dotted-decimal, so it never catches hostnames; wildcard DNS services (nip.io, sslip.io) are the cheapest bypass to test.

