web-dev-qa-db-ja.com

prepareStatementはSQLインジェクションを回避しますか?

脆弱なSQLクエリを読んで、アプリケーションに挿入しようとしました。それは十分に安全ではありません。データベースの検証やその他の挿入操作にステートメント接続を使用しています。

PrepareStatementsは安全ですか?さらに、このステートメントにも問題がありますか?

35
Mohamed Saligh

文字列連結を使用して任意の入力からクエリを作成しても、PreparedStatementは安全ではありません。この例を見てください:

preparedStatement = "SELECT * FROM users WHERE name = '" + userName + "';";

誰かが入れたら

' or '1'='1

userNameと同様に、PreparedStatementはSQLインジェクションに対して脆弱です。これは、そのクエリが次のようにデータベースで実行されるためです。

SELECT * FROM users WHERE name = '' OR '1'='1';

したがって、使用する場合

preparedStatement = "SELECT * FROM users WHERE name = ?";
preparedStatement.setString(1, userName);

あなたは安全になります。

このWikipediaの記事 から取得したこのコードの一部。

56
darioo

準備されたステートメントは、適切に使用すると、SQLインジェクションから保護されます。ただし、コード例を質問に投稿してください。正しく使用しているかどうかを確認できます。

2
pts

この記事 で説明されているように、文字列を連結している場合、PreparedStatementだけでは役に立ちません。

たとえば、1人の不正な攻撃者が次のことを実行できます。

  • すべてのデータベース接続がビジーになるようにスリープ関数を呼び出し、アプリケーションを使用不可にします
  • dBから機密データを抽出する
  • ユーザー認証のバイパス

また、影響を受けるのはSQLだけではありません。バインドパラメータを使用していない場合、JPQLでも危険にさらされる可能性があります。

結論として、SQLステートメントを作成するときに文字列連結を使用しないでください。そのために専用のAPIを使用します。

1
Vlad Mihalcea

単純にPreparedStatementを使用するだけでは安全ではありません。 SQLクエリでパラメーターを使用する必要がありますが、これはPreparedStatementで可能です。詳細については、 ここ を参照してください。

1
Petar Minchev