Le contenu de cet article est une introduction à la méthode de blocage complet des attaques par injection SQL en PHP. Il a une certaine valeur de référence. J'espère que cela sera utile. vous avez aidé.
Il peut y avoir de nombreux types de motivations d'attaque, mais à première vue, il semble qu'il y en ait plus. Cela est très vrai si un utilisateur malveillant trouve un moyen d'effectuer plusieurs requêtes.
Si votre script exécute une instruction SELECT, alors l'attaquant peut forcer l'affichage de chaque ligne d'enregistrements dans une table - en injectant une condition telle que "1=1" dans la clause WHERE, comme indiqué ci-dessous (avec la partie injectée en gras) :
SELECT * FROM wines WHERE variety = 'lagrein' OR 1=1;'
Comme nous l'avons commenté plus tôt, cela peut être une information utile en soi, car elle révèle la structure générale du tableau (c'est quelque chose qu'un enregistrement normal ne peut pas accomplir ), et semble potentiellement contenir des enregistrements contenant des informations secrètes.
Une commande de mise à jour constitue potentiellement une menace plus directe. En plaçant d'autres caractéristiques dans la clause SET, un attaquant peut modifier n'importe quel champ de l'enregistrement en cours de mise à jour, comme dans l'exemple suivant (dans lequel la partie injectée est affichée en gras) :
UPDATE wines SET type='red','vintage'='9999' WHERE variety = 'lagrein'
Par en ajoutant une condition vraie telle que 1=1 à la clause WHERE d'une instruction de mise à jour, cette plage de modification peut être étendue à chaque enregistrement, comme dans l'exemple suivant (où la partie injectée est affichée en gras) :
UPDATE wines SET type='red','vintage'='9999 WHERE variety = 'lagrein' OR 1=1;'
La commande la plus dangereuse est peut-être DELETE - ce n'est pas difficile à imaginer. La technique d'injection est la même que ce que nous avons déjà vu - en modifiant la clause WHERE pour élargir la gamme des enregistrements concernés, comme dans l'exemple suivant (où la partie injectée est affichée en gras) :
DELETE FROM wines WHERE variety = 'lagrein' OR 1=1;'
Injections de requêtes multiples
Les injections de requêtes multiples augmenteront les dommages potentiels qu'un attaquant peut causer - en permettant d'inclure plusieurs instructions destructrices dans une seule requête. Lors de l'utilisation d'une base de données MySQL, un attaquant peut facilement y parvenir en insérant un caractère d'arrêt inattendu dans la requête - désormais un guillemet injecté (simple ou double) marque la fin de la variable souhaitée. Terminez ensuite la commande par un point-virgule. Désormais, une commande d'attaque supplémentaire peut être ajoutée à la fin de la commande d'origine désormais arrêtée. La requête destructrice finale pourrait ressembler à ceci :
SELECT FROM wines WHERE variety = 'lagrein';GRANT ALL ON .* TO 'BadGuy@%' IDENTIFIED BY 'gotcha';'
Cette injection créera un nouvel utilisateur BadGuy et lui donnera des privilèges réseau (tous les privilèges sur toutes les tables en plus, un mot de passe "inquiétant" est ajouté à) ; cette simple phrase SELECT. Si vous avez suivi nos conseils dans l'article précédent et restreint sévèrement les privilèges de l'utilisateur du processus, alors cela ne devrait pas fonctionner car le démon du serveur web ne dispose plus des privilèges GRANT que vous avez révoqués. Mais en théorie, une telle attaque pourrait donner carte blanche à BadGuy pour faire ce qu’il veut avec votre base de données.
Quant à savoir si une telle requête multi-requête sera traitée par le serveur MySQL, la conclusion n'est pas unique. Certaines des raisons peuvent être dues à différentes versions de MySQL, mais la plupart sont dues à la manière dont plusieurs requêtes existent. Le programme de surveillance de MySQL permet pleinement une telle requête. L'interface graphique MySQL-phpMyAdmin couramment utilisée copiera tout le contenu précédent avant la requête finale, et ne fera que cela.
Cependant, la plupart des requêtes multiples dans un contexte d'injection sont gérées par l'extension mysql de PHP. Heureusement, par défaut, il ne permet pas d'exécuter plusieurs instructions dans une requête ; tenter d'exécuter deux instructions (comme l'injection illustrée ci-dessus) provoquera simplement un échec - aucune erreur n'est définie et aucune information n'est générée en sortie. Dans ce cas, bien que PHP n'implémente son comportement par défaut que "régulièrement", il peut en effet vous protéger de la plupart des attaques par injection simples.
La nouvelle extension mysqli en PHP5 (voir http://php.net/mysqli), comme mysql, ne prend pas automatiquement en charge plusieurs requêtes, mais elle fournit une fonction mysqli_multi_query() pour vous aider à effectuer plusieurs requêtes - si tu veux vraiment le faire.
Cependant, la situation avec SQLite - le moteur de base de données SQL intégrable fourni avec PHP5 (voir http://sqlite.org/ et http://php.net/sqlite) est encore plus désastreuse en raison de sa facilité d'utilisation. L'application a attiré l'attention de nombreux utilisateurs. Dans certains cas, SQLite autorise par défaut de telles requêtes multi-instructions car la base de données peut optimiser les requêtes par lots, en particulier le traitement des instructions INSERT par lots, qui est très efficace.
Cependant, si les résultats de la requête sont utilisés par votre script (par exemple, lors de l'utilisation d'une phrase SELECT pour récupérer des enregistrements), la fonction sqlite_query() ne permet pas l'exécution de plusieurs requêtes.
3. Vulnérabilité d'injection SQL INVISION Power BOARD
Invision Power Board est un système de forum bien connu. Le 6 mai 2005, une vulnérabilité d'injection SQL a été découverte dans le code de connexion. Il a été découvert par James Bercegay de GulfTech Security Research.
Cette requête de connexion ressemble à ceci :
$DB->query("SELECT * FROM ibf_members WHERE id=$mid AND password='$pid'");
La variable d'ID de membre $mid et la variable d'ID de mot de passe $pid sont récupérées à partir de la fonction my_cookie() à l'aide des deux lignes de code suivantes :
$mid = intval($std->my_getcookie('member_id'));$pid = $std->my_getcookie('pass_hash');
Ici, la fonction my_cookie() récupère les variables demandées du cookie à l'aide de la phrase suivante :
return urldecode($_cookie[$ibforums->vars['cookie_id'].$name]);
【留意】从该cookie回来的值底子没有被处理。虽然$mid在运用于查询之前被强制转换成一个整数,可是$pid却保持不变。因而,它很容易遭受咱们前面所评论的注入类型的进犯。
因而,经过以如下方法修正my_cookie()函数,这种软弱性就会露出出来:
if ( ! in_array( $name,array('topicsread', 'forum_read','collapseprefs') ) ) { return $this-> clean_value(urldecode($_cookie[$ibforums->vars['cookie_id'].$name])); } else { return urldecode($_cookie[$ibforums->vars['cookie_id'].$name]); }
经过这样的改正之后,其间的要害变量在"经过"全局clean_value()函数后被回来,而其它变量却未进行检查。
现在,已然咱们大致了解了什么是SQL注入,它的注入原理以及这种注入的软弱程度,那么接下来,让咱们探讨如何有用地防备它。幸亏,PHP为咱们供给了丰厚的资源,因而咱们有充沛的信心预言,一个经细心地彻底地运用咱们所引荐的技能构建的应用程序将会从你的脚本中底子上消除任何或许性的SQL注入-经过在它或许形成任何损坏之前"整理"你的用户的数据来完成。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!