Formation PUB010 : PHP, 2018 Sécuriser le code

Protection contre les injections SQL avec les requêtes préparées (anciennes techniques : guillemets magiques et addslashes())


Avez-vous déjà affiché à l'écran les données d'un formulaire Web et constaté que PHP y avait ajouté des barres obliques inverses ? D'où vient ce comportement ? Pourquoi a-t-il été mis en place ? Et comment régler ce problème ?

▼Publicité

Un peu d'histoire : les guillemets magiques

Avant sa version 5.4, PHP offrait un mécanisme permettant de protéger contre certaines injections SQL les valeurs reçues par HTTP (variables $_GET, $_POST et $_COOKIE) : les guillemets magiques (magic quotes). Ainsi, lorsqu'un internaute entrait la valeur « j'arrive » dans un formulaire, les guillemets magiques, s'ils étaient activés, la transformaient automatiquement en « j\'arrive ».

Les guillemets magiques appliquaient automatiquement la fonction addslashes() aux valeurs reçues par HTTP. Une barre oblique inverse était donc automatiquement ajoutée devant :

  • les apostrophes ( ' )
  • les guillemets ( " )
  • les barres obliques inverses ( \ )
  • le caractère NUL

Il était possible d'activer ou non les guillemets magiques à l'aide d'une configuration dans le fichier php.ini : magic_quotes_gpc = On ou Off. Les guillemets magiques étaient donc contrôlés côté serveur. Dans un programme PHP, il était possible de vérifier s'ils étaient activés ou non à l'aide de la fonction get_magic_quotes_gpc().

Aujourd'hui, il n'est plus possible d'utiliser les guillemets magiques. Ils sont donc toujours considérés comme désactivés, comme indiqué clairement dans la documentation sur les guillemets magiques :

Avertissement : Cette fonctionnalité est devenue OBSOLETE depuis PHP 5.3.0 et a été SUPPRIMEE depuis PHP 5.4.0.

Pourquoi PHP a-t-il supprimé les guillemets magiques ? Parce que dans plusieurs cas, les variables $_GET, $_POST et $_COOKIE ne sont pas utilisées dans des requêtes SQL et donc n'ont pas besoin de se voir appliquer un addslashes().

Les guillemets magiques alourdissaient le traitement inutilement et causaient même des problèmes d'affichage : les fameuses barres obligues inverses qui apparaissent dans le texte. De plus, le fait d'échapper les apostrophes et guillemets donnait au programmeur une fausse impression de sécurité car cette technique ne protège que contre certaines injections SQL.

Un exemple d'injection SQL

Voici un exemple du risque encouru lorsque les apostrophes ou guillemets entrées par un usager ne sont pas traités. Soit une requête SQL qui utilise directement la valeur entrée dans le formulaire afin de vérifier si l'usager a fourni les bonnes informations d'authentification :

PHP

$requete = "SELECT nomfamille, prenom FROM usagers WHERE code = '$code' AND motdepasse = '$motdepasse'; 

Dans un formulaire d'authenfication, un usager pourrait entrer comme code d'authentification « 1' OR 1=1 -- ». Ceci peut sembler bizarre mais chacun de ces caractères joue un rôle bien particulier. La requête lancée sur le serveur sera la suivante :

MySQL

SELECT nomfamille, prenom FROM usagers WHERE code = '1' OR 1=1 --' AND motdepasse = '...'; 

L'usager malveillant pourrait donc s'authentifier sur le système sans connaître le mot de passe puisque la condition 1=1 serait toujours évaluée à VRAI et que les caractères -- indiquent que le reste de la requête est un commentaire.

Vous pouvez tester cette technique sur un site de défis de sécurité : https://ringzer0team.com/login

En échappant les apostrophes, la requête deviendrait plutôt :

MySQL

SELECT nomfamille, prenom FROM usagers WHERE code = '1\' OR 1=1 --' AND motdepasse = '...'; 

L'apostrophe ne serait ainsi pas interprétée comme caractère de fin de chaîne et donc l'authentification ne pourrait pas avoir lieu sans les vraies informations d'un usager.

 

Blague sur les injections SQL

Source : http://xkcd.com/327/

Utilisation de requêtes préparées lors de requêtes à la base de données

La présence d'apostrophes dans des informations devant être enregistrées dans la BD (ou utilisée dans tout type de requête SQL) peut ouvrir un trou de sécurité.

Puisque les apostrophes ne sont plus automatiquement échappées et que, de toute façon, l'utilisation de addslashes() ne protège que contre un type précis d'injection SQL :

Il est absolument nécessaire d'utiliser les requêtes préparées afin de sécuriser les requêtes SQL utilisant des informations saisies dans un formulaire, dans un URL ou encore dans un cookie.

Pour plus d'information

« Les magic quotes ou guillemets magiques ». Open Classroom. http://fr.openclassrooms.com/informatique/cours/les-magic-quotes-ou-guillemets-magiques

« Injection SQL ». PHP. http://php.net/manual/fr/security.database.sql-injection.php

« What is SQL Injection? ». Infosec institute. http://resources.infosecinstitute.com/dumping-a-database-using-sql-injection/

« addslashes() vs mysql_real_escape_string()...the final debate ». sitepoint. http://www.sitepoint.com/forums/showthread.php?337881-addslashes()-vs-mysql_real_escape_string()-the-final-debate

« addslashes() Versus mysql_real_escape_string() ». Chris Shiflett. http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string

« SQL injection, myths and fallacies ». Slideshare. http://fr.slideshare.net/billkarwin/sql-injection-myths-and-fallacies

« MySQL SQL Injection Cheat Sheet ». pentestmonkey. http://pentestmonkey.net/cheat-sheet/sql-injection/mysql-sql-injection-cheat-sheet

« SQL Injection ». hakipedia. http://hakipedia.com/index.php/SQL_Injection

« Protéger les données entrant dans la BDD ». Open classrooms. http://fr.openclassrooms.com/informatique/cours/securite-php-securiser-les-flux-de-donnees/proteger-les-donnees-entrant-dans-la-bdd

« Quelques exemples basiques d’attaque sur une application web ». BlogoErgoSum. http://www.blogoergosum.com/16638-quelques-exemples-basiques-dattaque-sur-une-application-web

« Sécurité ». PHP. http://www.php.net/manual/fr/security.php

« RingZer0 Team Online CTF ». RingZer0. https://ringzer0team.com/

« Welcome to the Skull Security Wiki! ». Skull Security. https://wiki.skullsecurity.org/index.php?title=Main_Page

Dernière révision le 26 mars 2018
Merci de partager !

▼Publicité

Site fièrement hébergé chez A2 Hosting

A2 Hosting

Soumettre