Qué es escapar HTML y por qué importa
En HTML, ciertos caracteres tienen significado estructural: < abre una etiqueta, > la cierra, & inicia una entidad, las comillas delimitan atributos. Si querés mostrar un signo menor literal en la página sin que el navegador piense que estás abriendo una etiqueta, lo escapás como <. La regla aplica a cualquier contenido que vaya entre etiquetas o dentro de atributos.
Los 5 caracteres principales
<se escapa como<>se escapa como>&se escapa como&"se escapa como"'se escapa como'
XSS: el ataque que escapar previene
Cross-Site Scripting (XSS) ocurre cuando un atacante inyecta código JavaScript en una página que otros usuarios van a ver. El vector clásico es un comentario en un blog: si el sistema renderiza <script>robarCookies()</script> sin escapar, ese script corre en el navegador de cada visitante con acceso al sesión y a las cookies. Escapar todo input de usuario antes de insertarlo en el DOM elimina el vector. Los frameworks modernos (React, Vue, Astro) escapan por defecto, pero si insertás contenido con innerHTML o dangerouslySetInnerHTML, la responsabilidad vuelve a ser tuya.
Cuándo escapar y cuándo no
- Escapar siempre al insertar input de usuario en el DOM, al mostrar contenido de una API que no controlás, o al loguear datos en una página.
- No escapar dos veces. Si un framework ya escapa, escapar manualmente convierte
&en&amp;y el usuario ve basura. - No escapar contenido confiable y deliberado. Si estás insertando HTML que vos generaste y querés que se renderice, escapar lo rompe.
Mostrar código en un blog
Si tu post enseña a usar la etiqueta <script>, no podés escribirla literal en el HTML del artículo: el navegador la interpretaría como una etiqueta real e intentaría ejecutar lo que viene adentro. Escapás los signos a <script> y el lector la ve textual. Muchos editores de blog (incluyendo WordPress y Ghost) escapan automáticamente dentro de bloques de código, pero no siempre, y a veces conviene tener el escape manual a mano.
Desescapar: el camino inverso
A veces recibís texto que ya viene con entidades HTML (de un feed RSS, una API JSON que entregó HTML codificado, un export de base de datos). Para mostrarlo o procesarlo como texto plano, hay que desescapar. Si vas a renderizarlo en el DOM, asegurate de no introducir XSS: desescapar y luego inyectar con innerHTML es exactamente lo que escapar previene.
HTML vs URL encoding
Son dos cosas distintas. Codificación de URL transforma caracteres no seguros en %XX (espacio se vuelve %20). Escape HTML transforma caracteres especiales en entidades (espacio se queda igual, < se vuelve <). Si confundís los dos, terminás con strings tipo %26lt%3B que no significan nada en ningún contexto.