flawopen.com/XSS in JavaScript/DOMPurify and innerHTML
¿DOMPurify basta para que innerHTML sea seguro?
DOMPurify es un sanitizador de lista de permitidos sólido para HTML enriquecido si su salida llega directamente a un sink HTML sin modificarse después. Es como revisar un paquete en el muelle: si otro proceso lo vuelve a empaquetar o lo introduce por otra entrada, la inspección inicial ya no cubre lo que llega. Para texto normal, usa textContent y evita interpretar HTML.
// Sanitizado al guardar con una versión/política antigua. saveToDb(DOMPurify.sanitize(input)); // Después se confía en el texto guardado sin revisarlo. el.innerHTML = fetchedFromDb;
// Para HTML enriquecido, sanitiza con la versión actual // justo antes de insertarlo en contexto HTML. el.innerHTML = DOMPurify.sanitize(untrustedHtml, { USE_PROFILES: { html: true }, }); // Para texto normal, no lo interpretes como HTML. textNode.textContent = untrustedText;
Por qué sanitizar una vez al guardar es un patrón más débil
Sanitizar al guardar no es inseguro por sí solo, pero crea una frontera de datos obsoletos: el renderizador podría confiar en una salida antigua tras una corrección del sanitizador, un cambio de política o una ruta que omitió el paso. Vuelve a sanitizar al renderizar con la versión actual y la política del sink concreto. No modifiques ni pases el marcado limpio por otra biblioteca antes de insertarlo; el postprocesamiento puede anular la sanitización.
La configuración y el contexto de salida importan
La configuración predeterminada de DOMPurify permite HTML, SVG y MathML. Si solo necesitas HTML, limita el perfil con USE_PROFILES: { html: true }. No amplíes etiquetas o atributos sin revisión. DOMPurify no sanitiza CSS ni impide todas las solicitudes externas; usa el resultado solo en contexto HTML, nunca en JavaScript, atributos, XML, SVG o CSS.
Trusted Types y renderizado en servidor
Cuando esté disponible, exige Trusted Types mediante Content Security Policy para rechazar cadenas en sinks HTML salvo que pasen por una política aprobada. DOMPurify puede producir TrustedHTML; esto reduce usos accidentales del sink, pero no corrige una configuración insegura ni el postprocesamiento. En servidor, DOMPurify depende de una implementación DOM: mantén jsdom actualizado y no lo combines con happy-dom para sanitización sensible a la seguridad.
Lista de verificación de producción
- ✓Usa textContent para texto normal. Recurre a DOMPurify solo si el producto debe mostrar un subconjunto limitado de HTML enriquecido.
- ✓Sanitiza en el sink HTML final con la versión actual de DOMPurify y una lista mínima revisada; no modifiques después el marcado resultante.
- ✓Mantén la salida en contexto HTML. No la reutilices en JavaScript, CSS, atributos, XML, SVG ni otro contexto de parser.
- ✓Revisa conjuntamente setConfig() persistente, hooks, ADD_TAGS/ADD_ATTR, versiones del DOM en servidor y políticas/CSP de Trusted Types.
Busca sinks de inserción HTML
rg -n -g '*.{js,ts,jsx,tsx}' '(innerHTML|outerHTML|insertAdjacentHTML|document\.write|dangerouslySetInnerHTML)' .Fuentes y referencias
- DOMPurify — README y configuración
- DOMPurify — objetivos de seguridad y modelo de amenazas
- OWASP — prevención de XSS basado en DOM
- OWASP — seguridad de JavaScript y TypeScript
- FlawOpen — XSS en JavaScript