Cómo evitar inyecciones XSS al usar innerHTML en JS

Introducción La propiedad innerHTML es una de las mayores fuentes de vulnerabilidades XSS (Cross-Site Scripting). Si insertas directamente comentarios de usuarios o nombres de perfiles con ella, un atacante podría inyectar etiquetas <script> y robar cookies de sesión. La solución es priorizar textContent o usar APIs de saneamiento modernas para renderizar HTML seguro.

Solución Rápida (Código)

const userContent = "<img src=x onerror=alert('Hacked')>";

// PELIGROSO: Ejecuta el script inyectado
// elemento.innerHTML = userContent;

// SEGURO: Renderiza como texto plano
elemento.textContent = userContent;

// SEGURO (HTML necesario): Usar DOMPurify (Librería recomendada)
elemento.innerHTML = DOMPurify.sanitize(userContent);

Explicación técnica Cuando usas innerHTML, el navegador parsea el string como código HTML real. Si el string contiene eventos de JavaScript (como onerror o onclick), estos se ejecutarán inmediatamente en el contexto del usuario. textContent, por el contrario, trata todo el contenido como texto literal, neutralizando cualquier intento de ejecución de código.

En casos donde sea estrictamente necesario renderizar HTML (como un editor de texto enriquecido), nunca confíes en el input crudo. Debes usar una técnica de saneamiento (Sanitization) que elimine etiquetas peligrosas y atributos de eventos. Google y las grandes tecnológicas recomiendan APIs como Sanitizer API (nativa en navegadores modernos) o librerías probadas como DOMPurify. Proteger estos puntos de entrada es esencial para mantener la reputación de tu sitio y la seguridad de tus usuarios.

Conclusión Un desarrollador responsable siempre asume que el input del usuario es malicioso. Si te interesa la seguridad, revisa nuestro artículo sobre Content Security Policy (CSP) para principiantes.