¿Qué caracteres deben tener caracteres de escape en HTML?
¿Son lo mismo que XML, quizás más el espacio (
)?
He encontrado algunas listas enormes de caracteres de escape HTML, pero no creo que deban escaparse. Quiero saber de qué hay que escapar.
Si está insertando contenido de texto en su documento en una ubicación donde se espera contenido de texto 1 , generalmente solo necesita escapar los mismos caracteres que lo haría en XML . Dentro de un elemento, esto solo incluye el signo de escape de entidad &
y los signos delimitadores de elemento menor que y mayor que <
>
:
& becomes &
< becomes <
> becomes >
Dentro de los valores de los atributos también debes escapar el carácter de comilla que estás usando:
" becomes "
' becomes '
En algunos casos, puede ser seguro evitar escapar de algunos de estos personajes, pero te recomiendo que escapes de los cinco en todos los casos para reducir la posibilidad de cometer un error.
Si la codificación de su documento no admite todos los caracteres que está usando, como si intenta usar emoji en un documento codificado en ASCII, también debe evitarlos. Hoy en día, la mayoría de los documentos están codificados utilizando la codificación UTF-8 totalmente compatible con Unicode, donde esto no será necesario.
En general, no debes escapar de espacios como
.
No es un espacio normal, es un espacio que no se rompe . Puede usarlos en lugar de espacios normales para evitar que se inserte un salto de línea entre dos palabras, o para insertar espacios adicionales sin que se colapse automáticamente, pero esto suele ser un caso poco común. No haga esto a menos que tenga una restricción de diseño que lo requiera.
1 Por "una ubicación donde se espera contenido de texto", me refiero al interior de un elemento o valor de atributo citado donde se aplican las reglas de análisis normales. Por ejemplo: <p>HERE</p>
o <p title="HERE">...</p>
. Lo que escribí anteriormente no se aplica al contenido que tiene reglas de análisis o significado especiales, como dentro de un script o etiqueta de estilo, o como un elemento o nombre de atributo. Por ejemplo: <NOT-HERE>...</NOT-HERE>
, <script>NOT-HERE</script>
, <style>NOT-HERE</style>
, o <p NOT-HERE="...">...</p>
.
En estos contextos, las reglas son más complicadas y es mucho más fácil introducir una vulnerabilidad de seguridad. Le recomiendo encarecidamente que nunca inserte contenido dinámico en cualquiera de estas ubicaciones. He visto equipos de desarrolladores competentes conscientes de la seguridad introducir vulnerabilidades asumiendo que habían codificado estos valores correctamente, pero sin encontrar un caso límite. Generalmente existe una alternativa más segura, como poner el valor dinámico en un atributo y luego manejarlo con JavaScript.
Si es necesario, lea las Reglas de prevención XSS del Open Web Application Security Project para comprender algunas de las preocupaciones que deberá tener en cuenta.
Depende del contexto. Algunos contextos posibles en HTML:
- cuerpo del documento
- dentro de atributos comunes
- dentro de las etiquetas de script
- etiquetas de estilo interiores
- ¡varios más!
Consulte la hoja de trucos para la prevención de secuencias de comandos entre sitios de OWASP , especialmente las secciones "¿ Por qué no puedo simplemente codificar datos no confiables con entidades HTML? " y " Reglas de prevención XSS ". Sin embargo, es mejor leer el documento completo.
Básicamente, hay tres caracteres principales que siempre deben tener caracteres de escape en sus archivos HTML y XML, para que no interactúen con el resto de las marcas, por lo que, como probablemente esperará, dos de ellos serán los envoltorios de sintaxis, que son < >, se enumeran a continuación:
1) < (<)
2) > (>)
3) & (&)
También podemos usar comillas dobles (") como " y comillas simples (') como &apos.
Evite poner contenido dinámico en <script>
y <style>
. Estas reglas no se aplican a ellos. Por ejemplo, si tiene que incluir JSON en un archivo, reemplace < con \x3c, el carácter U+2028 con \u2028 y U+2029 con \u2029 después de la serialización JSON).
Caracteres de escape HTML: lista completa: http://www.theukwebdesigncompany.com/articles/entity-escape-characters.php
Por lo tanto, debes escapar <, o & cuando va seguido de cualquier cosa que pueda comenzar una referencia de carácter. Además, la regla sobre los signos y es la única regla de este tipo para los atributos entrecomillados, ya que la comilla coincidente es lo único que terminará uno. Pero si no desea terminar el valor del atributo allí, escape las comillas.
Cambiar a UTF-8 significa volver a guardar su archivo:
usar la codificación de caracteres UTF-8 para su página significa que puede evitar la necesidad de la mayoría de los escapes y simplemente trabajar con caracteres. Sin embargo, tenga en cuenta que para cambiar la codificación de su documento, no basta con cambiar la declaración de codificación en la parte superior de la página o en el servidor. Debe volver a guardar su documento en esa codificación. Para obtener ayuda para comprender cómo hacer eso con su aplicación, lea Configuración de codificación en aplicaciones de creación web.Personajes invisibles o ambiguos:
Una función particularmente útil para los escapes es representar personajes que son invisibles o ambiguos en su presentación.
Un ejemplo sería el carácter Unicode U+200F MARCA DE DERECHA A IZQUIERDA. Este carácter se puede utilizar para aclarar la direccionalidad en texto bidireccional (por ejemplo, cuando se utilizan escrituras árabe o hebrea). Sin embargo, no tiene forma gráfica, por lo que es difícil ver dónde se encuentran estos caracteres en el texto y, si se pierden u olvidan, podrían crear resultados inesperados durante la edición posterior. Usar (o su equivalente de referencia de caracteres numéricos ) hace que sea muy fácil detectar estos caracteres.
Un ejemplo de carácter ambiguo es U+00A0 ESPACIO SIN INTERRUPCIÓN. Este tipo de espacio evita los saltos de línea, pero se parece a cualquier otro espacio cuando se utiliza como carácter. El uso deja bastante claro dónde aparecen dichos espacios en el texto.
Si desea escapar de una cadena de marcado usando JavaScript, existe:
- https://github.com/component/escape-html
o, si no desea generar una dependencia, aquí tiene lo mismo, aunque un poco más lento porque usa split/map/join
en lugar de charCodeAt/substring
.
function escapeMarkup (dangerousInput) {
const dangerousString = String(dangerousInput);
const matchHtmlRegExp = /["'&<>]/;
const match = matchHtmlRegExp.exec(dangerousString);
if (!match) {
return dangerousInput;
}
const encodedSymbolMap = {
'"': '"',
'\'': ''',
'&': '&',
'<': '<',
'>': '>'
};
const dangerousCharacters = dangerousString.split('');
const safeCharacters = dangerousCharacters.map(function (character) {
return encodedSymbolMap[character] || character;
});
const safeString = safeCharacters.join('');
return safeString;
}
La respuesta exacta depende del contexto. En general, estos caracteres no deben estar presentes ( HTML 5.2 §3.2.4.2.5 ):
Los nodos de texto y los valores de atributos deben consistir en caracteres Unicode, no deben contener caracteres U+0000, no deben contener caracteres Unicode permanentemente indefinidos (no caracteres) y no deben contener caracteres de control que no sean caracteres de espacio. Esta especificación incluye restricciones adicionales sobre el valor exacto de los nodos de texto y los valores de atributos según su contexto preciso.
Para elementos en HTML, las restricciones del modelo de contenido de texto también dependen del tipo de elemento. Por ejemplo, no es necesario escapar un "<" dentro de un elemento de área de texto en HTML porque el área de texto es un elemento de texto sin formato que se puede escapar.
Estas restricciones se encuentran dispersas en toda la especificación. Por ejemplo, los valores de los atributos ( §8.1.2.3 ) no deben contener un signo ambiguo y estar (i) vacíos, (ii) entre comillas simples (y por lo tanto no deben contener el carácter U+0027 APOSTROPHE '
), (iii) entre comillas dobles ( no debe contener el carácter U+0022 COMILLA "
), o (iv) sin comillas, con las siguientes restricciones:
... no debe contener ningún carácter de espacio literal, ningún carácter U+0022 COMILLAS ("), U+0027 caracteres APOSTROFO ('), U+003D caracteres SIGNO IGUAL (=), U+003C caracteres SIGNO MENOR ( <), U+003E caracteres de SIGNO MAYOR QUE (>) o U+0060 caracteres de ACENTO GRAVE (`), y no debe ser una cadena vacía.