2010-12-02 6 views
31

私はアプリケーションに脆弱なSQLクエリを読み込んで試しました。十分安全ではありません。私は単に、データベースのバリデーションやその他の挿入操作にStatement Connectionを使用しています。preparedStatementはSQLインジェクションを回避しますか?

preparedStatementsは安全ですか?また、この声明にも問題はありますか?

+1

プリペアドステートメントを移動するための方法です。 AFAIK準備された文は一度しか解析されないので、後でSQLインジェクションの機会はありません。もちろん、XSS攻撃などから保護するために、入力をサニタイズする必要があります。 – CurtainDog

答えて

47

任意の入力からクエリを構築するために文字列連結を使用すると、PreparedStatementは安全になりません。この例を見てみましょう:

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

を誰かがuserNameとして

' or '1'='1 

を置く場合は、あなたのPreparedStatementそのクエリが

SELECT * FROM users WHERE name = '' OR '1'='1'; 
としてデータベース上で実行されるため、SQLインジェクションの脆弱性になります

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

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

あなたは安全です。

this Wikipedia articleから取得したコードの一部です。

+3

setStringは何か違いはありますか?それは実際に何をしていますか?たとえそれが文字列の代わりに使われることさえあります。何が違うの? –

+10

@モハメッド:それは違いを生む。クエリー '' SELECT * FROM users WHERE name =? ''はコンパイルされたデータベースに送られ、' 'setString'の' 'userName'が代入されます。データベースに不正な値があると、エラーが発生します。したがって、 ''または' 1 '=' 1'は演算子'または 'と' = 'を含む文ではなく、文字列全体として扱われます。データベースは、それを値 "" 'または' 1 '=' 1 ''を持つ文字列として認識します。 – darioo

2

プリペアドステートメントを正しく使用すると、SQLインジェクションから保護されます。しかし、あなたの質問にコードサンプルを投稿してください。そうすれば、あなたがそれを適切に使用しているかどうかを知ることができます。

1

よく、単にPreparedStatementを使用しても安全にはなりません。 SQLクエリでは、PreparedStatementで可能なパラメータを使用する必要があります。詳細についてはhereをご覧ください。

1

this articleで説明したように、PreparedStatementだけでも、文字列を連結している場合は役に立ちません。例えば

、1回の不正な攻撃者はまだ次の操作を行うことができます。すべてのデータベース接続がビジー状態になるように、したがって、DBから機密データを抽出

  • アプリケーションが利用できなくなって、

    は、そして、それが影響を受けることができ、BだけSQLではありません。バインドパラメータを使用していない場合でも、JPQLさえ危うくなります。

    ボトムラインの場合、SQL文を作成するときには文字列連結を使用しないでください。その目的のために、専用のAPIを使用してください:

  • 関連する問題