SSRF Filter Bypass via URL Parser Divergence
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.
Netzilo detection
Netzilo reports this behaviour when it is observed.
- Signature ID
- 7c1f4a92-3b58-4e6d-9a41-5f0c8d2be713
- Severity
- High
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.