1

私たちが知っているように、SQL インジェクションを回避する最善の方法は、バインド変数で準備済みステートメントを使用することです。しかし、準備されたステートメントを使用し、顧客IDがユーザーインターフェイスから来ている以下のような変数をバインドしないとどうなるか疑問があります

String query ="select * from customer where customerId="+customerId;
PreparedStatement stmt = con.prepareStatement(query); //line1

1 行目は、バインド変数を使用していない場合でも、SQL インジェクションを制限していますか?

最善の方法は以下であることに同意しますが、上記のアプローチでSQLインジェクションの制限も処理する場合は、上記のアプローチを優先します(レガシープロジェクトとして)

String query ="select * from customer where customerId=?";
  PreparedStatement stmt = con.prepareStatement(query); 
  stmt.setInt(1, 100);

SQLインジェクションが不可能であることを確認するには、バインド変数を使用せずに準備されたステートメントで十分ですか?

4

3 に答える 3

1

いくつかの事柄を区別する必要があります。

プリペアド ステートメントを使用しても、それだけでは何の役にも立ちません。
同様に、一般的に準備されていない方法を使用しても害はありません。

これは、動的部分を query に挿入する必要がある場合にのみ機能します。したがって、この後者の場合、そのような動的部分はプレースホルダーのみを介してクエリに入る必要があり、実際の値は後でバインドする必要があります (プレースホルダーは?、クエリ内の実際のデータを表すまたはその他のマークです)。

「準備されたステートメント」という用語は、クエリに入るすべての動的データにプレースホルダーを使用することを意味します。そう、

  • クエリに動的部分がない場合、準備されたステートメントを使用しなくても、明らかに注入はまったくありません。
  • 準備されたステートメントを使用しているが、値をバインドするのではなくクエリに直接挿入する場合、インジェクションに対して広く開かれます。

したがって、繰り返しになりますが、すべての動的データ準備済みステートメントのプレースホルダーのみが機能します。そして、それは次の理由で機能します。

  • すべての動的値は適切にフォーマットする必要があります
  • 準備されたステートメントにより、適切な書式設定 (または処理)が避けられなくなります。
  • 準備されたステートメントは、唯一の適切な場所で適切な書式設定 (または処理) を行います - クエリ実行の直前であり、他の場所ではないため、安全性は次のような信頼できないソースに依存しません。
    • データを安全にするよりもむしろデータを台無しにするいくつかの「魔法の」機能。
    • プログラムフローのどこかで変数をフォーマットする(またはフォーマットしない)ことを決定できる1人(または複数)のプログラマーの善意。それが非常に重要なポイントです。
  • 準備されたステートメントは、クエリに入力される値そのものに影響しますが、ソース変数には影響しません。ソース変数はそのまま残り、その後のコードで使用できます (電子メールで送信したり、画面に表示したりできます)。
  • プリペアド ステートメントを使用すると、アプリケーション コードを劇的に短くすることができ、舞台裏ですべての書式設定を行います (*ドライバーが許可する場合のみ)。
于 2013-04-23T06:50:31.157 に答える
-1

これが古い投稿であることは知っていますが、行 1 のクエリに整数のみを許可することを確認できれば、インジェクション攻撃を回避できることを追加したかっただけです。文字列入力は、インジェクション攻撃が発生する場所です。上記のサンプルでは、​​int のように見えますが、変数「customerId」のクラスが不明です。質問は Java とタグ付けされているので、int でインジェクション攻撃を行うことはできないので、問題ないはずです。

行 1 の文字列である場合、'customerId' が安全なソースから取得されたものであり、そこから整数である必要があることを確認する必要があります。投稿フォームまたは他のユーザーが生成したフィールドからのものである場合は、それをエスケープするか、確実に整数に変換することができます。文字列の場合は、整数にキャストしてください。パラメータをバインドする必要はありません。

于 2013-08-23T13:15:04.430 に答える