highCWE-79A03:2021

dangerouslySetInnerHTML Sin Sanitización

Usar dangerouslySetInnerHTML de React con input de usuario sin sanitizar permite a atacantes inyectar scripts maliciosos que se ejecutan en los navegadores de otros usuarios.

Cómo Funciona

React escapa contenido por default, previniendo XSS. Sin embargo, dangerouslySetInnerHTML bypasea esta protección y renderiza HTML crudo. Cuando el HTML viene de input de usuario (comentarios, bios de perfil, editores de texto rico), los atacantes inyectan tags script, event handlers (onerror, onload) o URIs JavaScript que se ejecutan en navegadores de otros usuarios. Esto habilita secuestro de sesión, robo de credenciales y toma de cuentas. El ataque persiste porque el HTML malicioso se guarda en la base de datos y se renderiza para cada visitante.

Código Vulnerable
function Comment({ comment }) {
  return (
    <div
      dangerouslySetInnerHTML={{ __html: comment.body }}
    />
  );
}
Código Seguro
import DOMPurify from 'dompurify';

function Comment({ comment }) {
  const sanitized = DOMPurify.sanitize(comment.body, {
    ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p', 'br'],
    ALLOWED_ATTR: ['href']
  });
  return (
    <div dangerouslySetInnerHTML={{ __html: sanitized }} />
  );
}

Ejemplo Real

En 2020, una vulnerabilidad de Stored XSS en el CMS de Webflow permitió a atacantes inyectar JavaScript a través de campos de texto rico. El código malicioso se ejecutaba para cada visitante que veía la página afectada, potencialmente comprometiendo miles de usuarios.

Cómo Prevenirlo

  • Siempre sanitiza HTML con DOMPurify antes de usar dangerouslySetInnerHTML
  • Restringe tags y atributos permitidos al mínimo necesario
  • Prefiere renderizar Markdown con un parser seguro en vez de HTML crudo
  • Usa headers Content Security Policy para mitigar el impacto de XSS

Tecnologías Afectadas

ReactNext.jsNode.js

Data Hogo detecta esta vulnerabilidad automáticamente.

Escanea Tu Repo Gratis

Vulnerabilidades Relacionadas