fév 23

C’est vrai, on ne se refait pas, alors les déformations professionnelles reprennent le dessus…

La confiance est le liquide amniotique de l’économie. Que ce soit dans le monde bancaire ou pour le E-commerce, cela reste vrai. La sécurité d’un site est donc un problème central. Le client considérera comme normal, comme le minimum syndical, que votre site soit sécurisé.

Si un jour cette confiance que votre client vous porte est prise en défaut, les conséquences sont dramatiques. Il sera quasiment impossible de remonter la pente si une mésaventure de sécurité arrive, les clients n’oseront plus payer en ligne sur le site concerné. Monster a éprouvé récemment de gros tracas, tout comme Myspace avec le ver « Sam is my hero » ou Facebook avec ses worm XSS. Nos tests d’intrusion et nos tests de sécurité externe nous montre tous les jours des failles en pagaille, alors voici un petit mot pour, au moins, éviter le pire et le plus trivial.

Sécurité de Zend et de PHP

Premièrement, Magento repose sur Zend et Zend est solide. PHP est pas mal troué, mais le framework Zend en lui même est plutôt clean. Donc si un buffer overflow (ou un dérivé du genre) existe dans Php, c’est à votre hébergeur de gérer ca coté serveur, avec par exemple GRsec+Pax. La plupart des failles dans PHP ne sont pas révélées par les hackers, tout le monde en garde une dans son coin, mais un bon patch GRsec fera correctement le boulot et évitera le pire.

Zend de son coté est une réelle avancée. Pour une fois, par défaut, un Framework propose une sécurité bien faite des contrôles des entrées utilisateurs. Car la majeure partie des failles provient de ce point. Les XSS (Cross Site Scripting) et une partie des SQL injection, sont possibles uniquement parce que le filtrage a été insuffisant sur un formulaire ou une barre de  recherche par exemple.

Si l’on ne s’éloigne pas trop du sujet Magento, le bilan est bon. Zend le protège, Varien n’a pas fait d’erreur de fond, tout va bien. Le facteur qui va mettre en risque le site c’est donc le développement « maison ». Un formulaire créé et contrôlé sans passer par Zend, c’est potentiellement la porte ouverte à nos amis XSS/SQLinject.

Filtrer les « user input »

Je code donc je porte une responsabilité de sécurité chapitre 1 !
Si vous développez en dehors des fonctions sécurisées de Zend, peu importe la raison, d’une manière générale : « Le moins, le mieux ». Limitez les jeux de caractères utilisés/acceptés au stricte nécessaire. Créez en plusieurs au besoin pour avoir de la granularité.

Si possible limitez à la regular expression suivante : [a-zA-Z0-9]
Sinon, si vous devez élargir un peu la regular expression suivante : [a-zA-Z0-9#[email protected]éèëêùàâôöïî],
on est encore dans l’acceptable,
par contre, à bannir au maximum : [-,',+,",&,$,%,\,<,>,|,\\,\,(,),\0,\n]
(je les ai séparé  par des virgules pour améliorer la lisibilité mais selon l’interpréteur de Regexp vous aurez peut être à enlever ces virgules et ce n’est pas \o mais bien \zéro).

Attention également aux encoding, à forcer sur toutes les pages, pour éviter de se faire envoyer des encodages exotiques qui contourneraient les protections. L’UTF8 est bon choix de part son coté universel et récent.

Owasp fournit une librairie pour aider les développeurs à éviter les XSS

Échappement des chaines

Utilisez Escape/unescape afin de nettoyer les donnés traitées

Pour PHP5, les fonctions htmlentities et htmlspecialchars sont vos amies

Upload de fichiers

Un bon gag bien célèbre que l’on croise souvent aussi : l’upload de fichier. Que du bonheur ! Si l’on ne contrôle pas le type de fichier reçu, on s’expose à de très graves déconvenues… Je vous garantie qu’un C99shell ou une backdoor PHP du genre, c’est la compromission complète du serveur en quelques heures maximum. Alors à réception d’un fichier, vérifier son type, appelez l’antivirus dessus et contrôlez son extension, cela peut éviter bien des malheurs car se faire envoyer une backdoor au lieu d’une photo ou d’un fichier HTML, c’est un classique qui fait toujours aussi mal.

Reverse Proxy & Firewall

Un Reverse proxy peut aussi aider. En dehors de sa « classique » fonction de cache, il peut aussi pour permettre de « nettoyer » les  URLs qui sont appelées et éventuellement, couplé à des flex rules ou un IDS, il peut bannir en temps réel sur votre Firewall les petits rigolos qui veulent forger des URL. (REJECT quand on est gentil, DROP si on l’est un peu moins et TARPIT si on est très fâché)

En général, un service Web doit exposer un port 80 et un 443. Le HTTP et le HTTPS sont publiques puisque tout le monde doit pouvoir s’y connecter, par contre, le service SSH, le FTP ou d’autres n’ont pas à être visibles depuis le monde entier. Il faut donc filtrer ces accès et les protéger. Un Firewall en tête de toute votre infrastrucutre fera bien l’affaire, il est aussi possible de Firewaller par machine puisque Netfilter est intégrer dans presque tous les noyaux Linux.

Protégez, au minimum votre port ssh, c’est un minimum. Si vous ne savez pas faire, juste pour le SSH, mettez dans un script (cat > ./ssh_filter.sh, à la fin CTRL+D puis chmod 755 ./ssh_filter.sh) :

#/bin/bash
/sbin/iptables -I INPUT -s xxx.xxx.xxx.xxx -p tcp –dport 22 -j ACCEPT
/sbin/iptables -I INPUT -p tcp –dport 22 -j DROP

Attention, il ne se lancera pas tout seul avec la machine si elle reboot, allez voir le howto (voir plus bas) si vous voulez des détails.

Remplacer xxx.xxx.xxx.xxx par l’IP depuis laquelle vous administrez le serveur. Oui c’est de la survie ultra minimale, mais un cour de firewalling c’est long à faire. Si vous voulez en savoir plus, j’ai rédigé, (il y a longtemps) un petit howto to simple ici.

Droits des fichiers, droits des démons/services

Un des soucis fréquemment rencontrer, c’est que dans le doute, au moindre message d’erreur, la personne qui installe un site, un blog, un système de E-commerce ou autre Weberies met un bon vieux 777 sur le répertoire et les fichiers. Dans le doute aussi, histoire de pas être embété, mes testeurs ont déjà aussi vu des Apache en root (les workers). Tout cela est mal, très mal même… Donc un bon fichier Web a des droits adaptés : 755 au plus large mais JAMAIS de 777 en production ! N’oubliez pas que tout fichier contenant un mot de passe de connexion à un base de données (config.php par exemple) ne doit pas être lisible de tous (pas 755 donc).

De même les démons, apache en premier lieu (mais aussi potentiellement le serveur FTP et Mysql), doivent être lancé sous un nom d’utilisateur non privilégié, sous débian normalement Apache se lance en www-data comme utilisateur et www-data comme groupe.

Protection Kernel contre les overflows et cage/chroot

Le noyau de votre Linux, par défaut sur la majorité des distributions, est compilé avec le support des modules. Ce n’est pas idéal puisque mettre une backdoor à un noyau modulaire est très simple une fois que l’on est root et c’est assez indétectable. La compilation du noyau en statique est donc préférable et il faut y ajouter le patch GRsec/Pax. Ce patch est certes quelque peu joyeu à paramétrer quand on ne le connait pas, mais il est bourré de qualités ! En premier lieu il rend la pile non exécutable, ce qui complique singulièrement les exploitations par overflows.  Ensuite il améliore beaucoup d’autres points, renforcement des chroots, des logs, cacher les processus noyau, amélioration des pools d’entropie.

Les cages (ou Chroot) sont également un bon moyen de défense contre les overflows, d’autant plus si elles sont couplées à GRsec/PAX pour éviter que l’intru puisse sortir de la cage du démon. Les cages sont des sous répertoires, comprenant tout ce qu’il est nécessaire d’avoir (et rien de plus) pour que le démon/service concerné, puisse s’exécuter. Ainsi, il n’a aucune visibilité sur le reste du système si jamais il se retrouvait compromis par un overflow. Il existe des moyens de contourner ces restrictions mais Pax résout le problème.

Webservices

Je code donc je porte une responsabilité de sécurité chapitre 2 ! Un webservice, par principe, expose une grande partie de son fonctionnement à travers un WSDL (prononcez « wisdel ») qui décrit les types et fonctions associés. Grace à cette mine d’information, par essence publique, il est facile de consulter un webservice que l’on pourrait atteindre et de lui faire donner des informations confidentielles. Afin d’éviter ce type de désagrément, il faut mettre le Webservice à l’abri de requêtes frontales depuis Internet (dans un sous réseau), voir cacher le Wdsl quand cela est possible.

Backoffice, password et bruteforce

Une fois que vous avez pensé à tout, que reste t’il à faire ? Mettre un mot de passe décent sur le backoffice évidemment mais ça, vous l’aviez déjà fait. On évite de se faire bruteforcer au cas ou en mettant un .htaccess, éventuellement qui ne vous embetera pas depuis vos IP à vous, mais vous protégera des petits rigolos qui voudraient bruteforcer votre admin ou encore d’une éventuelle faille sur les URL dans l’admin. Un simple .htaccess contenant :

AuthUserFile /www/wikigento/htpass (bien sur ce n’est pas le bon chemin ;) )
AuthName « Wikigento »
AuthType BasicOrder allow,deny
allow from xxx.xxx.xxx.xxxx
allow from yyy.yyy.yyy.yyy
Require valid-user
Satisfy any

vous permettra de vous connecter depuis les IP xxx.xxx.xxx.xxx ou yyy.yyy.yyy.yyy sans demande de login/pass et depuis n’importe quelle IP en renseignant correctement une demande de login/pass.

Autres principes de sécurité pour vos Webdev

N’oubliez pas, par exemple, que la sécurité de vos applications doit se faire coté serveur et pas coté client. Le client, par principe de sécurité, est à considérer comme compromis. Il est possible assez facilement de jouer avec le Javascript envoyé à un browser avec de addons comme Firebug. Ne faites donc confiance qu’à ce que VOUS maitrisez, le serveur. Gare notamment au modèle de sécurité qui repose sur Javascript ou Ajax, ce sont des technologies « client side » et donc par définition elles ne peuvent en aucun cas garantir une transaction ou l’intégrité d’une procédure.

écrit par Philippe Humeau \\ tags: