Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
dev:cross-site_scripting [2007/07/02 12:21]
david.verdin@cru.fr
dev:cross-site_scripting [2007/08/29 16:12] (current)
david.verdin@cru.fr
Line 6: Line 6:
   * http://​ha.ckers.org/​xss.html   * http://​ha.ckers.org/​xss.html
   * http://​www.commentcamarche.net/​attaques/​cross-site-scripting.php3   * http://​www.commentcamarche.net/​attaques/​cross-site-scripting.php3
 +  * http://​www.cgisecurity.com/​articles/​xss-faq.shtml
 +  * http://​www.cert.org/​tech_tips/​cgi_metacharacters.html
  
-**Ces informations n'ont pas la prétention d'​être exhaustives**,​ mais nous vousles ​livrons car nous pensons qu'​elles peuvent aider les développeurs d'​applications web qui souhaitent protéger leurs applications contre ce type d'​attaques.+**Ces informations n'ont pas la prétention d'​être exhaustives**,​ mais nous vous les livrons car nous pensons qu'​elles peuvent aider les développeurs d'​applications web qui souhaitent protéger leurs applications contre ce type d'​attaques.
 </​note>​ </​note>​
  
Line 14: Line 16:
 ===== Cross-site quoi ? ===== ===== Cross-site quoi ? =====
  
-Si vous n'avez jamais entendu parler de cross-site ​srcipting ​(XSS), lisez quelques articles de fond avant de lire ce qui suit.+Si vous n'avez jamais entendu parler de cross-site ​scripting ​(XSS), lisez quelques articles de fond avant passer à la suite.
 Le principe du cross-site scripting est présenté dans plusieurs pages. Une bonne présentation synthétique se trouve dans [[http://​fr.wikipedia.org/​wiki/​Cross_site_scripting|wikipédia]]. Le site [[http://​www.cgisecurity.com/​articles/​xss-faq.shtml|www.cgisecurity.com]] propose une FAQ claire. Le principe du cross-site scripting est présenté dans plusieurs pages. Une bonne présentation synthétique se trouve dans [[http://​fr.wikipedia.org/​wiki/​Cross_site_scripting|wikipédia]]. Le site [[http://​www.cgisecurity.com/​articles/​xss-faq.shtml|www.cgisecurity.com]] propose une FAQ claire.
  
-En résumé, on peut dire que, dans notre contexte, un XSS est un appel à un script interprété côté client ​(en clair : du javascript), dissimulé dans une chaîne de caractère. Le gros du boulot est de contrer la dissismulation.+En résumé, on peut dire que, dans notre contexte, un XSS est un appel à un script interprété côté client, dissimulé dans une chaîne de caractère. Le gros du boulot est de contrer la dissismulation.
  
 ===== Objectif et limites du présent texte. ===== ===== Objectif et limites du présent texte. =====
Line 252: Line 254:
   * Les paramètres de l'​interface SOAP   * Les paramètres de l'​interface SOAP
   * Les archives.   * Les archives.
 +
  
 ====== Où faire intervenir le filtrage dans le code ? ====== ====== Où faire intervenir le filtrage dans le code ? ======
  
-Il existe une fonction bas niveau de contrôle des paramètres saisis.+ 
 +===== Pour l'​interface web et les URL ===== 
 + 
 +Il existe une fonction bas niveau de contrôle des paramètres saisis ​: la fonction ''​get_parameters()''​. Tous les paramètres utilisés par wwsympa.fcgi y passent. On filtre là, on est tranquilles. 
 + 
 +Tout n'est pas à filtrer drastiquement. La liste des éléments où le HTML est légitime est : 
 + 
 +  * le shared : lors de la création d'un fichier par l'​interface web, ou lors d'un upload de fichier (fonction ''​do_d_upload()''​) 
 +  * la homepage (dans customizing) 
 +  * l'​édition des templates 
 +  * les avis divergent sur le fichier "​info"​ 
 +  * PAS les archives. On peut éventuellement dissimuler du XSS dans le corps d'un message ensuite affiché par les archives. Il faut voir ce que MHonArc propose. 
 + 
 +Tous des éléments de formulaire HTML permettant de saisir ces paramètres ont le bon goût d'​avoir le même nom. Si ce sont les seuls, on n'a qu'à ajouter ce nom (''​content''​) à la liste des paramètres où le HTML est autorisé. 
 + 
 +Dans ''​get_parameters'',​ on va exploiter un hash contenant les noms des paramètres autorisés à contenir du HTML. Tous les autre paramè_tres seront filtrés. Si on trouve du HTML, on rejettera l'​action en cours. 
 + 
 +===== Pour le mail ===== 
 + 
 +Seul le gecos est dangereux par mail. 
 +On doit tester la valeur de ''​$i''​ (et tant qu'à y être renommer cette variable) dans la fonction ''​parse()''​ de ''​Commands.pm''​. 
 + 
 +===== Pour le serveur SOAP ===== 
 + 
 +On doit tester les paramètres passés aux fonctions ''​subscribe'',​ ''​add''​ et ''​createList''​ de ''​SympaTransport.pm''​. 
 +Si possible, essayer de trouver (ou créer) un accès centralisé aux paramètres passés au serveur SOAP. 
 + 
 +====== Les regexp ====== 
 + 
 +Ben c'est pas gagné... 
 + 
 +On prévoit d'​ajouter,​ dans le hash %regexp de tools.pm, deux regexp : 
 + 
 +  - ''​html-free''​ : permet de repérer toute chaîne de caractère contenant du HTML ; 
 +  - ''​xss-free''​ : ne permet de repérer que les chaînes contenant du HTML pouvant introduire du code dangereux. 
 + 
 +Autant on peut brutalement interdire le HTML (en repérant en gros les chaînes commençant par un chevron ouvrant) autant ça va être coton de repérer le XSS avec une simple regexp puisqu'​on ne repère pas forcément un XSS grâce à la chaîne HTML. 
 + 
 + 
 + 
 + 
 +===== html_free ===== 
 + 
 +Une première approche est d'​empécher purement et simplement de saisir le caractère "<",​ sous quelque forme que ce soit. 
 +99,9 % des XSS exploitent une balise HTML. La seule chose dont on est sûr c'est qu'une telle balise DOIT commencer par une caractères chevron ouvrant : "<"​. 
 + 
 +On peut raffiner en recherchant des chaînes du genre "<​blabla"​. C'​est-à-dire que "<"​ soit suivi de quelque chose qui pourrait être une balise. Ce qui nous place dans 99 % des cas d'​utilisation du chevron. En effet, même si on l'​emploie pour taper "​2<​3",​ on peut détecter une balise HTML avec cette méthode. 
 + 
 +Cela dit : qu'​est-ce qu'une telle chaîne pourrait bien venir foutre dans un paramètre de Sympa, hein ? 
 + 
 +On va donc faire ainsi. 
 + 
 +Regexp proposée : on repère le caractère "<"​ sous ses diverses formes : 
 +<​code>​$html_free = '​(<​|%3c|(&​+('​."​$dividers"​.'​)*(l('​."​$dividers"​.'​)*t|#​+x*0*(60|3c)+)+\;​*)|x*0*(60|3c))';​ 
 +Avec : 
 +$dividers = '​\s|&​+#​+x*0*(09|0a|0d)+\;​*';​ 
 +</​code>​ 
 +On ignore les espaces ainsi que leurs expressions en HTML. 
 + 
 +FIXME : Il manque le caractère nul. 
 + 
 + 
 + 
 + 
 +===== xss_free ===== 
 + 
 +Beaaaaaauuuuuucoup plus compliqué : On ne peut pas interdire toutes les chaînes de caractère contenant "<"​. Il faut donc trouver les mauvaises. 
 + 
 +OR, il existe au moins un exemple de XSS de la forme : 
 +<​code><​IMG src="​path/​monImage.jpeg"/></​code>​ 
 +Il suffit que le fichier monImage.jpeg ne contienne pas une image mais un script. Dans certains cas, il sera interprété. :-( 
 + 
 +Quelle solution nous reste-t-il ? 
 + 
 +Risquer les exceptions de ce genre, pour le moment, et filtrer les balises ci dessous : 
 + 
 +  * ''<​script/>''​ 
 +  * ''<​img/>''​ 
 +  * ''<​style/>''​ 
 +  * ''<​meta/>''​ 
 +  * ''<​body/>''​ 
 +  * ''<​*frame*/>''​ 
 +  * ''<​bgsound/>''​ 
 +  * ''<​input/>''​ 
 +  * ''<​link/>''​ 
 +  * ''<​layer/>''​ 
 +  * ''<​base/>''​ 
 +  * ''<​object/>''​ 
 +  * ''<​embed/>''​ 
 +  * ''<​applet/>''​ 
 + 
 +Et, dans le contexte de n'​importe quoui qui contienne un "<"​ : 
 + 
 +  * ''​style=''​ 
 +  * ''​dynsrc=''​ 
 +  * ''​lowsrc=''​ 
 +  * ''​onload=''​ et tous les déclencheurs : ''​on*=''​ 
 +  * ''​datasrc=''​ 
 +  * ''​javascript:''​ par acquis de conscience. ;-) 
 + 
 +Ça devrait être un bon début... 
 + 
 +Ça donne ces regexp : 
 + 
 +<​code>​ 
 +m$xss_free = "​($infSign)+($dividers)*((($tags)|.*($attributes))+|($encodedChars)+)";​ 
 + 
 +Avec : 
 + 
 +my $tags = '​script|\w*frame\w*|style|input|layer|bgsound|link|meta|base|object|embed|applet';​ 
 +my $attributes = '​style=|dynsrc=|lowsrc=|on\w*=|javascript:';​ 
 +my $dividers = '​\s|&​+#​+x*0*(9|a|d|10|13)+\;​*';​ 
 +my $encodedChars = '​(&​+('​."​$dividers"​.'​)*#​+x*0*[0-9a-f]+\;​*|%+x*0*[0-9a-f]+\;​*)';​ 
 +my $infSign = '​(<​|%3c|(&​+('​."​$dividers"​.'​)*(l('​."​$dividers"​.'​)*t|#​+x*0*(60|3c)+)+\;​*)|&​+('​."​$dividers"​.'​)*x*0*(60|3c))';​ 
 + 
 +</​code>​ 
 + 
 +====== Où en sommes-nous ? ====== 
 + 
 +Avant de partir pouponner, j'ai eu le temps d'​intégrer le filtrage XSS pour le web uniquement. 
 +J'ai donc mis à jour tools.pm et wwsympa.fcgi pour qu'il en tiennent compte. Ça a l'air de marcher. 
 + 
 +Il reste encore à faire : 
 + 
 +  * intégrer le contrôle au niveau SOAP 
 +  * intégrer le contrôle au niveau mail 
 +  * vérifier le comportement de MHonArc 
 +  * Vérifier les templates et paramètres autorisés au HTML 
 + 
 +Voili voilou. Cela dit, le gros du boulot (mise au point de la regexp) est bien posé. 
 +Reste à tester... 
  
  • dev/cross-site_scripting.1183371671.txt.gz
  • Last modified: 2007/07/02 13:53
  • (external edit)