# SSRF Filter Bypass via URL Parser Divergence

- **Severity:** High
- **Signature ID:** `7c1f4a92-3b58-4e6d-9a41-5f0c8d2be713`

## Summary

An attacker crafts a URL that looks safe to an application's security check but is actually sent to a different, forbidden address. This works because the code that validates the URL and the code that fetches it use different libraries with subtly different rules for parsing addresses.

## How the attack works

The attacker builds a URL like https://httpbin.org\@evil.com/, mixing in a backslash before the @ sign. The security check (using urllib3) reads this as the safe host 'httpbin.org', because it treats the backslash as the start of a path and stops looking further. The actual HTTP client (using yarl/aiohttp) reads the same string differently: it treats the backslash as part of a username field and the @ sign as the real separator, so it connects to 'evil.com' instead. The attacker gets a request sent to an internal server, cloud metadata endpoint, or other restricted target while the validation layer believed it was checking a public, allowed host. This technique is especially relevant when the crafted URL is placed inside a JSON field sent to an inference server rather than fetched directly.

## Why it matters

An attacker can reach internal services, private networks, or cloud metadata endpoints that are supposed to be blocked, potentially exposing credentials, internal APIs, or infrastructure details.

## What you can do

- Use a single, consistent URL parser for both validation and the actual outbound request, or normalize the URL once before applying any downstream logic.
- Reject URLs containing unusual authority-section characters such as raw or percent-encoded backslashes before the '@' sign.
- Enforce network-level restrictions (e.g., egress filtering, metadata endpoint blocking) so that even a successful SSRF cannot reach sensitive internal targets.
- Audit any code path where URLs are extracted from request bodies or JSON fields and later dereferenced by a different component than the one that validated them.

## Known benign look-alikes

- HTTP basic-auth URLs of the form https://user:pass@host/ - both parses return the same host, so the script returns allow and the rule stays invisible.
- Windows or UNC style backslashes in a path or query string (for example ?redirect=share\folder). The backslash is outside the authority, both parses agree.
- npm scoped package paths (/@scope/pkg) and e-mail addresses in query parameters - the "@" is not inside the authority, so the analysis is skipped.
- Typo'd or hand-mangled URLs such as https://api.example.com\v1/thing that no HTTP client can resolve - the strict parse must yield a syntactically valid hostname preceded by an "@", otherwise the candidate is discarded.
- Proxy/tunnel URLs that legitimately encode a target hostname in the userinfo field. That path fires only as the lower-confidence userinfo-masquerade branch, and only when the encoded name is a host this agent already contacts.

## References

- https://owasp.org/Top10/A10_2021-Server-Side_Request_Forgery_%28SSRF%29/
- https://docs.aiohttp.org/en/stable/client_reference.html
- https://urllib3.readthedocs.io/en/stable/reference/urllib3.util.html

---
Source: https://www.netzilo.com/threats/ssrf-url-parser-divergence
