Prevención de Cross-Site Scripting (XSS)
Codificación por contexto, CSP y los antipatrones que inyectan HTML sin escapar.
El XSS permite a un atacante ejecutar JavaScript en el navegador de otra persona: robar sesiones, suplantar acciones o exfiltrar datos. Surge cuando datos no confiables llegan al DOM sin la codificación adecuada.
1. Deja que el framework escape por ti
Los frameworks modernos escapan por defecto al interpolar texto. El problema aparece cuando lo desactivas:
// MAL — inyecta HTML sin escapar
<div dangerouslySetInnerHTML={{ __html: comentarioUsuario }} />
// BIEN — React escapa el texto automáticamente
<div>{comentarioUsuario}</div>
Equivalentes peligrosos: v-html en Vue, [innerHTML] en Angular, {@html} en Svelte,
element.innerHTML = ... en JS puro.
2. Si debes renderizar HTML, sanéalo
Cuando el requisito es mostrar HTML enriquecido (editor WYSIWYG), sanéalo con una librería probada, nunca con regex propias:
import DOMPurify from 'dompurify';
const limpio = DOMPurify.sanitize(htmlUsuario);
3. Codifica según el contexto de salida
La misma cadena se escapa distinto en cada contexto. Insertar datos en un <script>, en un
atributo onclick, en una URL o en CSS requiere codificaciones diferentes. Evita meter datos del
usuario en contextos ejecutables.
// MAL — datos del usuario dentro de un contexto JS
const html = `<a href="javascript:init('${userInput}')">ir</a>`;
// BIEN — pasa los datos por un canal de datos, no de código
element.dataset.valor = userInput; // y léelo desde JS confiable
4. Content-Security-Policy como red de seguridad
Una CSP estricta sin unsafe-inline convierte muchos XSS en inofensivos aunque un bug se cuele.
Es defensa en profundidad, no sustituto de escapar.
5. Cuidado con el DOM-based XSS
El XSS no siempre pasa por el servidor. Fuentes como location.hash, document.referrer o
postMessage que fluyen a sinks como innerHTML o eval crean XSS puramente de cliente.
Checklist rápida
- Interpolación de texto por defecto; nada de
innerHTML/dangerouslySetInnerHTMLcon datos de usuario. - HTML enriquecido saneado con DOMPurify u otra librería madura.
- Datos del usuario fuera de contextos ejecutables (JS,
javascript:,eval). - CSP estricta como defensa en profundidad.
- Revisión de sources/sinks para XSS basado en DOM.
- #xss
- #owasp
- #frontend