3

query.sql次の内容で呼び出されたファイルがあるとします。

SELECT * FROM `users` WHERE `id`!=".$q->Num($_POST['id'])."

そして、「id」という名前の入力を含むhtmlフォームを持つphp-scriptで、次のトリックを実行します。

$sql=file_get_contents('query.sql');
$query= eval("return \"$sql\";");
//here follows something like $mysqli->query($query); and so on..

プリペアドステートメントを使用してチェックを実行しているので、SQLインジェクションについては心配していません。しかし、evalをそのように使用するのは安全ですか?$q->Numis_int

私が理解している限り、ここで実際に評価されるのは「$ {_ POST ['id']}」であり、ユーザーが入力した文字列値に評価されます。そして、これは、この文字列を2回評価した場合にのみ危険になります。私は文字列を一度だけ評価しますが、ユーザーの入力は単なる文字列であり、コンパイラーによってphp-codeとして解釈することはできず、php-injectionは不可能です。

更新 さまざまな方法論を提案し、準備されたステートメントを使用する必要性を強調していただきありがとうございます。しかし、これは私の質問ではありません。私の質問はすべてphp-injectionsについてです。そのようなevalの使用は悪いですか?はいの場合、なぜですか?

4

4 に答える 4

2

eval ステートメントは、eval を使用しない方法を見つけようとしますが$sql、二重引用符で囲まれているため、PHP インジェクションに対して脆弱ではありません"。PHP では、準備された変数でこの引用符を終了することはできません。


準備済みステートメントを使用しているため、SQL インジェクションについては心配していません。

そうじゃない?;) あなたは!

「.」を使用してクエリに $id を追加するのはなぜですか。演算子 (文字列操作)? 準備されたステートメントの利点を実際に使用する場合、次のようなものを期待しますbindParam()

準備されたステートメントが SQL インジェクションをどのように防ぐかに注意してください。SQL クエリ構文は、引数とは別に保持されています。したがって、サーバーは

  1. SQL クエリを解析する
  2. 引数を適用

引数が適用される前にクエリが既に解析されているため、クエリ構文を引数で操作することはできません。

「.」を使用して作成された MySQL クエリを準備する場合 SQL インジェクションに対して潜在的に脆弱な外部入力

あなたがしていることは、準備されたステートメントの原則を打ち負かします

于 2013-01-23T16:39:40.940 に答える
2

使用する必要はありませんeval- トークンを入れて、それを置き換えます:

// file query.sql
SELECT * FROM `users` WHERE `id`!="{id}";

//php
$sql = file_get_contents('query.sql');
$query = str_replace("{id}", $_POST['id'], $sql);

更新 いいえ、安全ではありません。誰かがあなたのquery.sqlスクリプトを編集して、あなたがやりたいことを何でもできるようにすることができます。「アプリは内部専用です」、「アクセス許可がロックされています」などと言うかもしれませんが、結局のところ、保証はありません。

于 2013-01-23T16:41:10.713 に答える
1

この回答からの参照。

https://stackoverflow.com/a/951868/627868

eval() の主な問題は次のとおりです。

安全でない入力の可能性。信頼されていないパラメーターを渡すと、失敗する可能性があります。多くの場合、パラメーター (またはその一部) が完全に信頼されていることを確認するのは簡単な作業ではありません。

トリッキーさ。eval() を使用するとコードが賢くなり、従うのが難しくなります。Brian Kernighan の言葉を引用すると、「デバッグは、そもそもコードを書くよりも 2 倍難しい。したがって、コードを可能な限り巧妙に書いたとしても、定義上、それをデバッグできるほど頭が良くないということになる」

于 2013-01-23T16:37:05.610 に答える
-1

次のコードを考えてみましょう。

$sql=file_get_contents('query.sql');
$query= eval("return \"$sql\";");

これにおける危険なポイントは次のとおりです。

  • ファイルquery.sqlが期待どおりに変更された場合、プログラム内の任意のコードを実行するために使用される可能性があります。

  • ファイルの名前はハードコードされて表示されます。そうでない場合、悪意のあるユーザーが予期しないファイル(場合によってはリモートサイトからのファイル)をロードする方法を見つけて、任意のコードが実行される可能性があります。

  • (SQLコードをプログラムに直接ハードコーディングするのではなく)このためにファイルを使用する唯一の理由は、それを構成ファイルとして使用したいからです。ここでの問題は、このファイルの構文がSQLとPHPの両方で無効であるということです。での実行方法によりeval()、構文が正確である必要もあります。間違った引用符を使用するか、引用符を見逃すと、爆発します。これにより、コードが脆弱になる可能性があり、構成がわずかに正しくない場合、正常に失敗するのではなく、ひどく失敗します。

ここでは直接SQLインジェクション攻撃は行われていないようですが、それに関しては、心配する必要はほとんどありませんeval()

私は、あなたが説明したのとほぼ同じように機能するコードが存在するプロジェクトで個人的に働いてきました。これの直接の結果として、システムにいくつかの非常に厄介なバグがあり、それらは大規模な書き直しなしに修正することは困難でした。コメントで他の人が推奨しているように、このアイデアから離れて、代わりに賢明なテンプレートメカニズムを使用することを強くお勧めします。

于 2013-01-23T17:33:45.037 に答える