Sie sind auf Seite 1von 16

La scurit PHP pour les tout petits

1. Prambule
Ce document est un livre de recettes pour protger une architecture LAMP (Linux, Apache, MySQL,
PHP), mais elle peut aussi aider, pour peu qu'on l'adapte correctement, protger toute architecture Web. La
dmarche ne garantit absolument pas l'inviolabilit, le 100% ne faisant pas partie de ce monde, mais va rendre la
tche du pirate plus complique, et plus longue.

1.1. Pr-requis
Nous supposerons que PHP est install en tant que module dans Apache. Le cas de PHP utilis comme
CGI ne devrait recouvrir que le cas des particuliers chez leur FAI favori. Nous supposerons aussi que le lecteur
est au moins habitu la programmation, mme sans tre un expert. Nous supposerons enfin que les
dveloppeurs web ne sont pas hostiles, tout au plus inconscients.

1.2. But des scripts


Les scripts, PHP par exemple, ont pour but dinteragir avec lutilisateur, ce qui signifie que celui-ci doit
envoyer, dune manire ou dune autre, des donnes qui seront utilises par le programme. Ces donnes seront,
aprs transformation, stockes par le programme, soit dans des fichiers, soit dans des bases de donnes, MySQL
par exemple, pour tre ensuite renvoyes d'une manire ou d'une autre un utilisateur. La difficult va donc
porter sur la protection de l'ensemble de cette chaine en vitant ou limitant les attaques informatiques.

Version du vendredi 1 fvrier 2013 Fabrice Prigent 1/16


2. Linux
Plusieurs choses peuvent tre faites au niveau du Linux pour renforcer la scurit. Parmi les plus
simples, mettre en place le pare-feu pour interdire les connexions extrieures sur autre chose que les ports
spcifiquement ouverts:
iptables A INPUT m state -state RELATED,ESTABLISHED j ACCEPT
iptables A INPUT i lo j ACCEPT
iptables A INPUT p tcp -dport 80 j ACCEPT
iptables A INPUT p tcp -dport 443 j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables A INPUT j LOG
iptables A INPUT j DROP
Reste ensuite interdire aux processus apache et MySQL sortir de la machine : qu'auraient-ils donc
faire l'extrieur (sauf cas du mod_proxy) ?
iptables A OUTPUT o lo j ACCEPT
iptables A OUTPUT m state -state RELATED,ESTABLISHED j ACCEPT
iptables A OUTPUT d mysql.site.fr p tcp -dport 3306 j ACCEPT # Serveur MySQL distant
iptables A OUTPUT d smtp.site.fr p tcp -dport 25 j ACCEPT # Serveur SMTP du site
iptables A OUTPUT d dns.site.fr p udp -dport 53 j ACCEPT # Serveur DNS du site
iptables -A OUTPUT -m owner --uid-owner 48 j LOG # Utilisateur Apache
iptables -A OUTPUT -m owner --uid-owner 27 j LOG # Utilisateur MySQL
iptables -A OUTPUT -m owner --uid-owner 48 j DROP # Utilisateur Apache
iptables -A OUTPUT -m owner --uid-owner 27 j DROP # Utilisateur MySQL
iptables A OUTPUT j ACCEPT
Dans les solutions plus ardues, on trouvera tous les processus de durcissement d'OS, au rang desquels
on trouvera SELinux, GrSecurity, Pax.
Dans les solutions gnrales et assez longues, on se reportera sur les excellents guides de la N.S.A. qui
parle, entre autres, de Linux, Cisco, Windows, etc.

3. Apache

3.1. Le logiciel lui-mme


Plusieurs mthodes existent pour scuriser apache. La premire ide est de le mettre en chroot. Cela
impose de nombreuses contraintes, difficiles respecter en production. Heureusement, la NSA pense nous
grce son SELinux qui permet de contraindre un processus, mme root, dans un environnement scuris. Ceci
est disponible, en particulier dans les RedHat 4.x ou +, Mandrake 10.x ou +, Debian et CentOS 4.x ou +.

3.2. Le paramtrage
Il est important de vrifier quelques paramtres, et de limiter leur action suivant vos utilisateurs (les
options allowOverride sont l pour cela).
<Directory />
AllowOverride None
</Directory>
Dsactivez la signature de l'apache:
ServerSignature Off
ServerTokens Prod
Dsactiver le mode trace
TraceEnable off
Pensez aussi journaliser correctement :
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
CustomLog logs/access_log combined
Evitez les log DNS qui sont une mauvaise ide, car ils prennent du temps pour une information inutile,
voire dangereuse : l'information DNS peut changer entre le problme et sa dtection.
Idem pour les IdentityCheck, hormis cas particulier.
HostnameLookups Off

Version du vendredi 1 fvrier 2013 Fabrice Prigent 2/16


IdentityCheck off
Mettez en place les .htaccess et empchez leur rapatriement.
AccessFileName .htaccess
<Files ~ "^\.ht">
Order allow,deny
Deny from all
</Files>
On peut aussi limiter les requtes en taille et rduire le timeout.
LimitRequestBody 1048576
LimitXMLRequestBody 10485760
Timeout 45
Refusez les indexations automatiques de rpertoires, tous vos fichiers seraient visibles (hormis cas
prcis). Cela peut-tre fait en crant systmatiquement un index.html, mais aussi au niveau du serveur ou des
rpertoires grce la directive.
Options -Indexes

3.3. Les VirtualHosts


Pensez faire des journaux individuels pour chaque virtualhost, ainsi qu'un fichier de configuration par
virtualhost (le rpertoire conf.d est fait pour cela). Choisissez bien leur nom, surtout si vous souhaitez utiliser les
certificats qui vont se baser sur ce nom.
Crer un serveur par dfaut, sans la moindre information.

3.4. L'arborescence

3.4.1.Fichiers rendre inaccessibles


Prvoyez une routine d'effacement de vos fichiers temporaires ou de sauvegarde (*.bak, *.old, *.$$$,
*.tmp, ficher~ ou *.2), ventuellement, vous pouvez aussi les rendre illisibles par le daemon apache.
chown root:root *.bak
chmod 400 *.bak

3.4.2.Rpertoires et fichiers
Il faut aussi faire sortir de l'arborescence, tant que faire se peut, les fichiers qui n'ont pas vocation tre
directement visibles. En particulier tout ce qui concerne les include et les fichiers de donnes.

3.4.3.Le fichier robots.txt


Le fichier /robots.txt doit contenir l'ensemble des rpertoires ne pas laisser explorer par des robots tels
GOOGLEBOT ou autre. Cela pourrait effectivement donner beaucoup trop d'informations aux pirates, en
particulier doivent tre exclus : les rpertoires de statistiques, les rpertoires privs, plus tout rpertoire "pig"
que vous pourriez crer. Exemple d'un tel fichier :
User-agent: *
# Rpertoires standard
Disallow: /cgi-bin
# Quelques fichiers
Disallow: admin.php
Disallow: test.php
# Statistiques
Disallow: /usage/
Disallow: /mrtg/
Disallow: /webalizer/
Disallow: /private/mrtg/
# Rpertoires prives
Disallow: /install_redhat/
Disallow: /noaccess/
Rappel : une rgle est faite pour tre contourne, et les pirates ne s'en priveront pas, le robots.txt n'ayant
qu'une vocation d'indication.

Version du vendredi 1 fvrier 2013 Fabrice Prigent 3/16


Ce fichier peut tre valid grce cet outil http://www.searchengineworld.com/cgi-bin/robotcheck.cgi.
Attention, seul gooblebot l'heure actuelle est capable de prendre en compte des ordres du type
Disallow: *.cgi

3.4.4.Les journaux sont vos amis


Il est important de suivre la vie de vos journaux, et de collecter le plus d'information possible sur votre
serveur. Journaliser, c'est bien, mais il est aussi souhaitable de reprer les anomalies.
On regardera donc avec attention (ou plutt, on fera regarder par un programme) les tentatives tranges,
rptitives. Un bon analyseur de journaux peut souvent (s'il n'est pas lui-mme piratable) donner un bon aperu
de choses "tonnantes". On regardera du ct de webstats, awstats ou autres.

3.5. Les modules de scurit


Afin de renforcer la scurit d'apache, plusieurs modules ont t dvelopps. On trouvera aussi des
routines intressantes en PHP.

3.5.1.Mod_chroot
Mod_chroot qui se trouve sur http://core.segfault.pl/~hobbit/mod_chroot/permet de mettre Apache dans
un chroot, sans avoir copier les innombrables fichiers ncessaires son fonctionnement. Rapide et efficace, il
n'atteint pas, malgr tout, la prcision d'une installation manuelle. De plus, il sera ncessaire de garder l'esprit
que tous les programmes lancs par apache seront cantonns au rpertoire chroot.
SecChrootDir /chroot/apache

3.5.2.Mod_security
Mod_security se trouve sur http://www.modsecurity.org. Il permet de normaliser les urls avant l'envoi
aux divers modules, et surtout de reprer les chanes de caractres, ou plutt les expressions rgulires
dangereuses dans les variables envoyes, ainsi que reprer, dans les pages de retour, les informations qui sont
signes d'une attaque russie. Il est de plus capable de chrooter apache de la mme manire que mod_chroot.
Son emploi est plus adapt un Apache 2.x. Mais sa rputation est telle que dsormais il est intgr
dans quasiment toutes les distributions.
Les signatures sont, quant elles, gres par l'OWASP, qui les met jour rgulirement.
Il suffit alors en gnral de tout activer et de dsactiver les rgles une par une et par virtualhost.
secremovebyid 13789432
Par souci d'explication voici comment se passait anciennement l'installation et sa configuration.
yum install httpd-devel # Installation des libraires de dveloppements apache
cd /usr/local/src
wget http://www.modsecurity.org/download/mod_security-2.5.7.tar.gz
tar zxvf mod_security-2.5.7.tar.gz
cd mod_security-2.5.7/apache2
apxs -cia mod_security.c
ou plus simplement sur une ubuntu/debian
apt-get install libapache2-modsecurity
cd /etc/modsecurity/
cp modsecurity.conf-recommended modsecurity.conf
service apache2 restart
Puis configuration pour une instance donne, ou au global
#
#
# Dfinition du comportement mod_security
#
LoadModule security2_module modules/mod_security2.so

<IfModule !mod_unique_id.c>

Version du vendredi 1 fvrier 2013 Fabrice Prigent 4/16


LoadModule unique_id_module modules/mod_unique_id.so
</IfModule>
<IfModule mod_security2.c>
# This is the ModSecurity Core Rules Set.
Include modsecurity.d/*.conf
Include modsecurity.d/activated_rules/*.conf

SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess Off
SecUploadKeepFiles Off
SecUploadFileLimit 10

SecDebugLog /var/log/httpd/modsec_debug.log
SecDebugLogLevel 0

# Audit log
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus ^5
SecAuditLogType Serial
SecAuditLogParts ABIFHZ
SecAuditLog /var/log/httpd/modsec_audit.log

SecTmpDir /var/lib/mod_security
SecDataDir /var/lib/mod_security

# Tailles maximales : changer suivant les applications


SecRequestBodyLimit 500000
SecRequestBodyInMemoryLimit 500000
SecResponseBodyLimit 2000000

</IfModule>
On pourra trouver sur le site http://www.modsecurity.org/projects/rules/index.html des rgles de filtrage,
qui seront, bien videmment, adapter : on ne scurise pas une application simple comme le logiciel
phpmyadmin.

3.5.3.Suhosin
Ceci est un module pour PHP, qui va en combler les trous les plus flagrants. Il se compose de deux
parties indpendantes : un patch et une extension. On peut le trouver sur http://www.hardened-
php.net/suhosin.127.html.
Le patch va ncessiter de recompiler php (et tous ses modules). L'extension, quant elle, peut s'utiliser
seule sans modification. Mais elle ne donne sa pleine puissance qu'avec le patch.

3.5.4.Mod_evasive
Ce module permet de mettre en liste noire des machines qui tentent de saturer un serveur web, par des
requtes trop rapides. Voici un exemple de configuration pour apache 2.x. A mettre dans le httpd.conf. Une
option supplmentaire permet aussi de lancer une commande systme.
<IfModule mod_evasive20.c>
DOSHashTableSize 3097
DOSPageCount 2
DOSSiteCount 50
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 10
DOSEmailNotify webmaster@site.fr
DOSLogDir "/var/lock/mod_evasive"
DOSWhitelist 127.0.0.1
DOSWhitelist 193.49.*.*
</IfModule>

Version du vendredi 1 fvrier 2013 Fabrice Prigent 5/16


3.6. La scurisation par chiffrement
Saint Graal de la scurit il y a quelques annes, on s'aperoit que le chiffrement n'est pas plus sr que
les entres du "tunnel" qu'il cre. Il s'agit toutefois d'un pr requis pour permettre de faire transiter des donnes
sans risquer l'observation et l'interception des communications.

3.6.1.L'installation du chiffrement
En apache, le chiffrement se fait de manire relativement simple : l'coute se fera sur le port ddi 443.
Le reste dpendra des certificats obtenus, plus quelques options si l'on souhaite rcuprer des variables dans les
certificats (le nom de l'utilisateur en particulier). Nous ne nous attarderons pas ici sur la gnration des
certificats, qui relverait d'un chapitre complet.
Mais on pourra avec profit liminer les chiffrements les moins puissants en travaillent su sslciphersuite
(en particulier ssl v2). On pourra se reporter au site http://www.sslabs.com pour valuer cette robustesse.
<VirtualHost webmail.site.fr:443>
ServerAdmin reseau@site.fr
DocumentRoot /var/www/html_webmail/
ServerName webmail.site.fr
SSLEngine on
SSLCertificateFile /etc/httpd/conf/ssl.crt/webmail.site.fr.crt
SSLCertificateKeyFile /etc/httpd/conf/ssl.key/webmail.site.fr.key
SSLCertificateChainFile /etc/httpd/conf/ssl.crt/cachain.txt
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
SSLOptions +StdEnvVars
</Files>
ErrorDocument 402 https://webmail.site.fr/
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
ErrorLog logs/error_webmail_log
CustomLog logs/access_webmail_log combined
</VirtualHost>

3.6.2.Le choix des algorithmes


Les algorithmes de chiffrement se ngocient au dbut de la session entre serveur et
client. Mais de nombreux critres vont prsider au choix de la CIPHERSUITE
les protocoles casss,
les incompatibles avec des navigateurs parce que trop vieux ou trop rcents,
les insuffisants,
ceux spcialiss en chiffrement symtriques ou assymtriques,
ceux spcialiss en signature (hashage),
les performants mais pas efficaces, etc.
Il est conseill par certains experts (cf https://wiki.mozilla.org/Security/Server_Side_TLS ) de
slectionner la ciphersuite suivante (en mode intermdiaire pour des clients pas trop
vieux).
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-
GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-
SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-
SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-
AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-
SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-
GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!
aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-
SHA:!KRB5-DES-CBC3-SHA
SSLHonorCipherOrder on

Version du vendredi 1 fvrier 2013 Fabrice Prigent 6/16


On pourra avec profit, s'intresser aux outils de tests de validit de
https://www.ssllabs.com (compter 2 minutes compltes de test).

3.6.3.Les contournements du chiffrement


Ils sont nombreux, malgr les apparences, et sont gnralement lis l'utilisateur qui fait trop confiance,
ou trop peu attention ce qu'il voit.

3.6.3.1.Problme du domaine "valide" l'orthographe similaire


Un pirate peut acheter un certificat auprs d'une socit (Verisign par exemple) pour le domaine
bnppariba.com. L'utilisateur recevra un certificat, valide, qu'il acceptera.

3.6.3.2.L'attaque Man in the Middle


Un pirate peut, en se plaant de manire relle ou virtuelle entre la victime et le site scuris, intercepter
les communications. Il va prsenter un pseudo certificat l'utilisateur, qui va l'accepter. Le pirate va
retransmettre les donnes de la session au vrai site en les chiffrant rellement, mais tout sera visible pour lui. De
nombreux outils permettent de faire cela de manire trs simple.

3.7. Les processus d'authentification


Il faut regarder avec attention les processus d'authentification, qui ne doivent en aucun cas tre une
source supplmentaire d'intrusion. Il est par exemple trs dangereux de faire circuler les mots de passe en clair
sur le rseau, ce qui implique le chiffrement des changes d'authentification. Mais cela ne suffit pas : si la
personne croit parler au serveur d'authentification, alors qu'il s'agit d'un pirate (notion de rogue tel que les
rogue AP en WiFi), il faut absolument que la personne le sache, et qu'elle n'ait pas pris l'habitude d'accepter
n'importe quel certificat ! Ce qui signifie utiliser une VRAIE notion de certificat et donc d'IGC (Infrastructure de
Gestion de Cls), aussi appele PKI (Public Key Infrastructure).

3.7.1.Le cookie d'authentification


Aprs une authentification, plus ou moins srieuse, l'ide est souvent de stocker l'authentification dans
un cookie et de l'utiliser dans des applications non chiffres. Le but pour le pirate consiste alors rcuprer le
cookie d'authentification pour le rejouer immdiatement. C'est une action tout faire faisable grce aux attaques
dites XSS (Cross Site Scripting).
A minima, il faudra, pour limiter les consquences de ce vol, stocker dans le cookie, ou dans les
variables de sessions dont il dpend, l'IP d'origine de la session, puis de refuser les connexions qui viennent d'une
autre IP. Cela se passera certainement moins bien si la victime et l'attaquant ont la mme adresse IP extrieure
(NAT, proxy-cache, etc.), ou si l'IP est "changeante" (voir le protocole DHCP).

3.7.2.Le SSO
Acronyme de Single Sign On, il dcrit un mcanisme d'authentification unique permettant l'utilisateur
de ne rentrer qu'une seule fois son mot de passe pour plusieurs applications (souvent web). Cela recouvre
plusieurs techniques bases quasiment toutes sur un serveur d'authentification.
Dans un cas le serveur connait tous les mots de passe et les fournit l'application qui le demande. Ceci
est particulirement dangereux : l'application va tre au courant du login et du mot de passe. Si elle est pirate ou
pirate, ceux-ci vont tre diffuss.
Dans le second, le serveur fournit l'identit du client et confirme son authentification l'application
demandeuse (voir par exemple le projet CAS). L'application ne connait donc pas le mot de passe.

3.7.3.Les fdrations d'identit


Les fdrations d'identit ont pour but de permettre un individu, faisant partie d'un organisme A d'tre
reconnu par un autre organisme B pour accder certains de ses services. B (appel fournisseur de services),

Version du vendredi 1 fvrier 2013 Fabrice Prigent 7/16


lorsque l'individu le contacte, va demander A de confirmer son identit, par exemple grce un SSO. B ne
connatra ni le login, ni le mot de passe de l'individu, mais, parce qu'il fait confiance A, lui accordera des droits.
Deux projets sont en lice :
http://shibboleth.internet2.edu (shibboleth)
http://www.projectliberty.org (liberty alliance)

3.8. Les reverse-proxy

3.8.1.Le mod_proxy
Le mod_proxy va permettre de placer un apache en frontal d'un autre serveur HTTP, de type apache ou
non. Cela va dcharger le serveur protg d'un certain nombre d'actions de scurit (voir le module
mod_security), et ventuellement du chiffrement des communications.
Le serveur frontal n'ayant qu'un rle de relais, on va pouvoir lui faire subir une cure d'amaigrissement,
toujours profitable, et lui restreindre ses possibilits de communications. Il deviendra alors moins vulnrable, et
moins capable d'actions nfastes.
Afin de pouvoir faire du reverse-proxying en toute circonstance, on regardera du cot de mod_ext_filter
pour faire une rcriture des urls, mme dans les javascript.
La configuration d'un reverse-proxy pouvant tre assez longue, nous laisserons le lecteur faire ses
propres recherches.

3.8.2.Un reverse-proxy de scurit : Vulture


Il existe un reverse-proxy de scurit complet qui existe en GPL : il s'agit de Vulture, disponible sur
http://vulture.open-source.fr. Il combine les fonctionnalits de l'ensemble des outils prcdents, puisqu'il les
intgre. Il est aussi capable de faire du SSO.

3.8.3.Un reverse-proxy SSO : LemonLDAP


Lemonldap est un reverse-proxy qui permet de crer un serveur apte grer une authentification unique
pour un ensemble d'applications web. Il est disponible sur http://LemonLDAP.sourceforge.net.

3.8.4.NGINX
Serveur web d'origine russe il est rput pour sa faible empreinte mmoire et CPU, ainsi que pour sa
rapidit. On l'utilise soit en remplacement, soit en reverse-proxy de Apache. http://www.nginx.org. Sa faible
modularit et sa rigidit en font un outil dur, mais terriblement efficace.
Certains le coupleront, profit, avec son module NAXSI qui fait du filtrage positif (on n'autorise que ce
que l'on connait) contrairement mod_security.

4. Paramtrer PHP

4.1. Le safe-mode

4.1.1.But
Le safe-mode est une configuration particulire du module PHP qui permet de limiter les actions
possibles pour le pirate, mais aussi celles du programmeur par la mme occasion. Mais elle n'est plus active
depuis la 5.4.0.

Version du vendredi 1 fvrier 2013 Fabrice Prigent 8/16


4.1.2.Activation
On lactive simplement en mettant dans le php.ini la variable safe_mode on. Suivra ensuite une liste
de variables que lon positionnera suivant les besoins de restriction :
safe_mode
safe_mode_gid
safe_mode_include_dir
safe_mode_exec_dir
safe_mode_allowed_env_vars
safe_mode_protected_env_vars
Le fonctionnement par dfaut de safe-mode sera le suivant :
Le script ne peut lire que les fichiers qui appartiennent au propritaire du processus php (on peut limiter
ce fait grce safe_mode_gid) ou ceux qui sont dans les rpertoires donns par safe_mode_include_dir
Le script ne peut excuter que les commandes qui se trouvent dans safe_mode_exec_dir (attention bien
les terminer par /)
Un certain nombre de fonctions seront limites, en gnral par une vrification du propritaire, et du
rpertoire dexcution
Un certain nombre de fonctions seront indisponibles (dl, shell_exec,set_limit_time,max_execution_time)
La fonction mail ne peut modifier le 5me paramtre (paramtres additionnels).
Des variables ne seront plus accessibles :
Les variables PHP_AUTH_USER (mais REMOTE_USER, oui) et PHP_AUTH_PW
Les en-tte commenant par AUTHORIZATION
safe_mode on

4.2. Les autres paramtrages


Dautres variables permettent de limiter encore les droits des scripts PHP.

4.2.1.open_basedir
Permet de limiter louverture des fichiers un rpertoire donn. Attention bien le terminer par /. Ceci
est plus ou moins redondant avec le safe_mode.

4.2.2.disable_functions
On peut dsactiver des fonctions. Est-il indispensable de laisser les commandes system et readfile
actives ?
disable_functions readfile,system

4.2.3.disable_classes
Idem, mais avec les classes.

4.2.4.register_globals
Permet dviter que des variables internes aux scripts ne soient directement affectes dune valeur
par lutilisateur distant. Facilit offerte par PHP ses dbut, elle est devenue la principale cause de failles des
scripts PHP pendant une longue priode. Dsormais, depuis la version 4.2.0, elle est OFF par dfaut. Ce
changement a occasionn le mauvais fonctionnement de plusieurs milliers de scripts dans le monde.
register_globals off
Ce nouveau comportement implique que les variables seront dsormais rcupres par les tableaux
$_GET
$_POST
$_COOKIE
$_REQUEST (quivalent aux 3 premiers)

Version du vendredi 1 fvrier 2013 Fabrice Prigent 9/16


$_FILES
$_SESSION
et $_SERVER
ainsi la variable $login devra tre rcupre par $login=$_GET['login']

4.2.5.Limiter les informations pour le pirate


On empche l'affichage d'informations trop prcises sur la version de php, les erreurs qui ne doivent pas
s'afficher dans le navigateur mais dans les logs.
expose_php off
display_errors off
error_log syslog

4.2.6.magic_quotes_gpc
Les variables peuvent tre utilises pour bloquer ou modifier le systme. magic_quotes_gpc est un
moyen efficace de protger le systme (particulirement les accs aux bases de donnes) dun comportement
imprvu. Magic_quotes_gpc va ainsi protger le systme des caractres NULL, \, quotes et guillemet " .
magic_quotes_gpc on
L'inconvnient de cette mthode est qu'elle alourdit les scripts, et rend toutes les variables sous forme
protg. Il faut alors, lors de l'affichage, toutes les dprotger par la fonction strip_slashes(). On peut ,
parfois, remplacer ce procd trs "dgt collatral" par une utilisation judicieuse de la fonction
add_slashes(). Il est d'ailleurs fortement question de remettre le magic_quotes_gpc off dans les futures
versions de PHP.

4.2.7.Paramtres de limitation divers


Afin de limiter les dgts d'un dni de service (D.O.S.) on peut mettre des contraintes sur les ressources.
En voici quelques unes :
max_execution_time = 30 ; Temps maximum d'xecution en secondes
memory_limit = 8M ; taille mmoire maximale par script

4.2.8.Les modules de protection


Quelques modules daide au filtrage des variables ont t dvelopps pour PHP, on pourra se reporter en
particulier http://www.phpclasses.org/browse/class/78.html qui les recense. En voici un.

4.2.8.1.HTMLPURIFIER
Il s'agit d'une classe php qui va vrifier la conformit de la page et la nettoyer de tout XSS qui pourrait
tre prsent avant son affichage. Elle est disponible sur http://htmlpurifier.org/ et son utilisation est relativement
simple.

4.2.8.2.INPUTFILTER
Cest un ensemble de classes php, disponible ici, http://cyberai.com/inputfilter/ et qui permet de filtrer
les URLs et les variables des codes javascript, SQL injection ou autres.

4.2.8.3.PHP-IDS
Disponible sur http://php-ids.org, il permet de dtecter des utilisations potentiellement dangereuses en
donnant une valeur d'impact (de dangerosit). L'intgration dans le code source est relativement simple :
set_include_path(
get_include_path()
. PATH_SEPARATOR
. 'chemin/vers/la/bibliotheque/phpids'
);

Version du vendredi 1 fvrier 2013 Fabrice Prigent 10/16


require_once 'IDS/Init.php';
$request = array('GET' => $_GET, 'POST' => $_POST, 'COOKIE' => $_COOKIE);
$init = IDS_Init::init('IDS/Config/Config.ini');
$ids = new IDS_Monitor($request, $init);
$result = $ids->run();

if (!$result->isEmpty()) {
// On regarde le rsultat
echo $result;
}

4.2.9.La version 5.4.0 de PHP


Elle modifie grandement le fonctionnement scuritaire de PHP. Voici quelques informations disponibles
au moment de la rdaction de ce vade mecum:
Suppression des register globals
Suppression des magicquotes
Suppression du safe_mode
Suppression des super-globales $HTTP_*_VARS

4.2.10.Les frameworks de dveloppements


Ils permettent, pour les plus srieux, de grer une part importante des processus de scurit :
gestion des tokens POST contre les CSRF
protection contre certains XSS
vrification des injections SQL (ou LDAP)
dplacement des rpertoires hors du rpertoire WWW
On y trouvera
cakePHP
symfony-project

5. MySQL

5.1. Installer MySQL


MySQL peut trs facilement se placer en chroot, afin de limiter ses actions en cas d'intrusion :
mkdir -p /chrooted/chrooted-mysqld
cd /chrooted/chrooted-mysqld/
mkdir -p var/lib var/run lib etc tmp
grep "mysql:" /etc/passwd >etc/passwd
chmod 1777 tmp
cp -rp /var/lib/mysql var/lib/
cp -rp /var/run/mysqld var/run
ldd /usr/libexec/mysqld
#Crer les rpertoires reprs
#copier les fichiers reprs dans les rpertoires
mkdir -p lib/i686 usr/lib
cp -rp /lib/..
cp -rp /lib/libnss* lib/
# ajouter dans /etc/my.cnf
chroot=/chrooted/chrooted-mysqld

5.2. Configurer MySQL


MySQL est le support de beaucoup d'applications web. Les questions qui se posent :

Version du vendredi 1 fvrier 2013 Fabrice Prigent 11/16


Le MySQL doit-il tre accessible hors de la machine qui l'hberge ? Non 90%, donc on n'attache le
processus qu' l'interface localhost, ou, au pire, on utilise les iptables, ou tout autre procd de pare-feu local
pour limiter l'accs aux seules machines autorises.
Est-il normal que l'accs administrateur se fasse sans mot de passe ou avec un mot de passe par dfaut ?
Mettez en un nouveau. On peut utiliser pour cela la commande mysql_secure_installation, qui vous permettra
d'enlever les bases et les comptes inutiles.
Dsactiver les fonctions trop dangereuses en ajoutant dans /etc/my.cnf
set-variable=local-infile=0

5.3. Utiliser MySQL


Lors de la cration de compte MySQL, sparez les comptes suivants les applications. Profitez-en pour
ne donnez que les droits ncessaires, et en les divisant :
un compte d'administration (cration des tables),
un compte en criture
un compte en lecture.

5.4. Piger MySQL


Crer des donnes "honeytokens" afin de faciliter le reprage de vol de donnes (pour un I.D.S. ou pour
des preuves devant un tribunal). Cela peut-tre un compte, un enregistrement, etc.

6. Programmer en PHP
Une fois que lon a pris en compte lenvironnement de travail, mis en place les protections ncessaires
sur les scripts PHP et autres fichiers de configuration, un grand nombre de choses restent regarder.

6.1. Bien programmer


Cela semble vident, mais certains rflexes soublient en programmation web. Les principes doivent
tre les suivants :
Une variable doit toujours tre affecte.
Vrifiez toujours le rsultat des actions que vous effectuez
La connexion la base s'est-elle bien passe ?
Y a-t-il un rsultat dans votre requte ?
La valeur est-elle dfinie ?

6.2. Contrler les variables


La grande majorit des failles actuelles proviennent des variables qui nous sont fournies par lutilisateur.
Nous avons dj, grce register_globals, limiter le problme aux vraies variables quest sens nous
envoyer lutilisateur. Mais cela ne suffit pas. Le contenu des variables peut tre dangereux. Voici quelques
mthodes pour vrifier les variables.
Utilisez le moins possible les variables directement.
Si une variable $variable est sense tre numrique, confirmez le :
$variable=intval($variable);
Si une variable ne doit pas dpasser une certaine taille, en minuscule, confirmez le :
$login = preg_replace(".*([a-z]{3,8}).*", "\$1", $login);
Si une variable est sense avoir un format particulier, vrifiez le grce aux expressions rgulires :
if (preg_match('/^[A-Z0-9._%-]+@[A-Z0-9._%-]+\.[A-Z]{2,6}$/', $email))
{suite_du_traitement();}
else
{die "erreur dans la variable email\n";}; // Remarquez que l'on n'utilise pas la
valeur de $email.
Dans le cas de variables numratives, qui ne peuvent prendre leurs valeurs que dans un intervalle, on
utilise soit les "elseif", soit un tableau intermdiaire :

Version du vendredi 1 fvrier 2013 Fabrice Prigent 12/16


$valeur=$_GET['valeur'];
if ($tab_valeurs_autorisees[$valeur])
{$valeur=$tab_valeurs_autorisees[$valeur]);}
else
{die "valeur est incorrecte"}
Tente-t-on d'utiliser la variable pour envoyer du javascript ? Il faut enlever les caractres "<" et ">";
Vous utilisez une variable qui contient nom de fichier, ou dont on drive un nom de fichier, rpertoire,
ou commande ? Effacez les .. / ; * et autre ?
Une base de donnes est implique ? Attention aux squences dangereuses
-- ou # (qui sont des commentaires)
; (qui est un sparateur de commande)
l'espace (trs utilis si vous n'avez pas "quot" la variable)
les mots cls SQL (UNION tant le plus pris).

6.3. Les piges viter

6.3.1.Le stockage des mots de passe


Doit-on stocker les mots de passe en clair ? A 99% c'est non, car on ne veut que comparer un mot de
passe, pas le lire. Il faut utiliser les commandes de hashage telles que MD5, crypt, et autre SHA1, SHA2 ou
SHA3 et ne stocker que le hach d'un mot de passe dans les bases de donnes.
De plus, le hash doit inclure un partie sel pour viter le phnomne des rainbow tables .
Le sel doit tre diffrent pour chaque utilisateur, sinon toute personne pouvant crer un compte va
pouvoir deviner le sel, puis reconstituer une rainbow table : Une Radeon 7970 est capable de faire 400 millions
de SHA256 la seconde.

6.3.2.L'emplacement des fichiers de donnes


Les fichiers de donnes doivent-ils tre dans un rpertoire accessible par le web ? 99% non, donc
dplacez les (dans la limite des processus de confinement de votre serveur).

6.3.3.Le signalement des erreurs


La tentation, si lon fait des tests de variables est de signaler exactement le problme lutilisateur.
Erreur ! ! ! Le programme doit stopper le traitement, proprement, mais sans rutiliser la variable. Un pirate
pourrait utiliser cette protection pour entrer dans le systme. Un comble !

6.4. Contre les XSS : htmlentities()


Pour se protger des XSS, une ide simple est d'encoder les caractres particuliers en leur quivalent
web. Cela empche leur interprtation par les navigateurs.

6.5. Contre le SQL-Injection: mysql_real_escape_string()


Afin d'viter l'excution de champs variables, il peut tre utile "d'chapper", c'est dire rendre
inoffensifs, les caractres dangereux pour MySQL. C'est le rle de cette commande, qui doit tre prfre sa
petite soeur mysql_escape_string(). Pour tre utilise, une connexion la base doit avoir t faite. Une version
postgresql existe.
$link=mysql_connect('mysql_host','mysql_user','mysql_password') or die(mysql_error());
$query=sprintf("SELECT * FROM users WHERE users='%s'",mysql_real_escape_string($user));
mysql_query($query);

6.6. Utilisation des prepare/execute


Pour la mme raison, on peut aussi utiliser les commandes paramtres, qui ont de plus l'avantage
d'acclrer les traitements :
require_once("DB.php");

Version du vendredi 1 fvrier 2013 Fabrice Prigent 13/16


$db = &DB::connect("mysql://user:pass@host/database1");
$p = $db->prepare("SELECT * FROM users WHERE username = ?");
$db->execute( $p, array($_GET['username']) );
et
$db->query( "SELECT * FROM users WHERE username = ?", array($_GET['username']) );
ou encore, avec l'extension mysqli (php5).
$db = new mysqli("localhost", "user", "pass", "database");
$stmt = $db -> prepare("SELECT priv FROM testUsers WHERE username=? AND password=?");
$stmt -> bind_param("ss", $user, $pass);
$stmt -> execute();

7. Les expressions rgulires


Avant toute chose : http://www.commitstrip.com/fr/page/10/
Les expressions rgulires sont un formidable moyen de contrle des donnes. Elles travaillent sur la
notion de schma suite de caractres, et non de chiffres ou de mots.
Il existe, pour simplifier, deux types d'expressions rgulires : les posix et les expressions perl. Celles-
ci, plus compltes et puissantes sont de plus en plus utilises. En php on vrifiera la prsence d'une chaine grce
la fonction preg_match. Nous ne voyons ici qu'une toute petite partie des expressions rgulires.

7.1. Les caractres


Un caractre reprsente gnralement son propre caractre a reprsente la lettre a.
[a-z] reprsente tout caractre entre a et z
[B-E] reprsente tout caractre entre B et E
[0-9] reprsente tout caractre entre 0 et 9
. (le point) reprsente n'importe quel caractre

7.2. Les oprateurs


Les oprateurs permettent de prciser le nombre de fois o un caractre apparat ou bien de faire des
oprations de concatnation ou de choix
AB reprsente la squence des caractres A et B
A* reprsente n'importe quelle chaine de caractres contenant des A (de 0 autant que l'on veut)
A+ reprsente n'importe quelle chaine ayant au moins un A
A? reprsente le fait d'avoir zro ou un A.
A{3} signifie trois A de suite
A{2,5} signifie que l'on peut avoir de deux cinq A.
A|B signifie que l'on peut avoir A ou B

7.3. Les autres lments


^ reprsente le dbut de la chaine de caractres
$ reprsente la fin de la chaine de caractres
( ) les parenthses permettent d'appliquer un oprateur un ensemble de caractres.
\ permet de faire perdre un oprateur ou un caractre son "caractre" spcial. \. reprsente le
caractre point.

Version du vendredi 1 fvrier 2013 Fabrice Prigent 14/16


7.4. Les commutateurs
Certaines options dans la slection permettent de prciser les traitements lors de la recherche
i pour ne pas faire de distinction entre majuscule et minuscule
o pour ne "compiler" la rgle de dtection qu'une fois (ce qui est plus rapide)

7.5. Quelques exemples


If preg_match("/Fabrice/",$chaine)
le prnom Fabrice est-il prsent dans $chaine (fabrice ne sera par repr car le f n'est pas majuscule)
If preg_match("/h(ab)*/i",$chaine)
Toute chaine compose de h suivi de 0 x fois de ab sera repre. Les lettres pouvant tre en minuscule
ou en majuscule.
If preg_match("/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/",$chaine)
Toute chaine de caractre contenant une adresse IP (ou du moins qui y ressemble).
If preg_match("/[0-9]{1,4}((bis)|(ter))?/",$chaine)
Toute chaine qui contient un numro de rue (avec ventuellement le bis ou le ter)
If preg_match("/^[0-9]{5}$/",$chaine)
La chaine est gale un code postal (ni plus ni moins).

8. Les outils de tests

8.1. Les tests externes


Ils se comportent comme les pirates en essayant d'obtenir des informations en tant sans droits
particuliers.

8.1.1.Nmap
Grand classique. Il permet de reprer les ports ouverts, la version du logiciel qui tourne (en se basant sur
les bannires). Il est disponible sur http://insecure.org

8.1.2.Wapiti
Scanneur de vulnrabilits inconnues, principalement pour XSS. Il est disponible sur
http://wapiti.sourceforge.net/.

8.1.3.Autres outils
NIKTO http://www.cirt.net/code/nikto.shtml (vulnrabilits web connues)
Nessus http://www.nessus.org (vulnrabilits connues)
Springenwerk http://www.springenwerk.org (failles XSS)
skipfish http://www.googlecode.com/skipfish (scanner exhaustif )
sqlmap http://sqlmap.sourceforge.net/ (SQL injection)

8.2. Les tests internes


Ce sont les valideurs de code. Ils essaient de reprer dans les codes sources les fonctions et mthodes de
programmation dangereuses.

Version du vendredi 1 fvrier 2013 Fabrice Prigent 15/16


8.2.1.PHPsecAudit
Il est disponible sur http://developer.spikesource.com/projects/phpsecaudit

8.2.2.Pixy

Auditeur de code PHP en java pour faille SQL et XSS http://pixybox.seclab.tuwien.ac.at/pixy/

8.2.3.RATS
http://www.securesoftware.com/resources/download_rats.html

9. URLographie
Voici quelques URLs sur la bonne protection des scripts en PHP
http://fr2.php.net/features.safe-mode
http://fr2.php.net/manual/fr/security.php
http://phpsec.org/
http://www.phpsecure.info/
http://shiflett.org/php-security.pdf
http://regexlib.com/
http://www.owasp.org/
http://www.securityfocus.com/infocus/1694
http://dev.mysql.com/doc/mysql/en/Security.html
http://www.securityfocus.com/infocus/1726
http://www.kitebird.com/articles/ins-sec.html
http://www.certa.ssi.gouv.fr/site/CERTA-2007-INF-002.pdf
http://www.certa.ssi.gouv.fr/site/CERTA-2004-INF-001/index.html
http://www.apachesecurity.net/ (horse book de chez O'Reilly)
http://en.wikibooks.org/wiki/Programming:PHP:SQL_Injection

10.Autres informations
Ce document est largement perfectible. n'hsitez pas me signaler les erreurs et les amliorations
l'adresse fabrice.prigent@laposte.net.
Il est disponible sous licence creative commons http://creativecommons.org/licenses/by-nc-sa/2.0/fr/

Version du vendredi 1 fvrier 2013 Fabrice Prigent 16/16

Das könnte Ihnen auch gefallen