Por qué sigue siendo importante otra hoja de trucos xss
Frameworks modernos ≠ Sin XSS. El autoescapado en React/Angular/Svelte reduce los agujeros de las plantillas, pero los sistemas reales aún envían el mal uso de la API DOM, widgets de terceros inseguros, Markdown/WYSIWYG permisivos, javascript: Manejadores de URL, SVG/MathML, restos de JSONP y confianza implícita en ubicación/hash/postMessage.
Los ecosistemas vectoriales evolucionan. PortSwigger anota continuamente las cargas útiles mediante evento / etiqueta / atributo / navegadorreduciendo drásticamente la "memoria tribal". Esa curación es oro cuando se necesita una amplia cobertura sin reinventar taxonomías de carga útil.
El filtrado por sí solo no es una defensa. OWASP ha repetido esto durante más de una década: la corrección depende de el contexto de representación de los datos. Combinación de codificación de salida adecuada, higienización (para HTML creado por el usuario), política (CSP, Tipos de confianza), y marco higiene no es negociable.

Matriz superficie de ataque × contexto
Utilice esta matriz como lista de control de ejecución al programar validaciones de Playwright/Burp/Nuclei o auditorías de código. Cada fila vincula una representación contexto a arriesgado fregaderoscomún entradasEl primer movimiento defensivoy cómo verificar a escala.
| Contexto | Fregaderos de riesgo (ilustrativo) | Puntos de entrada típicos | Defensa primaria | Cómo validar a escala |
|---|---|---|---|---|
| Texto HTML | innerHTMLplantilla de concatenación de cadenas | parámetros reflejados, cuadros de búsqueda, biografías de usuarios, comentarios | Codificación de salida HTMLnunca envíes HTML que no sea de confianza | Headless render + DOM-taint hooks; diff DOM before/after |
| Atributo | href/src/accióncualquier on* manipulador | javascript: URL, atributos SVG, datos: URL | Codificación de atributos/URLprohibir javascript:; CSP | Fuzz por atributos; control de autodisparadores y navegación |
| JavaScript | evalúe, Función, setTimeout(cadena) | JSONP callbacks, script dinámico concat/parsing | Prohibir la evaluación dinámica; serializar las entradas; sandbox si es necesario. | Gancho eval/Funciónrecopilar pilas de llamadas y argumentos |
| URL/Navegación | ubicación, documento.URL concat | redirecciones abiertas, inyecciones hash/fragmentadas | Canonicalize; allowlists estrictos; nunca coser cadenas sin procesar | Repetición Real-UA; rastreo de la cadena de redireccionamiento |
| Plantillas/SSR | filtros/partes no seguros | cruces de datos de plantillas del lado del servidor | Escape estricto de plantillas; listas blancas de variables | Pruebas unitarias de plantillas + fuzzing de marcadores de posición |
| Contenido enriquecido | WYSIWYG/Markdown/SVG/MathML | HTML/SVG externo pegado; contenido del perfil de usuario | Desinfección de listas de permisos (DOMPurify); CSP; soltar etiquetas peligrosas | Reproducción de cargas útiles por lotes + registro de violaciones de CSP |
Mínimos ejemplos reproducibles (MRE) que se pueden ejecutar realmente
1) Contexto de atributos + activador de interacción cero
<input autofocus onfocus="fetch('/beacon?xss=1')">
Por qué es importante: Los eventos de enfoque se autodisparan al cargarse en muchos flujos de UX (campos de búsqueda, avisos rápidos). Sustituir por <svg onload=…> o <img onerror="…"> para probar diferentes semánticas de activación.
2) Soporte SVG + peculiaridades en la gestión de URL
<svg><a xlink:href="javascript:fetch('/beacon?svg')">x</a></svg>
Por qué es importante: SVG es un espacio de nombres XML independiente con un análisis sintáctico de atributos históricamente peculiar. Los equipos a menudo olvidan desinfectar SVG o permitirlo a través de renderizadores Markdown.
3) XSS basado en DOM (linaje fuente → sumidero).
<script>
const q = new URL(location).hash.slice(1);
document.getElementById('out').innerHTML = q; // sink
</script>
<div id="out"></div>
Por qué es importante: El clásico antipatrón "leer de la URL, escribir en el DOM". Está en todas partes en sitios heredados y herramientas internas. Se soluciona con codificación contextual correcta y nunca escriba directamente en sumideros HTML.
Línea de base defensiva (la ingeniería es lo primero, no los eslóganes)
- Codificación de salida por contexto. Codificar para HTML / Atributo / URL / JS respectivamente. El autoescapado del marco no cubre DOM laminado a mano actualizaciones.
- Permitir la limpieza de la lista para el HTML del usuario. Cuando la lógica empresarial requiera un contenido rico (comentarios, biografías, bases de conocimientos), utilice DOMPurificar (o equivalente) con configuraciones reforzadas; evite "cortar palabras" de la lista negra.
- Política de seguridad de contenidos. Comience con
script-src 'self'+ bloque inline por defecto; setobject-src 'none'ybase-uri 'none'. Adopte Tipos de confianza en Chromium para forzar APIs DOM seguras en tiempo de compilación/ejecución. - Auditoría API peligrosa. Prohibir o vetar
eval/new Function/setTimeout(cadena)y conversiones dinámicas de JSON→código. Aplique las reglas de ESLint durante la compilación y falle el CI cuando se produzcan infracciones. - Prueba y verificación como código. Automatice la repetición de la carga útil. Emparejar con Notificación de infracciones del PEC y correlación pasarela/registro para separar "ventanas emergentes demostrables" de explotable caminos que importan a la empresa.
De la chuleta a la tubería: automatización que funciona
El camino más corto desde la "biblioteca de vectores" hasta la "garantía de producción" es un bucle de cinco etapas:
- Descubrimiento del contexto. Exploraciones estáticas (reglas ESLint, grep semántico) + sondeos en tiempo de ejecución que etiquetan posibles sumideros (
innerHTML(definidores de atributos, puntos de navegación). - Programación vectorial. Asignar cada sumidero/contexto a un piscina curada de cargas útiles (eventos de atributos, peculiaridades de etiquetas, manejadores de URL), filtrado por navegador y banderas de características.
- Pruebas sin cabeza. Playwright/Chromium funciona por vector. Consola de captura, red, Infracciones del CSPy las mutaciones DOM.
- Correlación de señales. Únete a los hallazgos sin cabeza con Pasarela API y registros de aplicaciones para descartar "ruido frente a real". Esto acaba con los falsos positivos el primer día.
- Informes basados en la evidencia. Adjunte automáticamente capturas de pantalla, rastros HTTP, diferencias DOM antes/después e infracciones de políticas. puntuación confianza para que los ingenieros sepan por dónde empezar.
Reproductor mínimo de Playwright (fragmento drop-in)
import { chromium } from 'playwright';
const vectors = [
'#\"><img src="x" onerror="fetch(\">',
'#<svg onload="fetch(\">'
];
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
page.on('consola', m => console.log('consola:', m.text()));
page.on('pageerror', e => console.error('pageerror:', e));
for (const v of vectores) {
await page.goto('https://target.example/' + v);
await page.screenshot({ ruta: `evidence_${encodeURIComponent(v)}.png` });
}
await browser.close();
})();
Prodúcelo: añadir etiquetas de linaje fuente→sumidero a cada ejecución, activar Informe CSP para recoger las infracciones, y almacenar Diferencias DOM para hacer evidentes las regresiones en los PR.
Realidades marco para las que debe diseñar
- React/JSX. El autoescapado ayuda, pero dangerouslySetInnerHTML y crudo
ref.current.innerHTML = ...volver a abrir el fregadero. Trátelos como olores de código; póngales un desinfectante y una política de tipos de confianza. - Angular. El desinfectante es decente, pero bypassSecurityTrustHtml y API similares pueden abrir agujeros; documente cada desvío y restrinja a fuentes vetadas.
- Siguiente/Siguiente/SSR. Las páginas generadas por el servidor sólo deben hacerse eco de codificado contenido. Nunca confíe en que los frameworks cliente "limpien" los errores del servidor.
- Markdown/MDX/WYSIWYG. Trátelos como Ingesta de HTML problemas. Refuerza tu renderizador, aísla los widgets que no sean de confianza y purga los atributos de eventos/manejadores URL.
- SVG/MathML. Si debe permitirlos, limite el conjunto de características y ejecute un desinfectante que entienda los espacios de nombres XML. Si no son críticos, conviértalos a trama segura en el servidor.
Familias prácticas de carga útil que realmente necesitarás
- Activación automática de eventos:
autofocus,onload,onerror,onanimationstart,onfocus,onpointerenter. Ideal para probar la explotabilidad sin clics del usuario. - Manejadores de URL:
javascript:,datos:y ocasionalmentevbscript:(legado). Aplicar listas permitidas. - Colisiones de plantillas: Trucos de división/concatenación que se cuelan a través de filtros ingenuos (por ejemplo, salir de contextos de atributos y luego volver a introducir HTML).
- DOM clobbering: Sobrescribir IDs/nombres para redirigir rutas de código y aterrizar un fregadero.
- Tiempo de mutación-observador: Disparadores que aprovechan las actualizaciones dinámicas en lugar de la carga inicial.
CSP y tipos de confianza: del "nice to have" al guardrail
- CSP le ofrece un lenguaje de políticas para restringir las fuentes de los scripts y la ejecución en línea. Empiece por lo estricto y amplíelo sólo para los casos comprobados. Combínelo con
informe-uri/Informe ay cosecha informes de infracción en tu telemetría. - Tipos de confianza obligar a los promotores a aprobar política creada en las API de DOM que, de otro modo, aceptarían cadenas sin formato (
innerHTML,outerHTML,insertAdjacentHTML,Gama1TP5CrearFragmentoContextual). Esto elimina clases enteras de DOM XSS por construcción. - Consejo de rodaje: ejecutar CSP en
sólo informedurante dos sprints; corrija las infracciones y, a continuación, haga cumplir la normativa. Introducir un único Política de tipos de confianza para toda la aplicación y sólo emitir HTML "bendecido" a través de constructores examinados.
Cómo demostrar la explotabilidad a los ingenieros
- Guiones de reproducción: Proporcione un one-liner (URL o curl) y una rama de Playwright para reproducir.
- DOM diff: Muestra el nodo exacto que ha cambiado y la ruta (
#app > .profile > .bio). - Pilas de llamadas: Para los sumideros JS, incluya las trazas de pila de su
eval/Funciónganchos. - Pruebas del DEN: Adjuntar violación JSON para infracciones inline/script src.
- Narrativa empresarial: "Esto puede exfiltrar tokens de sesión de
/cuentaa través de un<img>baliza" gana a "alerta saltada" siempre.
Ejecutando esta hoja de trucos xss dentro de Penligent
Si ya utiliza Penligente como plataforma automatizada de pentest, puede empaquetar todo lo anterior en una única plantilla ejecutable:
- Plantilla de tarea: "XSS Recon + Validar". El agente realiza el reconocimiento (subdominio/puerto/huella digital), programa los vectores por contexto detectado, ejecuta la repetición sin cabeza, y correlaciona las señales con troncos/portones para reducir el ruido.
- Exportación basada en pruebas. Los hallazgos se envían con puntuaciones de confianzaContiene pasos reproducibles, capturas de pantalla, registros de infracciones de CSP y diferencias de DOM en las que sus ingenieros pueden confiar.
- Donde más ayuda. Grandes ámbitos con pilas mixtas heredadas + SPA, o equipos que migran a CSP/Tipos de confianza y necesitan triaje basado en pruebas en lugar de trivialidades sobre la carga útil.

Errores comunes que siguen afectando a los equipos veteranos
- Sanear la entrada, no la salida. Si debe aceptar HTML, desinfecte y siguen codificando a la salida en función del contexto de destino; los dos no son intercambiables.
- Permitir
javascript:por "flexibilidad". Elimínelo por completo; ponga en la lista blanca sólo protocolos específicos (https,mailto...tal vez...tel). - Tratar Markdown como "texto seguro". Es un renderizador, sus plugins deciden la seguridad. Audite las etiquetas/atributos permitidos; considere la rasterización del lado del servidor para SVG no fiables.
- Ignorar contextos no HTML. La concatenación de URL y las evals JSON→JS son reincidentes. Refuerza la política de "no-cadenas-a-código".
- Confiar en un entorno. XSS que falla en headless puede tener éxito en Chromium móvil o en versiones antiguas de escritorio. Mantenga un matriz del navegador para aplicaciones de alto valor.
Lista de control de la producción, colóquela junto a su insignia CI
- Context-aware codificación utilidades con pruebas unitarias para HTML/Attr/URL/JS
- DOMPurificar (o equivalente) bloqueado en una configuración reforzada para rutas de contenido enriquecido
- CSP con
script-src 'self'(no unsafe-inline),object-src 'none',base-uri 'none'; recogida de infracciones conectada a telemetría - Tipos de confianza política + reglas de lint en tiempo de compilación para bloquear los sumideros de cadenas sin procesar
- Prohibición de las normas de ESLint
eval/new Function/setTimeout(cadena)(Aplicación de CI) - Dramaturgo suite de reproducción sembrado con vectores al estilo PortSwigger; capturas de pantalla por vector + DOM diffs
- Automatizado correlación de señales con registros de aplicaciones / eventos de la pasarela API
- Informes basados en pruebas con puntuaciones de confianza y notas de impacto empresarial
- Líneas de plantilla PR: "¿Introduce nuevos sumideros HTML?" "¿Evita el desinfectante?" "¿Se actualiza la política de TT?"
- Revisión periódica de los widgets de terceros/WYSIWYG/Configuración de Markdown
PREGUNTAS FRECUENTES
P: Si ya utilizamos React/Angular, ¿seguimos necesitando esto?
R: Sí. Los frameworks no vigilan todas las escrituras DOM, widgets de terceros o Markdown/SVG. Aún necesitas sanitizer + CSP + TT, y debes evitar escribir datos no confiables en sumideros DOM sin procesar.
P: ¿Deberíamos bloquear todos los scripts inline con CSP?
R: Sí, por defecto. Utilice nonces o hashes sólo cuando sea absolutamente necesario y documente la excepción. El objetivo a largo plazo es evitar por completo los scripts en línea.
P: ¿Basta con desinfectar?
R: No. La desinfección reduce la superficie de ataque para Ingesta de HTMLpero aún así es necesario codificación de salida y los guardarraíles políticos. Diferentes problemas, diferentes herramientas.
P: ¿Qué navegadores probamos?
R: Como mínimo, los dos principales motores de escritorio + móvil de su base de usuarios. Mantén una matriz pequeña; algunos vectores son específicos de cada navegador o están limitados por características.
Otras lecturas (autorizadas)
- PortSwigger - Hoja de trucos de secuencias de comandos en sitios cruzados (XSS) - un catálogo vivo de vectores, PoCs y notas de navegación.
- OWASP - Hoja de trucos para la prevención de XSS - estrategias de codificación rigurosas y adaptadas al contexto y tablas de lo que se debe hacer y lo que no.
- OWASP - Hoja de trucos para la prevención de XSS basado en DOM - patrones source→sink y mitigaciones en el navegador.
- PortSwigger - ¿Qué es XSS? - tutorías estructuradas y laboratorios prácticos para la formación de nuevos empleados.
Apéndice: referencia rápida sobre saneamiento y codificación
- Nodos de texto HTML → escapar
& " ' / - Valores de los atributos → Codificación de atributos HTML + desautorización de atributos de eventos de datos no fiables.
- URL → codificar componentesprotocolos allowlist; nunca escriba raw
javascript:/datos: - Cadenas JS → serializar de forma segura; nunca pase datos del usuario a API que interpreten código
Nota de cierre: Un útil hoja de trucos xss es uno que puede cable en su canalización-no un póster de cargas útiles inteligentes. Comience con el descubrimiento del contexto, programe vectores por contexto, reproduzca sin cabeza, correlacione con registros y envíe pruebas con puntuaciones de confianza. Tanto si adopta Penligent como si desarrolla su propio arnés, dirija el proceso con pruebas y dejar que la política imponga los guardarraíles.

