ホームページ  >  記事  >  バックエンド開発  >  MySQL への PDO 接続がインジェクションを妨げる理由

MySQL への PDO 接続がインジェクションを妨げる理由

不言
不言オリジナル
2018-05-05 09:29:121727ブラウズ

  $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>

この場合、PHP は単純に SQL ステートメントを mysql サーバーに送信します。これは、mysql_real_escape_string を通常使用して文字列をエスケープし、それを SQL ステートメントに結合するのと何ら変わりません。 PDO ローカル ドライバーによってエスケープされます)、明らかにこの場合でも SQL インジェクションを引き起こす可能性があります。つまり、pdo prepare の mysql_real_escape_string がローカルのシングルバイト文字セットを使用してクエリを操作するために PHP でローカルに呼び出されます。マルチバイトでエンコードされた変数を渡しても、依然として SQL インジェクションの脆弱性が発生する可能性があります (php 5.3.6 より前のバージョンの問題の 1 つであり、PDO を使用する場合に php 5.3.6 以降にアップグレードすることが推奨される理由が説明されています)。 DSN 文字列で文字セットを指定する場合、正しいエスケープは、mysql サーバーの文字セットを指定し、変数を MySQL サーバーに送信して文字エスケープを完了することです。 PDO には PDO::ATTR_EMULATE_PREPARES という名前のパラメータがあり、ローカルで準備をシミュレートするために PHP を使用するかどうかを示します。このパラメータのデフォルト値は不明です。また、先ほどキャプチャしたパケット キャプチャと分析の結果によると、PHP 5.3.6 以降です。デフォルトでは引き続きローカル変数を使用し、それらを SQL に結合して MySQL サーバーに送信します。この値を 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();
今回は、PHP が SQL テンプレートと変数を 2 回で MySQL に送信し、MySQL が完了します。変数のエスケープ処理。変数と SQL テンプレートは 2 回送信されるため、SQL インジェクションの問題はありませんが、

$pdo = などの charset 属性を指定する必要があります。 new PDO('mysql:host=localhost;dbname=test

;charset=utf8

', 'root');

次に、DSN で charset が指定されている場合、次の質問があります。 set names 8dfab5cd353228de2a245e6f3e44b919 を実行する必要がありますか?

はい、set names 8dfab5cd353228de2a245e6f3e44b919 には 2 つの関数があります:

A。クライアント (PHP プログラム) が送信したエンコーディング

B. mysql サーバーに、クライアントが結果に必要なエンコーディングを伝えます

つまり、データテーブルがgbk文字セットを使用し、PHPプログラムがUTF-8エンコーディングを使用する場合、クエリを実行する前にset names utf8を実行して、mysqlサーバーに正しくエンコードするように指示できます。プログラム内でエンコードを変換する必要があります。このようにして、クエリを utf-8 エンコーディングで mysql サーバーに送信し、取得される結果も utf-8 エンコーディングになります。これにより、プログラム内の変換エンコードの問題が解消され、文字化けしたコードが生成されることはありません。

では、DSN で文字セットを指定する役割は何でしょうか? それは、エスケープ時にローカルドライバーが指定された文字セットを使用することを PDO に伝えるだけです (mysql サーバーの通信文字セットは設定しません)。 mysql サーバーを設定します。通信文字セットの場合は、set names 8dfab5cd353228de2a245e6f3e44b919 コマンドも使用する必要があります。

関連する推奨事項:

PDO メソッドに基づく ThinkPHP フレームワーク接続データベース操作例

以上がMySQL への PDO 接続がインジェクションを妨げる理由の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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