web-dev-qa-db-ja.com

PHP MySQLI Prevent SQL Injection

私はすぐに公開されるウェブサイトを構築し、SQLインジェクションの防止についていくつか質問がありますが、mysqli_real_escape_stringの使用方法は理解していますが、私のSQL文を取得していますが、select文を実行しているとき、または挿入更新と削除時にだけ使用する必要がありますか?また、サイトを公開する前に他のセキュリティを実装することをお勧めします。

39
user2201765

読み取りまたは書き込み、永続的または一時的であるかどうかにかかわらず、任意のクエリを挿入できます。インジェクションは、1つのクエリを終了し、別のクエリ(mysqliで可能)を実行することで実行できます。これにより、目的のクエリが無関係になります。

ユーザーからのものであれ、内部からのものであれ、外部ソースからのクエリへの入力は、クエリへの引数、およびクエリのコンテキスト内のパラメータと見なされる必要があります。クエリ内のパラメータはすべてパラメータ化する必要があります。これにより、適切にパラメーター化されたクエリが作成され、準備されたステートメントを作成して引数を使用して実行できます。例えば:

SELECT col1 FROM t1 WHERE col2 = ?

?は、パラメーターのプレースホルダーです。 mysqliを使用すると、prepareを使用して準備済みステートメントを作成し、bind_paramを使用して変数(引数)をパラメーターにバインドし、executeを使用してクエリを実行できます。引数を完全にサニタイズする必要はありません(実際、サニタイズするのは有害です)。 mysqliはあなたのためにそれをします。完全なプロセスは次のとおりです。

$stmt = mysqli->prepare("SELECT col1 FROM t1 WHERE col2 = ?");
$stmt->bind_param("s", $col2_arg);
$stmt->execute();

また、パラメータ化されたクエリ準備済みステートメントの間には重要な違いがあります。このステートメントは準備されていますが、パラメーター化されていないため、インジェクションに対して脆弱です。

$stmt = mysqli->prepare("INSERT INTO t1 VALUES ($_POST[user_input])");

要約する:

  • すべてクエリは適切にパラメーター化する必要があります(パラメーターがない場合を除く)
  • すべてクエリへの引数は、ソースに関係なく、可能な限り敵対的に扱われるべきです。
46
Explosion Pills

数秒で閉じられますが、単に物事をまっすぐにするために

Mysqli_real_escape_stringの使用方法を理解しています

私はあなたがそうでないのではないかと心配しています。

sQLステートメントで取得するすべての変数でそれを使用する必要がある場合

絶対にありません。
この関数は、SQL文字列のフォーマットに使用する必要がありますonly

select文を実行しているとき、または単に更新と削除の挿入時に使用する必要がありますか?

[〜#〜] any [〜#〜] SQLステートメント。しかし、再び、「mysqli_real_escape_stringを使用する」のではなく、リテラルを完全かつ適切にフォーマットする

また、他にどのセキュリティをお勧めしますか

sQLセキュリティに関して-文字列だけでなくany kindのリテラルを適切にフォーマットする必要があります。そして、それぞれにフォーマットルールの別個のセットが必要です

1