ホームページ  >  記事  >  データベース  >  SQL インジェクションを防ぐ PDO のメカニズム

SQL インジェクションを防ぐ PDO のメカニズム

黄舟
黄舟オリジナル
2017-02-25 10:28:251439ブラウズ

PDO を使用して MySQL データベースにアクセスする場合、デフォルトでは実際のプリペアド ステートメントは使用されません。この問題を解決するには、準備されたステートメントのエミュレーション効果を無効にする必要があります。 PDO を使用してリンクを作成する例を次に示します:

コードは次のとおりです:

$dbh = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);


setAttribute() この行は必須であり、プリペアド ステートメントのエミュレーションを無効にし、実際のペアペア ステートメントを使用するように PDO に指示します。これにより、SQL ステートメントと対応する値が mysql サーバーに渡される前に PHP によって解析されなくなります (考えられるすべての悪意のある SQL インジェクション攻撃を無効にします)。構成ファイルで文字セット属性 (charset=utf8) を設定できますが、古いバージョンの PHP (

完全なコードの使用例を見てみましょう:

コードは次のとおりです:

$dbh = new PDO("mysql:host=localhost; dbname=dbtest", "user", "pass");
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); //禁用prepared statements的仿真效果
$dbh->exec("set names 'utf8'");
$sql="select * from test where name = ? and password = ?";
$stmt = $dbh->prepare($sql);
$exeres = $stmt->execute(array($testname, $pass));
if ($exeres) {
 while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
     print_r($row);
 }
}
$dbh = null;


上記のコードは SQL インジェクションを防ぐことができます。なぜ?

prepare() が呼び出されるとき、クエリ ステートメントはデータベース サーバーに送信されます。この時点では、execute() が呼び出されるとき、ユーザーによって送信されるデータはありません。と呼ばれる、ユーザーによって送信されたデータはデータベースに送信され、それらは別々に送信され、2 つは独立しており、SQL 攻撃者には攻撃の余地がありません。

しかし、次のような状況には注意する必要があります。PDO は SQL インジェクションを防ぐことができません

1。次のような値のセットを置き換えることはできません。コードは次のとおりです。

SELECT * FROM blog WHERE userid IN ( ? );

2. プレースホルダーでデータ テーブル名や列名を置き換えることはできません。

コードは次のとおりです。

SELECT * FROM blog ORDER BY ?;

3. プレースホルダーで他の SQL 構文を置き換えることはできません。 、例:

コードは次のとおりです:

SELECT EXTRACT( ? FROM datetime_column) AS variable_datetime_element FROM blog;

上記は、SQL インジェクションを防ぐための PDO のメカニズムの内容です。さらに関連する内容については、PHP 中国語 Web サイト (www.php.cn) に注意してください。 !



声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。