より簡単に理解し、より一般的な答えは、このように書きます:
動的SQLクエリを想像してみて:
sqlQuery='SELECT * FROM custTable WHERE User=' + Username + ' AND Pass=' + password
単純なSQLインジェクションがちょうどこれが効果的にSQLクエリになるだろう' OR 1=1--
として
ユーザーネームを入れて次のようになります。
sqlQuery='SELECT * FROM custTable WHERE User='' OR 1=1-- ' AND PASS=' + password
これがtrueに等しくする、boolean型である、その名が空白(''
)または1=1
あるすべての顧客を選択すると言います。その後、--
を使用して残りのクエリをコメント化します。これにより、カスタマーテーブル全体が印刷されます。または、それを使用して何でもできます。
は今、パラメータ化クエリは、コードのように、違ったことを実行します。ユーザー名とパスワードが関連付けられているinputedユーザ名とパスワードを指し示す変数です
sqlQuery='SELECT * FROM custTable WHERE User=? AND Pass=?' parameters.add("User", username) parameters.add("Pass", password)
。
今のところ、これは何も変わらないと思うかもしれません。きっとあなたはまだだけのユーザ名フィールドに誰OR = 1' 1のようなものを入れることができます - 、効果的にクエリを作成:
sqlQuery='SELECT * FROM custTable WHERE User=Nobody OR 1=1'-- AND Pass=?'
そして、これは有効な引数のように思われます。しかし、あなたは間違っているでしょう。
パラメータ化されたクエリが動作する方法は、SQLクエリがクエリとして送信され、データベースがこのクエリが行うことを正確に認識しているだけで、ユーザー名とパスワードを単に値として挿入します。これは、データベースがすでにクエリが何をするのかを知っているため、クエリに影響を与えることができないことを意味します。したがって、この場合、ユーザ名はNobody OR 1=1'--
で、空白のパスワードが検索されますが、falseになるはずです。
これは完全な解決策ではありません。入力検証はまだ実行する必要があります。xssなどの他の問題に影響することはないので、データベースに入れても問題ありません。それがページに読み込まれると、出力の検証に応じて通常のjavascriptとして表示されます。だから実際には、入力検証を使用するのが最善ですが、パラメータ化されたクエリやストアドプロシージャを使用してSQL攻撃を止めることです。
出典:http://www.lavamunky.com/2011/11/why-parameterized-queries-stop-sql.html
また、(この場合、およびTSQL)SQL変数をサポートしていない場所で変数を使用しようとするためにエラーが発生します。 IE: 'FROM'句、IN句でカンマで区切られたリストを表す単一のパラメータなど –
これは質問に答えないと思います。 SQLParameterクラスを使用してストアドプロシージャを呼び出すことができます。SQLParameterクラスは、プロシージャにparamsを渡しますが、sp_executesqlは呼び出しません。連結されたSQL文字列のパラメータ値はどうなりますか? – Ian