Est-il possible d'exploiter XSS dans le code suivant?
jQuery(window.location.hash)
Il me semble que window.location.hash
commence toujours par un hachage #
, et jQuery moderne interprète toujours cela comme un sélecteur d'ID. Est-ce correct?
Oui, il est possible de faire quelque chose de malveillant avec jQuery(window.location.hash)
. Voir cet article de blog archivé qui a été mentionné dans un commentaire à ne réponse dans une autre question SE. Une attaque de synchronisation CSS peut être effectuée, comme cela a été décrit dans le blog:
Si nous exécutons le sélecteur
*:has(:has(:has(*)) :has(*) :has(*)) input[name=authenticity_token][value^='x']
, cela ne prendra du temps que si l'authenticité_token commence par 'x'.
Un site malveillant peut ouvrir un site cible dans une iframe et voir si le sélecteur met longtemps à correspondre. Si input[name=authenticity_token][value^='x']
Ne correspond pas, le sélecteur sera court-circuité et jQuery ne vérifiera pas les :has(...)
s les plus coûteuses.
Comme mentionné dans le billet de blog, si cela s'exécute dans un navigateur qui exécute les deux sites dans le même processus, le retard dans un site qui appelle le site victime peut être facilement mesuré. (Il me semble qu'il peut même y avoir une attaque de synchronisation possible même avec des processus séparés, car cela peut généralement ralentir l'ordinateur même si les processus sont planifiés séparément. En général, il est probable que des problèmes soient écrits pour qu'une page soit écrite telle qu'il peut faire beaucoup de traitement selon que quelque chose dans l'URL correspond à une chaîne secrète.)
Les correctifs 9521 et 1129 il y a plusieurs années tentent d'atténuer ce problème, mais ne prétendent pas supprimer complètement la possibilité pour XSS. J'ai exécuté dans jQuery 2.x certains des exploits qui, selon eux, existent toujours, mais ils ne semblent pas fonctionner, donc je ne peux pas définitivement confirmer et nier si le code que vous avez fourni est suffisant à exploiter.
Pour ce que ça vaut, il est également possible que cet exploit se produise si vous faites quelque chose avec l'objet jQuery. Supposons que vous ayez autorisé les clients à envoyer du code HTML et qu'un client ait soumis les éléments suivants:
<div id="xss">alert('xss');<div>
Et pour une raison folle, vous aviez le code suivant sur la page qui affiche ce HTML:
eval(jQuery(window.location.hash).text());
Un hachage d'URL de #xss
Entraînerait le déclenchement d'une alerte.
Je peux donc confirmer que c'est possible, bien qu'il serait très difficile d'exploiter cette manière particulière sans écrire le code spécifiquement pour être vulnérable.
Je recommanderais de faire une vérification de validation sur la valeur de window.location.hash
Ou de supprimer les caractères spéciaux avant de le passer à jQuery()
, et comme toujours, pensez à ce que vous faites avec l'objet jQuery.
Comme le mentionne la réponse de Goose, il semble qu'il y avait certaines versions antérieures de jQuery qui étaient vulnérables à cela.
Étant donné que la fonction jQuery peut convertir des chaînes en éléments DOM comme celui-ci ...
$(‘<p>Something</p>’);
Si votre code avait:
$(location.hash);
Et un attaquant vous a fait accéder à votre page avec une URL spécialement conçue qui se terminait par un fragment de hachage comme:
#p=<img src%3D/%20onerror%3Dalert(1)>
Ensuite, jQuery interpréterait le hachage comme HTML, créerait les éléments DOM nécessaires et exécuterait en fait tous les gestionnaires JS qui leur sont attachés.
Les futures versions de jQuery semblent avoir atténué cela en priorisant les sélecteurs d'ID sur HTML, donc tout ce qui commence par un hachage est traité comme un sélecteur CSS, pas comme HTML.
Pourquoi deviner? Désinfectez-le d'abord avec\w, c'est si simple. Cela semble assez terrifiant s'ils ont un contrôle complet sur cette ligne jQuery même si elle doit commencer par un hachage. Dans les mots de l'oie liée 9521 ,
Je suppose que la question est de savoir s'il s'agit d'un mouvement à tête d'os si commun que nous devons prioriser un sélecteur d'ID sur HTML pour ce cas. Je pourrais être convaincu.
et
Cependant, je ne sais pas comment nous pouvons généralement nous protéger contre cela. Le symbole de hachage est uniquement du texte et la chaîne est du code HTML valide. Les utilisateurs ne doivent pas transmettre d'entrée non fiable à $ () qui pourrait contenir un script.
Donc, selon au moins un développeur jQuery, cela n'est même pas du tout considéré comme une vulnérabilité - Et il veut laisser le soin au programmeur de ne pas le faire. Même si vous ne l'ajoutez pas maintenant, un responsable ultérieur le remarquera probablement et ajoutera window.location.hash.replace(/[^\w]/g, "")
. (Ou [^\w-]
si vous utilisez des tirets). Rien n'est vraiment sauvé en l'évitant. Bien sûr, ils peuvent l'atténuer, mais je n'aurais pas cette attitude étant la principale force derrière votre sécurité Web.
Mon go-to pour l'entrée utilisateur est un fichier JS spécial en haut qui gère toutes les entrées de nettoyage et stocke des choses comme window.location.hash dans une variable "UserHash" qui est déjà filtrée, avec une désinfection documentée pour que les autres sachent ce qu'ils peuvent assumer . J'ai constaté que ne pas le faire entraînerait inévitablement des vulnérabilités plus tard. Quelqu'un se demandera "Oh, c'est sûr ici, donc ce sera sûr ici", laissant les choses à la limite de la semi-sécurité tomber dans une vulnérabilité réelle.