0

PDO でパラメーター化されたクエリを使用して、かなり複雑なクエリで MySQL データベースからデータを取得しています。これを行う一環として、次のようなコードを使用します。

クエリ:

$query = "SELECT * FROM table WHERE something = :id_$id";
$stmt = $db->prepare($query);

パラメータバインディング:

$stmt->bindParam(":id_$id", $id);

私の理解では、PDO は bindParam への呼び出しで置換文字列を「クリーニング」することにより、パラメーター化された入力をサニタイズしますが、私の質問は 、攻撃者が望ましくない SQL を挿入するために ($id の値を介して) 上記のような構造を悪用できるかどうかです。 ?

PDO は :id_$id のテキストを $id のサニタイズされた値に置き換えます。そのため、:id_$id のどの部分も最終的なクエリに含まれるべきではないと思いますが、明確な答えを得たいです!

編集:これが安全なことであると信じる理由を説明する必要があったほど明確ではなかったようです. もちろん、これが良い方法だとは言いません。

これが安全であると私が考える理由は、PDO (これが間違っている場合は訂正してください) が、置換テキストでサニタイズされたbound-param のテキスト置換を行うためです。直観的に、これは置換テキスト (":id_$id") が任意の値であることを示しているはずです。これは、パラメーターがクエリに配置されたときに PDO によって完全に置き換えられるためです。パラメータの置換にはパラメータの値のサニタイズが含まれるため、「:id_$id」は実行するのが危険な場合がありますが、「$id」(最終クエリに表示されるもの) は安全なはずです。

とにかく、それは私の推論です。私のコードではこれほど危険なことはしていないので、これはより学術的な関心事です。

4

3 に答える 3

1

もちろん脆弱です。

ただし、名前付きプレースホルダーの使用は完全にオプションです。したがって、それらをまったく使用する必要はありません。

$query = "SELECT * FROM table WHERE something = ?";
$stmt = $db->prepare($query);
$stmt->execute(array($id));

そして、ご存知のように、かなり複雑なコードは単純化できます。

于 2013-05-14T05:56:54.023 に答える
-1

$id に許可された値のクローズド セットを使用することを検討する必要があります。つまり:

switch ($id) {
  case "value01":
    $param = ":id_01";
    break;

  case "value02":
    $param = ":id_02";
    break;

  default:
    // safe value
    $param = ":id_00";
}

$query = "SELECT * FROM table WHERE something = $param";
$stmt = $db->prepare($query);
$stmt->bindParam("$param", $id);
于 2013-05-14T06:06:00.847 に答える
-1

pdo は入力をサニタイズします。さらに、bindValue/bindParam の 3 番目の引数でタイプを指定できます。"" の場合、php によって解釈される可能性があるため、トークンの一部として $ を使用することは避けたいと思います。

$query = "SELECT * FROM table WHERE something = :id;";
$stmt = $db->prepare($query);
$stmt->bindParam(":id", $id, PDO::PARAM_INT);

これにより、$id が int でない場合、pdo で例外が発生することが保証されます。

この方法で sql を注入しようとしても、エスケープされます。

于 2013-05-13T19:59:35.343 に答える