XSS: ¿Qué etiquetas y atributos HTML pueden desencadenar eventos de Javascript?

11 minutos de lectura

XSS: ¿Qué etiquetas y atributos HTML pueden desencadenar eventos de Javascript?
Alix Axel

Estoy tratando de codificar un purificador HTML seguro y liviano basado en una lista blanca que usará DOMDocument. Para evitar una complejidad innecesaria, estoy dispuesto a hacer los siguientes compromisos:

  • Se eliminan los comentarios HTML
  • script y style las etiquetas se quitan todas juntas
  • sólo los nodos secundarios del body se devolverá la etiqueta
  • todos los atributos HTML que pueden desencadenar eventos de Javascript serán validados o eliminados

He estado leyendo mucho sobre ataques XSS y prevención y espero no ser demasiado ingenuo (si lo soy, ¡hágamelo saber!) al suponer que si sigo todas las reglas que mencioné anteriormente, seré a salvo de XSS.

El problema es que no estoy seguro de qué otras etiquetas y atributos (en cualquier [X]versión HTML y/o versiones/implementaciones del navegador) pueden desencadenar eventos de Javascript, además de la atributos de evento predeterminados de Javascript:

  • onAbort
  • onBlur
  • onChange
  • onClick
  • onDblClick
  • onDragDrop
  • onError
  • onFocus
  • onKeyDown
  • onKeyPress
  • onKeyUp
  • onLoad
  • onMouseDown
  • onMouseMove
  • onMouseOut
  • onMouseOver
  • onMouseUp
  • onMove
  • onReset
  • onResize
  • onSelect
  • onSubmit
  • onUnload

¿Existen otros atributos de eventos no predeterminados o propietarios que puedan desencadenar eventos de Javascript (o VBScript, etc.) o la ejecución de código? Puedo pensar en href, style y action, por ejemplo:

<a href="https://stackoverflow.com/questions/6976053/javascript:alert(document.location);">XSS</a> // or
<b style="width: expression(alert(document.location));">XSS</b> // or
<form action="https://stackoverflow.com/questions/6976053/javascript:alert(document.location);"><input type="submit" /></form>

Probablemente eliminaré cualquiera style atributos en las etiquetas HTML, el action y href Los atributos plantean un desafío mayor, pero creo que el siguiente código es suficiente para asegurarse de que su valor sea una URL relativa o absoluta y no un código Javascript desagradable:

$value = $attribute->value;

if ((strpos($value, ':') !== false) && (preg_match('~^(?:(?:s?f|ht)tps?|mailto):~i', $value) == 0))
{
    $node->removeAttributeNode($attribute);
}

Entonces, mis dos preguntas obvias son:

  1. ¿Me falta alguna etiqueta o atributo que pueda desencadenar eventos?
  2. ¿Hay algún vector de ataque que no esté cubierto por estas reglas?

Después de muchas pruebas, reflexiones e investigaciones, he llegado a la siguiente (bastante simple) implementación que parece ser inmune a cualquier vector de ataque XSS que pueda lanzarle.

Aprecio mucho todas sus valiosas respuestas, gracias.

  • Su búsqueda de un URI puede ser engañada si un navegador admite direcciones URL mal formadas como http:jascript:alert(....

    – hakré

    07 ago.

  • bueno, hay muchas variaciones posibles en la evaluación de javascript, como codificar y decodificar. eval, archivo javascript externo, etc. Básicamente, no existe un método conocido que evite que el usuario haga algo malo. Puede intentar escapar de etiquetas, palabras, comillas, pero aún es posible inyectar xss a través de métodos interesantes. Sugiero leer seguridad de sombrero blanco para este problema, ¿quizás puedas encontrar algo útil?

    – Ígoris Azanovas

    07 ago.

  • Eso no suena “basado en la lista blanca”. Un enfoque basado en la lista blanca sería copiar solo las etiquetas y los atributos que sabe que son inofensivo. No necesita una lista de atributos harm_ful_ para eso.

    – hmakholm sobró Monica

    07 ago.

  • @hakre: Mientras no se ejecute Javascript, realmente no me importa si el enlace está roto. Según mis pruebas limitadas (y no tengo una gran cantidad de sistemas operativos, navegadores), ese fragmento (y algunas otras variaciones) no funcionará.

    – Alix Axel

    07 ago.

  • @Henning: Debería haberlo dejado más claro… Las etiquetas siempre deben estar en la lista blanca (script y style sin embargo, siempre se eliminará). Los atributos de la etiqueta pueden estar en la lista blanca o no (permitir todos los atributos, que deben estar internamente desinfectado o en la lista negra). Si permites el a etiqueta, probablemente también necesite permitir la href atributo y todavía tiene el mismo problema; es por eso que pensé en un enfoque de lista negra de segundo paso, ya que incluir en la lista blanca todos los valores de atributo de etiqueta posibles sería demasiado engorroso y altamente susceptible al error humano.

    – Alix Axel

    07 ago. 11 en 22:15

XSS: ¿Qué etiquetas y atributos HTML pueden desencadenar eventos de Javascript?
mike samuel

Mencionas href y action como lugares javascript: Pueden aparecer direcciones URL, pero te falta la src atributo entre un montón de otros atributos de carga de URL.

Línea 399 del OWASP Java HTMLPolicyBuilder es la definición de atributos de URL en un desinfectante HTML de lista blanca.

private static final Set<String> URL_ATTRIBUTE_NAMES = ImmutableSet.of(
  "action", "archive", "background", "cite", "classid", "codebase", "data",
  "dsync", "formaction", "href", "icon", "longdesc", "manifest", "poster",
  "profile", "src", "usemap");

El Índice HTML5 contiene un resumen de los tipos de atributos. No menciona algunas cosas condicionales como <input type=URL value=...> pero si escaneas esa lista para URL válida y amigos, deberían tener una idea decente de lo que agrega HTML5. El conjunto de Atributos de HTML 4 con tipo %URI también es informativo.

Su lista blanca de protocolos es muy similar a la Desinfectante OWASP una. La suma de ftp y sftp parece bastante inocuo.

Una buena fuente de información de esquema relacionada con la seguridad para elementos y atributos HTML es el Listas blancas Caja JSON que son utilizados por la Caja Desinfectante JS HTML.

¿Cómo planea renderizar el DOM resultante? Si no tienes cuidado, incluso si quitas todos los <script> elementos, un atacante podría obtener un renderizador con errores para producir contenido que un navegador interpreta como que contiene un <script> elemento. Considere el HTML válido que no contiene un elemento de secuencia de comandos.

<textarea><&#47;textarea><script>alert(1337)</script></textarea>

Un renderizador con errores podría generar el contenido de esto como:

<textarea></textarea><script>alert(1337)</script></textarea>

que contiene un elemento de script.

(Divulgación completa: escribí fragmentos de los dos desinfectantes HTML mencionados anteriormente).

  • Tu respuesta es oro, ¡+10 si pudiera! Investigué el OWASP PHP Sanitizer pero solo había una clase abstracta allí, la versión de Java, sin embargo, parece muy completa. No estoy exactamente seguro de cómo probar si Javascript se está ejecutando dentro de algunos de los atributos que mencionó, si lo sabe, hágamelo saber. Las listas blancas de Google Caja también son bastante ordenadas.

    – Alix Axel

    08 ago.

  • Oh, en cuanto a la representación DOM, mi código sigue siendo bastante nervioso, pero estaba usando el PHP incorporado. strip_tags() con las etiquetas de la lista blanca (para quitarle trabajo a la dom extensión) y luego atravesando los nodos HTML restantes con DOMDocument eliminando la etiqueta o los nodos de atributos si no estaban en la lista blanca o en la lista negra de forma permanente. Creo que he detectado algunos errores en strip_tags() así que reescribiré todo usando solo el dom extensión. Todavía estoy probando si necesito usar tidy antes, o si dom es lo suficientemente inteligente solo.

    – Alix Axel

    08 ago.


  • my.opera.com/karlcow/blog/…

    – Alix Axel

    10 ago. 11 en 10:08

  • stackoverflow.com/questions/2725156/…

    – Alix Axel

    10 ago. 11 en 10:21

  • Perdón por publicar todos estos enlaces, pero tengo una gran cantidad de pestañas abiertas en cajeros automáticos y podrían interesarle a alguien. “Busqué” en la lista blanca de atributos de Caja e hice un poco de Google y aparentemente el proyecto OWASP no contempla los siguientes (nuevos) atributos: profile, manifest, poster, formaction, icon y longdesc. Además, no pude encontrar ninguna referencia a la dsync atributo que mencionaste, ¿tienes alguno?

    – Alix Axel

    10 ago. 11 en 10:28

XSS: ¿Qué etiquetas y atributos HTML pueden desencadenar eventos de Javascript?
Píldoras de explosión

Garuda ya ha dado lo que yo consideraría como la respuesta “correcta”, y sus enlaces son muy útiles, ¡pero se me adelantó!

Doy mi respuesta sólo para reforzar.

En esta era de características cada vez mayores en las especificaciones de html y ecmascript, evitar la inyección de scripts y otras vulnerabilidades similares en html se vuelve cada vez más difícil. Con cada nueva incorporación, se introduce todo un mundo de posibles inyecciones. Esto se combina con el hecho de que los diferentes navegadores probablemente tengan diferentes ideas sobre cómo van a implementar estas especificaciones, por lo que obtiene aún más vulnerabilidades posibles.

Eche un vistazo a una breve lista de vectores introducidos por html5

La mejor solución es elegir lo que permitirás en lugar de lo que negarás. Es mucho más fácil decir “Estas etiquetas y estos atributos solo para las etiquetas dadas están permitidos. Todo lo demás se desinfectará en consecuencia o se desechará”.

Sería muy irresponsable de mi parte compilar una lista y decir “bien, aquí tienes: aquí tienes una lista de todos los vectores de inyección que te perdiste. Puedes dormir tranquilo”. De hecho, probablemente haya muchos vectores de inyección que ni siquiera los sombreros negros o los sombreros blancos conocen. Como dice el sitio web de ha.ckers, la inyección de secuencias de comandos solo está limitada por la mente.

Me gustaría responder a su pregunta específica al menos un poco, así que aquí hay algunas omisiones evidentes de su lista negra:

  • img src atributo. Creo que es importante señalar que src es un atributo válido en otros elementos y podría ser potencialmente dañino. img además dynsrc y lowsrc, tal vez incluso más.
  • type y language atributos
  • CDATA además de solo comentarios html.
  • Valores de entrada incorrectamente desinfectados. Esto puede no ser un problema dependiendo de qué tan estricto sea su análisis html.
  • Cualquier carácter especial ambiguo. En mi opinión, incluso los que no son ambiguos probablemente deberían codificarse.
  • Comillas faltantes o incorrectas en atributos (como comillas graves).
  • Cierre prematuro de etiquetas de área de texto.
  • UTF-8 (y 7) caracteres codificados en scripts
  • Aunque solo devolverá nodos secundarios de la etiqueta del cuerpo, muchos navegadores seguirán evaluando head, y html elementos dentro de body, y la mayoría head-solo elementos dentro de body de todos modos, así que esto probablemente no ayudará mucho.
  • Además de las expresiones css, las expresiones de imagen de fondo
  • framearena iframes
  • embed y probablemente object y applet
  • El lado del servidor incluye
  • Etiquetas PHP
  • Cualquier otra inyección (inyección SQL, inyección ejecutable, etc.)

Por cierto, estoy seguro de que esto no importa, pero los atributos camelCased no son xhtml válidos y deben estar en minúsculas. Estoy seguro de que esto no te afecta.

  • Buena respuesta, +1. El enlace que mencionas se basa en el onfocus atributo, si se elimina el nuevo autofocus atributo no representa ningún peligro por sí mismo, por lo que no considero que un nuevo vector de ataque, solo “empodera” a uno existente.

    – Alix Axel

    07 ago.

  • En cuanto a los puntos que mencionó, algunos de ellos pueden ser un problema, pero nuevamente uso un enfoque basado en una lista blanca: solo estoy tratando de compilar una lista negra que siempre se usará internamente (es decir, no configurable). El src El atributo es especialmente preocupante, probaré todo lo que mencionas y veré cómo va.

    – Alix Axel

    07 ago.

  • Cuando dice “expresión xss”, ¿quiso decir “expresión CSS” como en <div style="height: expression(alert(1337))"> para IE y moz-binding y similares para otros navegadores?

    –Mike Samuel

    08 ago.

Es posible que desee consultar estos 2 enlaces para obtener referencias adicionales:

http://adamcecc.blogspot.com/2011/01/javascript.html (esto solo es aplicable cuando la entrada ‘filtrada’ alguna vez se encontrará entre las etiquetas de script en una página)

http://ha.ckers.org/xss.html (que tiene una gran cantidad de activadores de eventos específicos del navegador enumerados)

He usado HTML Purifier, como lo está haciendo usted, por esta razón también en combinación con un editor wysiwyg. Lo que hice diferente fue usar una lista blanca muy estricta con un par de etiquetas y atributos de marcado básicos disponibles y expandirla cuando surgía la necesidad. Esto evita que te ataquen vectores muy oscuros (como el primer enlace de arriba) y puedes profundizar en la etiqueta/atributo recién necesitado uno por uno.

Solo mis 2 centavos..

  • Gracias, estaba al tanto de XSS Cheat Sheet. El primer enlace parece interesante, sin embargo, el póster resume exactamente lo que estoy tratando de evitar en una sola oración: “Así es, esto es una alerta () si aterriza en cualquier lugar en una sección ejecutable de JavaScript/dom aparece la cookie”. HTML Purifier es el de facto estándar para la desinfección de PHP HTML, pero también es muy pesado, espero que si hago algunos pequeños compromisos, podré encontrar algo que sea mucho más liviano.

    – Alix Axel

    07 ago.

  • Tienes toda la razón en la exageración de peso pesado 🙂 Aunque todavía tengo que experimentar retrasos obvios en la carga de la página debido a la desinfección por el purificador de HTML. Dado que es un marco bastante bien desarrollado, estoy bastante seguro de que los desarrolladores son conscientes de los problemas de rendimiento y lo más probable es que lo hayan hecho lo más ligero y rápido posible. Si sigue siendo un problema para usted personalmente, me gustaría recomendarle que consulte el almacenamiento en caché de código PHP (como APC) o desde el motor Zend.

    – Garuda

    07 ago.

  • todas las paginas no encontradas

    – MPGN

    24 abr.

No olvide los controladores de eventos de HTML5 JavaScript

http://www.w3schools.com/html5/html5_ref_eventattributes.asp

.

¿Ha sido útil esta solución?