HTML usa texto ordinario para dos tareas: contenido visible y estructura del documento. El signo menor que puede ser parte de una fórmula, pero también inicia una etiqueta. El ampersand puede aparecer en el nombre de una empresa, pero también inicia una referencia de carácter. Las entidades HTML, más precisamente character references, permiten expresar un carácter literal sin que el parser lo interprete como markup.
Texto y markup comparten canal
Cuando el browser parsea HTML, decide qué significan los caracteres según contexto. En texto, < produce < visible y & produce ampersand. Las referencias nombradas como © ayudan con símbolos conocidos; las numéricas apuntan a code points Unicode.
En documentos UTF-8 modernos, muchas letras pueden escribirse directamente. Las entidades siguen siendo esenciales para caracteres con significado sintáctico o cuando una representación ASCII comunica mejor la intención.
Escaping depende del contexto
Texto entre etiquetas, atributos, URLs, CSS y JavaScript tienen reglas distintas. Escapar una comilla es importante dentro de un atributo, pero no resuelve un valor colocado dentro de script. Una función genérica de “HTML escape” no cubre todos los destinos.
Los template engines seguros eligen encoder según contexto. Concatenar markup manualmente o pasar valores ya escapados entre contextos crea bugs y vulnerabilidades.
Encoding no es sanitization
Encoding hace que el input se muestre como texto. Si un usuario escribe <strong>, se ven esos caracteres. Sanitization es necesaria cuando se permite HTML real: un sanitizer parsea y elimina elementos, atributos y URLs no permitidos.
Si no necesitas rich text, escapar todo es más simple y seguro. Decodificar entidades antes de renderizar raw puede reintroducir markup peligroso.
Double encoding revela responsabilidad duplicada
Si un valor ya escapado se escapa otra vez, el usuario ve &lt; o secuencias parecidas. Suele ocurrir cuando base de datos, API y template creen ser dueños del escaping.
Guarda texto semántico y escápalo al final, en el boundary de salida. Las formas presentation-specific no deberían convertirse en valor canónico salvo que el campo sea explícitamente HTML.
La entidad no cambia el significado Unicode
Un carácter directo, una referencia decimal, una hexadecimal y una entidad nombrada pueden producir el mismo carácter en DOM. Después del parsing, el browser trabaja con el carácter, no con la forma en que se escribió en source.
Unicode normalization es otro asunto. Dos textos visualmente iguales pueden usar secuencias distintas. Las entidades no arreglan automáticamente comparación, búsqueda o deduplicación.
Los browsers son tolerantes, la seguridad no debe serlo
HTML incluye reglas de recuperación para documentos mal formados. Un filtro basado en reemplazos simples puede interpretar una secuencia de manera distinta al browser. Los atacantes explotan esas diferencias.
Usa encoders y sanitizers maduros que modelen parsing real. Content Security Policy ayuda, pero no sustituye contextual escaping.
Source y DOM muestran etapas distintas
Durante debugging, el source de la respuesta muestra qué envió el servidor. El DOM muestra lo que el browser entendió después de parsear. Comparar ambos ayuda a ubicar si el problema viene de storage, serializer, template o parser.
Validadores encuentran source mal formado; pruebas de rendering confirman comportamiento real. Para componentes críticos, conviene usar ambas miradas.
Los editores y migraciones pueden cambiar representation
Un editor visual puede convertir caracteres a entidades, reordenar atributos o normalizar HTML al guardar. Si abrir y guardar sin cambios produce un diff enorme, el sistema pierde capacidad de distinguir edición real de transformación técnica.
Para texto plano, el editor debe trabajar con valor semántico. Para HTML enriquecido, la política de normalización y sanitization debe estar documentada y cubierta por pruebas.
No todas las entidades mejoran legibilidad
Convertir cada carácter no ASCII a entidad hace el source más largo y difícil de revisar. UTF-8 directo suele ser más claro para texto normal. Las entidades son más valiosas para caracteres con función sintáctica o símbolos difíciles de distinguir visualmente.
El ownership evita discusiones repetidas
Un equipo debe saber qué capa produce texto, qué capa lo almacena y qué capa lo escapa. Si esa responsabilidad no está escrita, cada bug visible se resuelve con otro encode o decode local. El resultado es una cadena de parches que funciona en una pantalla y falla en otra.
Definir ownership también mejora seguridad. El desarrollador que renderiza un valor sabe si recibe plain text, sanitized HTML o un objeto que ya fue preparado para un contexto específico.
Las pruebas deben incluir caracteres incómodos
Un conjunto mínimo debería cubrir ampersands, signos menor y mayor, comillas, apóstrofes, texto no latino y secuencias que parecen entidades. También conviene probar valores que ya llegan encoded para confirmar que no se duplican. Esos fixtures protegen cambios de template engine y migraciones de contenido.
Las entidades son herramienta de sintaxis
No cifran, no ocultan y no autorizan. Permiten que contenido y estructura convivan en un documento textual. La práctica saludable es mantener texto semántico, escapar para el contexto exacto y sanitizar solo markup permitido.
Con esa disciplina, las entidades dejan de ser ruido visible y se vuelven una parte pequeña pero esencial de la seguridad y calidad de HTML.