2009-12-15 20 views
7

Al generar HTML, hay varios lugares diferentes donde el texto se puede interpretar como caracteres de control en lugar de como literales de texto. Por ejemplo, en el texto "normal" (es decir, fuera de cualquier elemento de marcado):¿Cuáles son todos los contextos de escape de HTML?

<div>This is regular text</div> 

así como dentro de los valores de atributos:

<input value="this is value text"> 

Y, creo, dentro de los comentarios HTML:

<!-- This text here might be programmatically generated 
and could, in theory, contain the double-hyphen character 
sequence, which is verboten inside comments --> 

Cada uno de estos tres tipos de texto tiene reglas diferentes para la forma en que debe ser escapado con el fin de ser tratada como no marcado. Así que mi primera pregunta es, ¿hay algún otro contexto en HTML en el que los caracteres se puedan interpretar como caracteres de marcado/control? Los contextos anteriores claramente tienen diferentes reglas sobre lo que se debe evitar.

La segunda pregunta es, ¿cuáles son las listas canónicas de caracteres (para cada contexto) que se deben escapar para garantizar que cualquier texto incrustado se trate como no marcado? Por ejemplo, en teoría solo necesita escapar 'y "en valores de atributo, ya que dentro de un valor de atributo solo el carácter de delimitador de cierre (' o" dependiendo del delimitador con el que comenzó el valor de atributo) tendría significado de control. Del mismo modo, dentro del texto "normal", solo < y & tienen un significado de control. (Me doy cuenta de que no todos los analizadores HTML son idénticos. Lo que más me interesa es cuál es el conjunto mínimo de caracteres que necesitan escaparse para apaciguar un analizador que cumpla con las especificaciones.)

Tangencial: El siguiente texto arrojará errores como HTML 4.01 Strict:

<a href="http://example.com/file.php?x=1&y=2">foo</a> 

en concreto, se dice que no sabe lo que se supone que la entidad "& y" para ser. Si pone un espacio después del &, sin embargo, lo valida bien. Pero si está generando esto sobre la marcha, probablemente no querrá comprobar si cada uso de & causará un error de validación, y en su lugar solo escape todos los valores de atributo &.

+0

Por cierto, me di cuenta de que no hay "secuencia de escape" para - dentro de un comentario HTML; simplemente están prohibidos (dado que los comentarios son ignorados por el analizador y no son procesados, una secuencia de escape no serviría para nada). Si por algún motivo necesitas incluir un comentario que incluya -, deberías quitarlo o reemplazarlo por algo menos ofensivo (U + 2014 EM DASH, por ejemplo). – dirtside

+0

tan simplemente ponga cuál es su pregunta. – Kieran

Respuesta

11
<div>This is regular text</div> 

Contenido del texto: & debe escaparse. < debe ser escapado.

Si se produce un documento en una codificación que no sea UTF, se deben escapar los caracteres que no quepan dentro de la codificación elegida.

En XHTML (y XML en general), la secuencia ]]> no debe aparecer en el contenido de texto, por lo que en ese caso específico debe escaparse uno de los caracteres de esa secuencia, tradicionalmente el >. Para mayor coherencia, la especificación XML canónica elige escaparse > cada vez en contenido de texto, lo cual no es una mala estrategia para una función de escape, aunque ciertamente puede omitirlo para la creación manual.

<input value="this is value text"> 

valores de atributo: & deben escaparse. Debe escaparse el delimitador de valor de atributo " o '. Si no se usa ningún delimitador de valor de atributo (no lo haga), no es posible escapar.

Canonical XML siempre elige " como el delimitador y, por lo tanto, se escapa de él. No es necesario que el carácter > se escape en valores de atributo y Canonical XML no. La especificación HTML4 sugirió la codificación > de todos modos para compatibilidad con versiones anteriores, pero esto afecta solo a unos pocos navegadores realmente antiguos y aterradores que nadie recuerda ahora; puedes ignorar eso.

En XHTML < se debe escapar. Si bien puedes escapar sin escaparte en HTML4, no es una buena idea.

Para incluir pestañas, CR o LF en los valores de los atributos (sin que se conviertan en espacios simples mediante el algoritmo de normalización del valor del atributo), debe codificarlos como referencias de caracteres.

Por tanto el contenido del texto y valores de atributos: en XHTML con XML 1.1, debe escapar los caracteres restringidos, que son el carácter Eliminar y códigos de control C0 y C1, menos pestaña, CR, LF y NEL. En total, [\x01-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F]. El carácter nulo puede no incluirse, incluso escapó en XML 1.1. Fuera de XML 1.1 no puede usar ninguno de estos caracteres, ni hay una buena razón por la que quiera hacerlo.

<!-- This text here might be programmatically generated 
and could, in theory, contain the double-hyphen character 
sequence, which is verboten inside comments --> 

Sí, pero como no hay escapatoria posible dentro de los comentarios, no hay nada que puedas hacer al respecto. Si escribe <!-- &lt; -->, significa literalmente un comentario que contenga "ampersand-letter l-letter t-puntoicolon" y se reflejará como tal en el DOM u otro infoset. Un comentario que contiene -- simplemente no se puede serializar en absoluto.

<![CDATA[ secciones y <?pi s en XML tampoco pueden usar el escape. La solución tradicional para serializar una sección CDATA que incluye una secuencia ]]> es dividir esa secuencia en dos secciones CDATA para que no ocurra al mismo tiempo. No puede serializarlo en una sola sección CDATA, y no puede serializar un PI con ?> en los datos.

CDATA-elementos como <script> y <style> en HTML (no XHTML) no pueden contener la secuencia de </ (ETAGO) ya que esto terminaría el elemento temprano y luego de error si no seguido por el-tag-nombre final. Dado que no es posible escapar dentro de los elementos CDATA, esta secuencia debe evitarse y solucionarse (por ejemplo, al convertir document.write('</p>') en document.write('<\/p>');. (Usted ve muchas estrategias tontas más complicadas para sortear esta, como llamar al unescape en un JS- % -cadena codificada; incluso a menudo '</scr'+'ipt>' que aún no es válida.)

Hay un contexto más en HTML y XML donde se aplican diferentes reglas, y eso está en la DTD (incluido el subconjunto interno en la declaración DOCTYPE, si tiene uno), donde el carácter % tiene Poderes especiales y debería escaparse para usarlo literalmente. Pero como autor de documentos HTML, es muy poco probable que alguna vez tenga que acercarse a ese lío.

The following text will throw errors as HTML 4.01 Strict: 

<a href="http://example.com/file.php?x=1&y=2">foo</a> 

Sí, y es tanto un error en Transitional.

If you put a space after the &, however, it validates just fine. 

Sí, bajo SGML descarta cualquier cosa menos [A-Za-z] y # no se inicia sea interpretado como una referencia. No es una buena idea confiar en esto sin embargo. (Por supuesto, no está bien formado en XHTML.)

+0

Gracias. En realidad, no me preocupaba XML aquí, solo HTML, pero ya verificaste lo que yo pensaba que era el caso. – dirtside

1

Los contextos anteriores claramente tienen diferentes reglas sobre lo que se debe evitar.

No estoy seguro de que los diferentes elementos tengan reglas de codificación diferentes, como usted dice. Todos los ejemplos que lista requieren la codificación HTML.

E.g.

<h1>Fish &amp; Chips</h1> 
<img alt="Awesome picture of Meat Pie &amp; Chips" /> 
<a href="products.aspx?type=1&amp;meal=fish%20%26%20chips&amp;page=1">Fish &amp; Chips</a> 

El último ejemplo incluye algunos de codificación URL para el signo también (&) y su en este punto las cosas se ponen peludas (envío de un signo como datos, por lo que debe ser codificada).

Así que mi primera pregunta es, ¿hay algún otro contexto en HTML en el que los caracteres se puedan interpretar como caracteres de marcado/control?

En cualquier lugar dentro del documento HTML, si los caracteres de control no se utilizan como caracteres de control, debe codificarlos (como una buena regla general). La mayoría de las veces, su codificación HTML, etc. & o > othertimes, cuando se trata de pasar estos personajes a través de una URL, el uso de codificación de URL% 20,% 26 etc.

La segunda pregunta es, ¿cuáles son las listas de caracteres canónicas, globalmente seguras (para cada contexto) que necesitan ser escapadas para asegurar que cualquier texto incrustado sea tratado como no marcado?

yo diría que el Wikipedia article tiene algunos buenos comentarios sobre ella y podría ser digno de una lectura - también la W3 Schools article supongo que es un buen punto. La mayoría de los lenguajes tienen incorporadas funciones para preparar el texto como HTML seguro, por lo que puede valer la pena verificar el idioma de su elección (si incluso está utilizando algún lenguaje de scripting y no está codificando manualmente el HTML).

Específicamente, Wikipedia dice: "Caracteres <,>," y & se utilizan para delimitar etiquetas, valores de atributos y referencias de caracteres. Referencias de entidades de caracteres & lt ;, & gt ;, & quot; y & amp ;, que están predefinidas en HTML, XML y SGML, puede utilizarse en lugar de representaciones literales de los personajes ".

para la codificación URL, this article seems a good starting point.

pensamientos de cierre como ya he divagado un poco: todo esto excluye los pensamientos de XML/XHTML que trae un juego completamente diferente a la cancha y su requisito de que casi todo el mundo y su perro necesitan ser codificados. Si está usando un lenguaje de scripting y está escribiendo una variable a través de eso, estoy bastante seguro de que será más fácil encontrar la función incorporada, o descargar una biblioteca que lo hará por ti. :) Espero que esta respuesta haya tenido un buen alcance y no hayas perdido el punto o pregunta o aparece en el tono equivocado :)

+0

Tienen diferentes reglas de escape; no necesita escapar un dirtside

+0

De acuerdo. Me limitaría a codificar todo el tiempo, lo que reduciría las posibilidades de que se escape un error. :) – Amadiere

0

Si le preocupa la validez del HTML final, puede considerar construir el HTML a través de un DOM, en lugar de como texto.

No dices a qué entorno estás apuntando.

+0

No me preocupa la práctica aquí, solo con la teoría. El comportamiento de diferentes navegadores web * a un lado *, ¿cuál es, teóricamente, la mejor práctica para escapar? – dirtside

+0

O más bien, la mejor * teoría * ;-) – dirtside

1

Si está buscando las mejores prácticas para escapar de los caracteres en los navegadores web (incluyendo HTML, JavaScript y hojas de estilo), la hoja de seguridad de prevención XSS de Michael Coates es probablemente lo que está buscando. Incluye una descripción de los diferentes contextos de interpretación, tablas que indican cómo codificar caracteres en cada contexto y muestras de código (usando ESAPI).

http://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet

0

Tenga en cuenta que <script> seguido por <!-- seguido por <script> vez más, entra en estado de doble escape, en el que es probable que nunca quiere ser, así que lo ideal es que escapar < con "\ u003C" dentro de cadenas de la secuencia de comandos (y expresiones regulares) para no activarlo accidentalmente.

Puede leer más sobre esto aquí http://qbolec-memdump.blogspot.com/2013/11/script-tag-content-madness.html

Cuestiones relacionadas