4

http://php.net/manual/en/pdo.prepared-statements.php

アプリケーションがプリペアド ステートメントのみを使用する場合、開発者は SQL インジェクションが発生しないことを確認できます (ただし、クエリの他の部分がエスケープされていない入力で構築されている場合、SQL インジェクションは依然として可能です)。

入力の一部がエスケープされていない場合、どのようなシナリオが考えられますか? 他のすべての入力が PDO を使用してデータベースに送られる場合でも、それは可能ですか?

他の入力が mysql_* 関数で処理され、mysql_real_escape_string でエスケープされないシナリオを考えています。他に脅威になり得るものはありますか?

どうもありがとう。よろしく

4

3 に答える 3

8

これは、信頼されていない値を列やテーブルの名前として、または LIMIT パラメータとして直接使用できないことを意味します。

たとえば、これは安全です。

$query = "SELECT * FROM tbl WHERE col = ?";

これらはそうではありませんが:

$query = 'SELECT * FROM tbl WHERE col = ? LIMIT ' . $_GET['limit'];
$query = 'SELECT * FROM tbl WHERE ' . $_GET['field'] . ' = ?';
$query = "SELECT * FROM tbl WHERE col = ? AND othercol = '" . $_GET['other'] . "'";
$query = 'SELECT * FROM ' . $_GET['table'] . ' WHERE col = ?';

基本的に、プリペアド ステートメントのプレースホルダーは、従来のクエリで一重引用符内のエスケープ値を使用する場所で使用することを意図しています。

データベースが通常、テーブル名などのプレースホルダーをサポートしていない理由を知りたい場合: 動的なテーブル/列名がそれほど一般的ではないという事実に加えて、データベース エンジンは通常、準備されたステートメントを準備時に最適化します。ただし、これは、どのテーブル/列がアクセスされているかを正確に知らなければ、適切に行うことはできません。

于 2012-05-17T12:19:40.560 に答える
2

このことを考慮:

$sql = "SELECT * FROM ".$_GET['tablename']." WHERE somecol = ?";

エスケープされていないユーザー入力をテーブル名に入力したため、たとえば、比較public_table p LEFT JOIN hidden_table h ON h.id = p.idに渡された値をエスケープした場合でも、渡して、望まない結果を取得することができます。somecol

重要なのは、プリペアドステートメント?はクエリでに渡したユーザー入力を安全にエスケープできますが、に渡す前に文字列にすでに存在していたデータをエスケープすることはできないということprepare()です。

于 2012-05-17T12:22:44.117 に答える
0

これは、PDOが魔法の薬であると思わせないことを意味します...プリペアドステートメントを使用しない場合でも、脆弱になります。

于 2012-05-17T12:21:45.800 に答える