Maison  >  Article  >  développement back-end  >  Pourquoi la connexion PDO à MySQL peut empêcher l'injection

Pourquoi la connexion PDO à MySQL peut empêcher l'injection

不言
不言original
2018-05-05 09:29:121727parcourir

  $stmt = $pdo->prepare('select * from user where id=?');
    $id = 1;
    $stmt->bindParam(1,$id);
    $stmt - >execute();

<span style="font-size:14px;" data-filtered="filtered"></span>

Dans ce cas, PHP envoie simplement l'instruction sql au serveur mysql, C'est ce n'est pas différent de la façon dont nous utilisons habituellement mysql_real_escape_string pour échapper la chaîne, puis la fusionner dans une instruction SQL (elle est simplement échappée par le pilote local PDO. Évidemment, dans ce cas, il est toujours possible de provoquer une injection SQL, c'est-à-dire). disons, en PHP, l'appel local de mysql_real_escape_string dans pdo pour préparer l'exécution de la requête utilise le jeu de caractères local à un octet, et lorsque nous transmettons des variables codées sur plusieurs octets, cela peut toujours provoquer des vulnérabilités d'injection SQL (l'un des problèmes des versions antérieures à PHP 5.3 .6 Tout d'abord, cela explique pourquoi lors de l'utilisation de PDO, il est recommandé de mettre à niveau vers php 5.3.6+ et de spécifier le jeu de caractères dans la chaîne DSN

qui est correct. l'échappement doit consister à spécifier le jeu de caractères pour le serveur mysql et à envoyer la variable au serveur MySQL pour compléter l'échappement des caractères

alors, comment. interdire l'échappement local PHP et laisser le serveur MySQL s'échapper ?

PDO a un paramètre nommé PDO::ATTR_EMULATE_PREPARES, qui indique s'il faut utiliser la préparation de la simulation locale PHP. inconnu. Et selon les résultats de l'analyse de capture de paquets que nous venons de faire, PHP 5.3.6+ utilise toujours des variables locales pour les convertir et les assembler en SQL et les envoyer au serveur MySQL. Nous définissons cette valeur sur false,

.
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);$stmt = $pdo->prepare(&#39;select * from user where id=?&#39;);
$id = 1;
$stmt->bindParam(1,$id);
$stmt - >execute();

Cette fois, PHP envoie le modèle SQL et les variables à MySQL en deux fois, et MySQL termine l'échappement des variables puisque les variables et le modèle SQL sont envoyés en deux fois, alors il n'y a pas de SQL. problème d'injection, mais l'attribut charset doit être spécifié dans le DSN, tel que :

$pdo = new PDO('mysql:host=localhost;dbname=test ; charset=utf8', 'root');

Eh bien, il y a un problème, si dans DSN Si le jeu de caractères est spécifié, dois-je toujours exécuter les noms de set 797dbf6fd39d3ec8a8adf3927ea6e605 >A. Dites au serveur mysql quel encodage le client (programme PHP) lui a soumis

B. Dites au serveur mysql quel est l'encodage du résultat requis par le client

En d'autres termes, si la table de données utilise le jeu de caractères gbk et que le programme PHP utilise l'encodage UTF-8, nous exécutons set names utf8 avant d'exécuter la requête et disons au serveur mysql de l'encoder correctement. Il n'est pas nécessaire de convertir l'encodage dans le programme. De cette façon, nous soumettons la requête au serveur mysql en codage utf-8, et les résultats obtenus seront également en codage utf-8. Cela élimine le problème de l'encodage de conversion dans le programme. N'ayez aucun doute. Cela ne produira pas de code tronqué.

Alors, quelle est la fonction de spécifier un jeu de caractères dans DSN ? Il indique simplement à PDO que lorsque le pilote local ? escapes Pour utiliser le jeu de caractères spécifié (et non pour définir le jeu de caractères de communication du serveur MySQL), pour définir le jeu de caractères de communication du serveur MySQL, vous devez également utiliser la commande set names 8dfab5cd353228de2a245e6f3e44b919

Recommandations associées :

Cadre ThinkPHP basé sur un exemple de fonctionnement d'une base de données de connexion en mode PDO

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn