Javascript: Evaluer du code sans eval()

Written by aaSSfxxx -

Des connaissances du langage Javascript peuvent être nécessaires pour la compréhension de cet article

Traditionnellement, on utilise la fonction eval() pour évaluer un morceau de code javascript. Or cette fonction est bien souvent bloquée par la plupart des filtres anti-XSS rudimentaires. Il existe cependant beaucoup de techniques permettant de passer au travers de ces filtres, et de parvenir malgré tout à exécuter le code de notre choix.
Nous allons donc survoler ici quelques méthodes permettant de contourner les filtres anti-XSS.

Créons une fonction !

En javascript, tout est objet mais aussi fonction. Ainsi, une fonction javascript est considérée comme un objet, et un objet est aussi considéré comme une fonction (compliqué tout ça, hein?). Tout cela pour dire que une fonction javascript est représentée par un objet "Function", dont le constructeur admet un argument: le code à exécuter. Le code Function("alert('Bonjour tous!')") va donc créer une fonction anonyme qui affichera "Bonjour tous!" une fois appelée. Ainsi, en l'appelant juste après sa création, nous pouvons exécuter n'importe quel code de notre choix.
Mais l'inconvénient de cette méthode est que notre code ressemble à du javascript, et il se peut que le code soit filtré. Nous allons donc voir comment contourner tout cela.

Obfusquons notre code !

Nous allons tout d'abord prendre le cas où le mot clé "function" est bloqué (sans souci de casse, c'est-à-dire que "Function" sera aussi bloqué). Il nous faut donc retrouver le constructeur perdu. Or, si vous vous souvenez de ce que j'ai dit avant, une fonction est un objet pour javascript. Or les objets possèdent une propriété "constructor" qui renvoie le constructeur qui a servi à les créer. Le constructeur d'une fonction est donc... "Function". On va donc prendre une fonction au hasard (tiens, window.open), et s'en servir pour exécuter notre code:

window.open.constructor("alert('Bonjour tous!')")()

Maintenant, compliquons un peu la chose. Supposons que le mot clé "constructor" ainsi que "window.open" soient bloqués (ou que vous vouliez rendre votre code particulièrement illisible). Avant de continuer, il vous faut vous rappeler que la notation objet.propriete équivaut à objet["propriete"]. Ensuite, il faut savoir que un nombre ou une chaîne de caractères sont aussi des objets et possèdent un constructeur. Or, ce constructeur est une fonction, qui possède aussi son constructeur ... Avec tous ces renseignements, vous devriez être en mesure de contourner le blocage simple de mots clés (indice: "constructor" == "con"+"str"+"uctor"). A vous de jouer!

Conclusion

Avec tout ceci, nous avons pu voir que le filtrage de mots-clés est totalement inutile, puisqu'un peu de créativité de la part du hacker permet de faire disparaître totalement toute trace des mots clés bloqués. Ainsi, il est fortement recommandé d'interdire aux utilisateurs d'entrer du code HTML, et de passer par des langages comme BBCode pour le formatage (attention cependant à ne pas le parser n'importe comment!).
Enfin, certaines personnes pensent qu'en mettant une interface WYSIWYG à la place du HTML sur leur site pour les utilisateurs est une protection efficace. Ceci est totalement faux: un simple script ou l'utilisation de Firebug permet de contourner aisément la protection. Prenez donc garde à ce que les utilisateurs peuvent entrer sur votre site !