En jQuery puedes especificar un selector de CSS y un código HTML con la misma forma abreviada.
Este es un selector:
$('#some-thing')
Este es el HTML que se evalúa de inmediato:
$('<svg onload=alert(1)>')
Este es un ejemplo de código de la vida real para analizar un selector desde el hash de ubicación (la parte de la URL después de un #
):
var x = $('#' + window.location.hash.substr(1));
x.addClass('highlighted').find('div').show();
Se tomó de esta pregunta y un enfoque similar es (peligrosamente) recomendado en este subproceso SO .
¿Ves el problema con eso? La intención del autor era permitir un selector CSS controlado por el usuario, pero si abre el sitio afectado como https://example.com/#<svg onload=alert(1)>
, terminará con este selector ambiguo:
$('#<svg onload=alert(1)>');
Las versiones anteriores de jQuery ejecutan esto como código HTML y, por lo tanto, crean una falla XSS ya que el controlador de eventos JS se ejecutaría inmediatamente una vez que se creara el nodo DOM. Sin embargo, las versiones más recientes deciden que una cadena que no comienza con un corchete angular debe analizarse como un selector, mitigando así la falla.
De los documentos :
Si se pasa una cadena como parámetro a $()
, jQuery examina la cadena para ver si parece HTML (es decir, comienza con <tag ... >
). Si no, la cadena se interpreta como una expresión de selector, como se explicó anteriormente. Pero si la cadena parece ser un fragmento de código HTML, jQuery intenta crear nuevos elementos DOM como se describe en el código HTML.
Puede leer acerca de cómo se cambió este comportamiento en la discusión a error # 9521 .
La página que vinculó solo señala con qué tipo de selector es vulnerable cada versión.