2009-04-23 6 views
17

A veces, el lado del servidor generará cadenas para incrustar en el código JavaScript en línea. Por ejemplo, si ASP.NET debe generar "Nombre de usuario". Entonces parece.¿Es necesario "escapar" el carácter "<" and ">" para la cadena de javascript?

<script> 
    var username = "<%UserName%>"; 
</script> 

esto no es seguro, ya que un usuario puede tener su/su nombre para ser

</script><script>alert('bug')</script></script>

Es vulnerabilidad XSS.

Así que, básicamente, el código debe ser:

<script> 
    var username = "<% JavascriptEncode(UserName)%>"; 
</script> 

Lo que hace JavascriptEncode es añadir charater "\" antes de "/" y """ y """ Por lo tanto, la salida HTML. es como var nombre de usuario = "</script> alerta (\ 'bug \') </script> </script>";.

navegador no interpretar "</script> "como fin del bloque de scripts. Entonces, XSS en evitado.

Sin embargo, todavía hay "<" y ">" allí. Se sugiere escapar de estos dos personajes también. Antes que nada, no creo que sea una buena idea cambiar "<" a "& lt;" y ">" a "& gt;" aquí. Y no estoy seguro de cambiar "<" a "\ <" y ">" a "\>" es reconocible para todos los navegadores. Parece que no es necesario realizar más codificaciones para "<" y ">".

¿Hay alguna sugerencia al respecto?

Gracias.

Respuesta

16

El problema tiene diferentes respuestas según el lenguaje de marcado que esté utilizando.

Si está utilizando HTML, no debe representarlo con entidades ya que los elementos de script están marcados como que contienen CDATA.

Si está utilizando XHTML, puede representarlos como CDATA con marcadores CDATA explícitos, o puede representarlos con entidades.

Si está utilizando XHTML, pero lo sirve como texto/html, entonces necesita escribir algo que cumpla con las reglas de XHTML pero que aún funcione con un analizador de texto/html. Esto generalmente significa usar marcadores CDATA explícitos y comentarlos en JavaScript.

<script type="text/javascript"> 
// <![CDATA[ 
    … 
// ]]> 
</script> 

Hace un tiempo, escribí un poco sobre the hows and whys of this.

+1

Pero aún el '>' en ']]>' dentro del bloque CDATA debe ser repaldado por '>'. Entonces 'foo [bar [0]]> 1234' debe ser reemplazado por' foo [bar [0]] < 1234' o 'foo [bar [0]]> 1234'. De lo contrario, el bloque CDATA se cerraría prematuramente. – Gumbo

+0

Dado que CDATA representa y los caracteres significan "&" y no "Comienzo de la entidad" - eso no funcionaría. Si necesita representar la cadena "]]>" dentro de CDATA, entonces estoy bastante seguro de que está chiflado y debería estar usando entidades para empezar (fuera de un bloque CDATA) – Quentin

+7

O simplemente agregue un espacio: 'foo [bar [0 ]]> 1234' - o si es parte de una cadena: ''foo [bar [0]]' + '> 1234'' - o simplemente contiene todos tus scripts en archivos .js externos. – gnarf

13

No, no debe escapar < y > usando entidades HTML dentro de <script> en HTML.

  • cadena escapar reglas de uso de JavaScript (sustituir con \\\ y " con \")
  • y reemplazar todas las ocurrencias de </ con <\/, para evitar que se escape fuera del elemento <script>.

En XHTML es más complicado.

  • Si envía XHTML como XML (la forma en que es incompatible con IE) y no ejerza bloque CDATA, entonces usted necesita para escapar de las entidades, además de la cadena de JavaScript escapar.
  • Si envía XHTML como XML y usa el bloque CDATA, no escapa de las entidades, pero reemplace ]]> con ]]]]><![CDATA[> para evitar escapes (además de la cadena de JavaScript que se está escapando).
  • Si envía XHTML como text/html (lo que hace el 99% de las personas), entonces tiene que usar el bloque XML CDATA, el escape XML CDATA y el escape de HTML a la vez.
+5

+1. Minor nitpick: no todas las ocurrencias de ' ', o'/'terminará la respectiva etiqueta de apertura.] (Http://mths.be/etago) –

2

La forma barata y fácil:

<script type="text/javascript"> 
    var username = "<%= Encode(UserName) %>"; 
</script> 

donde el esquema de codificación en Encode es traducir cada carácter de entrada en el asociado \xABCD representación compatible con JavaScript.

Otra forma barata y fácil:

<script type="text/javascript"> 
    var username = decodeBase64("<%= EncodeBase64(UserName) %>"); 
</script> 

si se trata sólo de ASCII.

Por supuesto, pst golpeó el clavo en la cabeza con la estricta manera de hacerlo.

+0

+1 Además, esta solución hace que su código fuente de salida se vea h4x0r! –

Cuestiones relacionadas