Guía en profundidad
HTML entities, escaping y seguridad del markup
Referencias de caracteres HTML, referencias numéricas, escaping contextual, sanitization y su relación con XSS.
Por qué existen las referencias de caracteres
HTML reserva algunos caracteres para la sintaxis del markup. Las referencias permiten representarlos cuando la forma literal sería ambigua o incómoda, mediante nombres como & o referencias numéricas.
HTML moderno maneja Unicode directamente, de modo que no todo carácter no ASCII necesita una entity. Se usan sobre todo para caracteres sensibles a la sintaxis y representaciones convencionales.
Referencias named y numeric
Las referencias con nombre asocian nombres estandarizados a caracteres o secuencias; las numéricas indican un code point Unicode en decimal o hexadecimal. El parser HTML resuelve ambas en el texto resultante.
Una referencia numérica identifica un code point, no los bytes UTF-8 con los que se transporta el documento. Encoding del fichero y sintaxis de entity son capas distintas.
El escaping depende del contexto
Texto HTML, valores de atributos, URL, CSS y JavaScript embebido tienen gramáticas diferentes. El escaping correcto debe conocer el contexto: lo apropiado para un text node puede ser insuficiente dentro de un script.
Los motores de plantillas seguros aplican escaping contextual. Desactivar el auto-escaping o concatenar markup con datos no confiables aumenta el riesgo de convertir datos en sintaxis ejecutable.
Escaping frente a sanitization
Escaping mantiene datos como texto dentro de un contexto. Sanitization recibe markup potencialmente activo y elimina o restringe elementos, atributos y URL según una política.
Si se permite un subconjunto de HTML de usuario, sustituir < y > no basta. Debe utilizarse un sanitizer mantenido que opere sobre la estructura parseada.
XSS y fronteras de confianza
Cross-site scripting aparece cuando datos controlados por un atacante llegan a un contexto ejecutable del navegador. La prevención combina encoding contextual, sanitization cuando se admite HTML y APIs que evitan sinks peligrosos.
Las entities no son un filtro universal: un valor seguro como texto puede volverse peligroso tras decodificarse o insertarse en otro contexto. Hay que seguir todo el flujo de datos.
Buenas prácticas
Mantén UTF-8 de extremo a extremo, confía en el escaping del framework y evita ciclos repetidos de encode/decode sin contrato claro. Prueba comillas, ampersand, caracteres sintácticos y Unicode en los límites.
Para mostrar texto usa APIs que creen text nodes. Si necesitas markup, define una allowlist y emplea librerías maduras de sanitization en lugar de regex o sustituciones ad hoc.