ToolZen ToolZen
Developer converter client

HTML Encoder / Decoder

Encode special characters to HTML entities and decode them back. Covers &, <, >, ", and all named entities.

Advertisement (Top Banner)
Advertisement (Bottom)

El escapado HTML sustituye el puñado de caracteres que de otro modo se leerían como marcado por referencias a entidades, para que el texto siga siendo texto. Es una operación pequeña con una reputación desproporcionada, porque hacerla mal es como ocurre el cross-site scripting, y porque "escapa la entrada" es un consejo sutil y peligrosamente incompleto.

Cinco caracteres, y el orden en que los sustituyes

El conjunto es pequeño: & pasa a &amp;, < a &lt;, > a &gt;, " a &quot; y ' a &#039;. Todo lo demás puede quedarse como está.

En esa lista se esconde un error clásico. Si sustituyes los caracteres de uno en uno y dejas & para el final, destruyes tu propio trabajo: < pasa a &lt;, luego el & que acabas de introducir pasa a &amp;, y la salida es &amp;lt;: un "&lt;" literal y visible en la página en lugar de un signo de menor que. El ampersand debe escaparse siempre primero, porque todas las demás sustituciones introducen uno.

Esta herramienta esquiva la trampa por completo emparejando los cinco caracteres en una sola pasada y sustituyendo cada uno exactamente una vez, así que el orden ni siquiera se plantea. Esa es la forma más robusta para este tipo de código, y vale la pena copiarla: una sola regex con una tabla de búsqueda no puede codificar dos veces, mientras que una cadena de llamadas a replace depende de que un desarrollador recuerde un invariante.

Por qué el apóstrofo es numérico

Fíjate bien y la comilla simple pasa a &#039; en vez de a &apos;, lo que junto a &quot; parece incoherente. Es deliberado. &apos; se definió en XML y solo llegó a HTML en la versión 5: no forma parte de HTML 4, y los analizadores muy antiguos lo mostrarán literalmente como los cuatro caracteres &apos; en lugar de como un apóstrofo.

La referencia numérica &#039; ha funcionado siempre y en todas partes. Es una cosa pequeña, pero es el tipo de cosa pequeña que aparece como texto destrozado en un cliente de correo que renderiza HTML de 2003, y la forma numérica no cuesta nada.

El escapado depende del contexto, y esta es la parte que importa

He aquí el malentendido que merece desmontarse: no existe el "HTML escapado" en abstracto. Solo existe texto escapado correctamente para un sitio concreto, y el mismo escapado que es perfectamente seguro en una posición es inútil en otra.

Entre etiquetas, escapar estos cinco caracteres es suficiente. Dentro de un atributo entrecomillado también lo es, siempre que el atributo tenga comillas de verdad. Escribe <img src=VALOR> sin ellas y un valor escapado que contenga un espacio se escapa igualmente: x onerror=alert(1) no contiene ningún carácter que el escapado HTML toque, y se convierte en un atributo. Son las comillas las que hacen el trabajo de seguridad, no el escapado.

En otros sitios va peor. Dentro de un bloque <script> no rigen las reglas de HTML: necesitas escapado de cadenas de JavaScript, y la secuencia </script> en cualquier punto de un literal de cadena cierra el bloque sin importar lo que la rodee. Dentro de un atributo de URL, el escapado HTML no hace nada contra javascript: como esquema. Dentro de un atributo style, CSS tiene su propia sintaxis de escape. Cinco contextos distintos, cinco reglas distintas, y un motor de plantillas que solo conoce uno producirá alegremente un agujero.

Descodificar es lo contrario de la seguridad

Codificar vuelve el texto inerte. Descodificar toma texto inerte y lo devuelve a la vida. Así que descodificar algo y luego meterlo en una página con innerHTML deshace exactamente la protección que la codificación proporcionaba, y este es un patrón real en código real, normalmente escrito por alguien que pensó que "descodificar" significaba "limpiar".

Esta herramienta es segura para descodificar porque no hace nada con el resultado salvo mostrártelo en una textarea, que no puede ejecutar nada. El riesgo vive en lo que hagas después. Si descodificas entidades para insertar el resultado en una página, usa textContent en vez de innerHTML; y si de verdad necesitas renderizar HTML suministrado por usuarios, necesitas un saneador como DOMPurify —una lista de etiquetas y atributos permitidos—, no un descodificador de entidades.

Preguntas frecuentes

¿Se envía mi texto a un servidor?

No. Esta herramienta está marcada como "client": la sustitución se ejecuta en la pestaña de tu navegador y no se transmite ni se guarda nada.

¿Codificar y luego descodificar me devuelve exactamente lo que tenía?

Sí. Las cinco sustituciones son reversibles e inequívocas, así que un viaje de ida y vuelta por esta herramienta devuelve el texto original carácter a carácter, ampersands y comillas incluidos. Eso no es cierto de todos los esquemas de escapado, pero sí de este.

¿Basta el escapado para prevenir XSS?

Solo cuando encaja con el contexto, como se describe arriba. La respuesta breve y honesta es que el escapado manual es la forma frágil de hacerlo. Los marcos modernos —React, Vue, Angular y cualquier motor de plantillas de servidor actual— escapan por defecto y saben en qué contexto están. Esa es la defensa real. Una herramienta como esta sirve para inspeccionar y entender un valor, no para ser la capa de seguridad de una aplicación.

¿Y &nbsp; y todas las demás entidades con nombre?

La especificación HTML define más de dos mil, y casi ninguna hace falta ya. En un documento UTF-8 puedes escribir é, ©, — y 😀 directamente, y eso es más legible de lo que &eacute;, &copy; y &mdash; fueron nunca. Las excepciones que conviene conservar son las cinco estructurales, más &nbsp; cuando quieres específicamente un espacio que no salte de línea. Las entidades con nombre en otros sitios son una costumbre heredada de una época en que las codificaciones eran poco fiables.

¿Por qué mi texto codificado muestra &amp;lt; en vez de &lt;?

Algo lo ha codificado dos veces. La primera pasada convirtió < en &lt;, y la segunda vio el & de ese resultado y lo convirtió en &amp;. Busca una plantilla que escape un valor ya escapado aguas arriba: es común cuando una capa escapa servicialmente y otra lo repite "por seguridad". Escapa una sola vez, en el punto de salida.