0

PHP アプリケーションを開発しているときに、この状況について考えました。ユーザーが何らかのテキストをフォームに送信すると、サーバー側でテキストがエスケープされ、データベースに挿入されます。問題は、最後のクエリ (DB からの値を使用するクエリ) で SQL インジェクションが発生する可能性があるかどうかです。

例 (データベース クラスについて説明する必要はないと思います):

$db->query("INSERT INTO accounts SET test='".$db->escape($_POST["sometext"])."'");

OK、これまでのところ、何も起こらないことはわかっています。理論的には、準備されたステートメントでもこれを行うことができましたが、違いはありません。

後で別のスクリプトで使用するために列テストの値が必要になり、値を別の場所に挿入する必要がある場合があります。

したがって、列が選択され、後で挿入されます。

$db->query("SELECT test FROM accounts WHERE ... LIMIT 1");
$row = $db->fetchRow();
$db->query("INSERT INTO secoundtable SET test='".$row["test"]."'");

ご覧のとおり、データベースの値は最後のクエリで使用されます。ここで逃げなきゃいけないの?

4

2 に答える 2

2

この質問に対する答えは、関数 $db->e​​scape が何をするかに大きく依存します。私の推測では、入力変数が入力に対して「安全」になるように単純にサニタイズするのでしょうか? その場合、ユーザー データを信頼しているため、2 番目のクエリで SQL インジェクション攻撃を受けやすくなります。

スクリプトを実行して、自分でテストしてください。

//First query shouldn't cause you any issues (I'm assuming your function is safe).
$test = "'";
$db->query("INSERT INTO accounts SET test='" . $db->escape($test) . "'");

//Second query will cause you issues because you're taking the single quote from your
//table column and inserting it directly into the last query.
$db->query("SELECT test FROM accounts WHERE ... LIMIT 1");
$row = $db->fetchRow();
$db->query("INSERT INTO secoundtable SET test='".$row["test"]."'");

ところで、SQL インジェクションに対して完全に安全になりたい場合は、Prepared Statements の使用を検討する必要があります。ここでのこのトピックは、読む価値があります。

于 2013-05-15T16:29:25.030 に答える
2

適切にパラメータ化されたクエリを常に使用する習慣を身に付ける必要があります。

最初のケースでは、次のことが考えられます。

  • メソッドには、escapeいくつかの場所で適切にエスケープしない原因となるエラーがあります
  • escape呼び出しを削除するために、コードが誤って更新される可能性があります

2 番目のケースでは、test列にアポストロフィが含まれている可能性があります。それは十分に悪いことですが、それがユーザー入力によるものである場合はさらに悪いことです。手で本格的な攻撃を行うことができます。

準備されたステートメント/パラメーター化されたクエリをまったく避ける理由はないと思います。それらは読みやすく、安全であり、簡単に再利用できます。

于 2013-05-15T16:29:03.640 に答える