0

重複の可能性:
PHP で SQL インジェクションを防ぐ方法は?

このスニペットを検討してください。

*mysqltest.php*

$user_id= $_GET['user_id'];
$user_id= mysql_real_escape_string($user_id);
$query  = "SELECT * FROM people WHERE uid=".$user_id;
echo $query;
//then execution ..

さて、このスクリプトを「mysqltest.php?user_id=56 or 1」と呼ぶと

クエリは SELECT * FROM people WHERE uid=56 or 1となり、インジェクションが成功します。

では、列が数値型であるような状況で、どうすれば身を守ることができるでしょうか?
これらの状況で、pdo または準備済みステートメントを使用しない他の回避策はありますか?

4

1 に答える 1

0

mysql_real_escape_string には「その他の問題」 はありません。

ほとんどの人は、この関数が「ユーザー入力」を何らかの方法で「クリーニング」することによってインジェクションから保護することを意図していると考えて、この関数を混乱させています。
これは確かに間違っています。
mysql_real_escape_string は、文字列をフォーマットして、SQL クエリに適したものにすることを目的としています。それで全部です。副作用として、注射もできなくなります。

そのため、文字列をクエリに動的に追加するたびに、データ ソースに関係なく、両方の文字列フォーマット規則に従う必要があります。

  • データを引用符で囲みます
  • その中の特殊文字をエスケープする

それらは互いに無用であるためです。

数値を文字列として扱っても問題ありませんが。
したがって、指定された例では、削除された回答で提案されているように、データを文字列として扱います

$user_id= $_GET['user_id'];
$user_id= mysql_real_escape_string($user_id);
$query  = "SELECT * FROM people WHERE uid='$user_id'";

唯一の例外は、整数のみである必要がある LIMIT 句のパラメーターです。
この場合の唯一の解決策は、データを目的の形式に手動でキャストすることです

$user_id= $_GET['user_id'];
$user_id= intval($user_id);
$query  = "SELECT * FROM people WHERE uid=$user_id";

しかし、覚えておいてください、別の治療を必要とする他のケースがあります

追加するもう1つのこと。
データを手動でフォーマットするのは退屈です。
いくつかのコードに任せて、コードを短く安全にする方がはるかに良い

于 2013-02-02T12:08:58.760 に答える