8

重複の可能性:
プリペアド ステートメントは SQL インジェクション攻撃からどのように保護できますか?

PDO を初めて使用する私たちにとっては、PDO の方が安全で使いやすいことがわかりますが、頭を悩ませることができないのは、これはどのように保護されているのでしょうか?

<?php
$db = new PDO('mysql:host=localhost;dbname=testdb;charset=UTF-8', 'username', 'password');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
try {
    //connect as appropriate as above
    $db->query('hi'); //invalid query!
} catch(PDOException $ex) {
    echo "An Error occured!"; //user friendly message
    some_logging_function($ex->getMessage());
}
foreach($db->query('SELECT * FROM table') as $row) {
    echo $row['field1'].' '.$row['field2']; //etc...
}
?>

念のために言っておきますが、それが何をするのかは理解していますが、入力をサニタイズするために正確に何をしているのでしょうか? リテラルを入れるだけのmysql_*使い方を知っています。PDO はこれと同じシステムを使用していますか? そうでない場合、私たちは衛生に関して何に頼っていますか?mysql_real_escape_string\

4

2 に答える 2

4

クエリの入力としてサニタイズするものはないようですが。さらに、クエリを入力しただけでは、何も実行されません。

しかし、それはあなたを助ける準備されたステートメントと呼ばれる魔法を持っています。詳細については、@yourcommonsenseのリンクを確認してください。

プリペアドステートメントはSQLインジェクション攻撃からどのように保護できますか?

于 2013-01-29T15:25:24.700 に答える
-1

PDO にはPDO::Quote()と同じ仕事をするメソッドがありmysql_real_escape_string()ます。これは、基本的に同じ機能とセキュリティの sme レベルを提供します。

より良いオプションは、「Prepared Statements」機能です。この機能では、 を使用して変数ではなくクエリにマーカーを挿入し、PDO::prepare()を使用PDO::execute()して変数をクエリに渡します。

これは、データベース エンジンの内部メカニズムを使用して変数をクエリにプッシュするため、より安全です。準備されたステートメントを介した SQL インジェクション攻撃の可能性はゼロです (データベース エンジン自体にバグがない限り、ただし、MySQL のバージョンを最新の状態に保つことで軽減できます。独自のコードとは関係ありません)。

プリペアド ステートメントには、データベース エンジンによってキャッシュできるという利点もあります。これは、同じクエリを使用して変数値が異なる複数の呼び出しを行う場合、古い文字列ベースのメカニズムを使用して同じクエリを作成する場合と比較して、パフォーマンスが向上することを意味します。

注: 一部の DB は、プリペアド ステートメントをネイティブでサポートしていない場合があります。その場合、PHP はそれらをエミュレートします。この場合、基本的に を使用する場合と同じPDO::Quoteであり、上記の利点は得られません。ほとんどのDBはそれらをサポートしていますが、それでも無効になる可能性があるため、必ずオフにしてくださいATTR_EMULATE_PREPARES

最後に、古い mysql 拡張機能には根本的なセキュリティ上の問題がいくつかあったため、PDO を使用する方がより安全です。たとえば、古い API は PHP と MySQL データベース間の通信を暗号化しません。これは、特に DB が PHP と同じサーバー上にない場合、傍受攻撃の理論的なリスクがあることを意味します。PDO はより新しいバージョンの MySQL 通信プロトコルを使用するため、このトラフィックを暗号化することができ、その結果、より安全になります (また、PDO が本当に古いバージョンの MySQL をサポートしていない理由でもあります)。古い API には、コードに深く根付いていて取り除くことができなかった類似の隠れたリスクが他にもいくつかあります。これが、mysqli拡張機能がその直接の代替として作成された理由です。

于 2013-01-29T16:13:24.820 に答える