2010-09-21 10 views
1

Je reçois une chaîne à partir de l'identificateur de fragment de la fenêtre en cours (location.hash). Je veux utiliser cette chaîne comme argument à location.replace(str).assainissement des chaînes d'URL non fiables qui seront transmises à location.replace

Dans des circonstances normales, la chaîne viendra du contrôle de code I, donc je ne suis pas inquiet de valider que la chaîne est une URL. Si la chaîne n'est pas une URL, l'appel à remplacer échouera tout simplement. C'est très bien. Ce qui m'inquiète, c'est de m'assurer que la chaîne n'est PAS une URL javascript: ou toute autre chose qui permettrait à quelqu'un d'exécuter Javascript arbitrairement sur mon domaine. Actuellement, je vérifie juste que str.indexOf('http') == 0.

Est-ce suffisant ou devrais-je désinfecter cette chaîne un peu plus?

Répondre

3

La désinfection que vous proposez ne suffit pas.

Un attaquant pourrait rediriger vers une URL data:uri contenant le code html/javascript encodé en base64. Cela permettrait à l'attaquant d'exécuter du code javascript arbitraire. Par exemple, cet extrait de code alertera « XSS » (Firefox, Safari et Opera)

 

    var data = 'data:text/html;base64,PHNjcmlwdD5hbGVydCgiWFNTIik8L3NjcmlwdD4='; 
    location.replace(data); 
 

Par ailleurs, il peut être possible de rediriger vers une URL FTP anonyme, ou utiliser un autre protocole obscur. Au lieu de mettre des protocoles/mots-clés en liste noire, utilisez une approche de liste blanche à la place. Maintenir une liste de bonnes URL dans votre code javascript. Ensuite, lisez l'identificateur de fragment et voyez s'il se trouve dans cette liste connue d'URL. Si ce n'est pas le cas, arrêtez le processus. En sécurité, les listes blanches sont toujours préférables aux listes noires.

+0

Votre exemple de chaîne de données ne passerait pas le test que j'ai proposé car il ne commence pas par 'http'. Je ne pense pas que je doive m'inquiéter des redirections non plus. J'essaie seulement d'empêcher l'exécution de Javascript non autorisé dans le contexte de mon domaine. – Brian

+0

Eh bien, votre code teste pour 'indexOf' http et ne commence pas avec http. Si l'attaquant place http quelque part dans la charge utile, votre test passerait, et l'attaquant serait toujours capable d'exécuter du code javascript. –

+0

str.indexOf ('http') == 0 est équivalent à startsWith. – Brian