BIPI
BIPI

Server-Side Request Forgery via PDF Generators and Headless Browsers

Cybersecurity

Headless Chrome and wkhtmltopdf in your invoice service is a juicy SSRF vector. We cover internal scanning, AWS metadata, file URI tricks, and the Chrome sandbox flags that flip a feature into a vulnerability.

By Arjun Raghavan, Security & Systems Lead, BIPI · December 26, 2023 · 10 min read

#ssrf#pdf#headless#aws-metadata#pentesting

The attack surface

Apps that generate PDFs from user supplied HTML or URLs run headless Chrome, wkhtmltopdf, or weasyprint server side. Whatever the renderer fetches comes from the server context. That is SSRF by design, dressed up as a feature.

Primitives to chase

  • img src http://169.254.169.254/latest/meta-data/iam/security-credentials/ for AWS
  • iframe src http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token for GCP
  • link rel stylesheet href http://localhost:6379 to probe internal Redis
  • file URI tricks in older wkhtmltopdf to read /etc/passwd

Internal network discovery

The PDF is your output channel. Embed images pointing at internal IPs in a grid. Pages that succeed show a real image or an HTTP error rendered as broken icon. Pages that fail timeout. The PDF becomes a port scanner output.

Cloud metadata extraction

AWS IMDSv1 returns a temporary credential string when fetched. Render it inside a textarea or pre block. The PDF will contain readable text. We have seen this bypass IMDSv2 because the headless instance still has v1 enabled by an older AMI.

Headless Chrome specific tricks

Chrome respects the same origin policy in the renderer, but service workers and fetch from inside the page can hit internal hosts that the operator forgot to block. The disable-web-security flag in some pipelines turns the renderer into a full CORS skipping client.

Discovery workflow

  1. Submit HTML or URL inputs that include external Burp Collaborator references
  2. Confirm the renderer fetches them server side
  3. Pivot to internal hostnames and cloud metadata addresses
  4. Use response timing or rendered page content to exfiltrate data

Tooling

Burp Collaborator for confirmation, SSRFmap for chaining, and a small Puppeteer harness to replicate the target rendering pipeline locally. ffuf can drive permutations of internal IP ranges.

Detection

  • Outbound requests from PDF worker subnets to 169.254 or 10.0 ranges
  • Render jobs whose HTML contains link or img tags pointing at private IPs
  • Browser process spawning network connections to non allowlisted destinations

Remediation

  1. Run the renderer in a network namespace that can only reach the public internet, no metadata, no internal services
  2. Allowlist hostnames in a forwarding proxy and route the renderer through it
  3. Disable file URI, disable JavaScript when not required, sanitize input HTML
  4. Switch cloud instances to IMDSv2 only, with hop limit 1
$6.5k
Bounty median for PDF SSRF reaching IAM creds
~28%
Cloud apps with IMDSv1 still enabled on render workers
Every PDF generator is a tiny browser holding your AWS credentials. Treat it that way.

Read more field notes, explore our services, or get in touch at info@bipi.in. Privacy Policy · Terms.