パラメーターは、悪意のあるユーザー入力からユーザーを保護するために使用されます。
しかし、パラメータが文字列を想定している場合、悪意のあるユーザーが「DROP」、「TRUNCATE」などを使用できるように、SQL として解釈される入力を書き込むことは可能ですか?
asp、asp.net、Java などのパラメータ間の保護に違いはありますか?
パラメーターは、悪意のあるユーザー入力からユーザーを保護するために使用されます。
しかし、パラメータが文字列を想定している場合、悪意のあるユーザーが「DROP」、「TRUNCATE」などを使用できるように、SQL として解釈される入力を書き込むことは可能ですか?
asp、asp.net、Java などのパラメータ間の保護に違いはありますか?
パラメーター化されたクエリは、通常、パラメーターがバックグラウンドで文字列である場合、通常の SQL 演算子がそのように解釈されないようにパラメーターを引用符で囲みます。これは、ユーザーが悪意のある可能性のあるデータを入力した場合でも、単に文字列入力として扱われ、SQL 演算子/コマンドとして解釈されないことを意味します。
さまざまなフレームワークでの実装方法には技術的な違いがあるかもしれませんが、基本的な考え方 (および結果) は同じです。
定義には注意が必要です。「パラメーター」にはさまざまな意味があります。たとえば、ストアド プロシージャへのパラメーターは、それ自体ではまったく保護されません。Java を例として使用するには、次のようにします。
sql = "exec proc_SearchForUser '" + userNameToSearch + "'";
生より良くも悪くもありません
sql = "SELECT * FROM Users WHERE userName = '" + userNameToSearch + "'";
ユーザー名の影響を受けやすい
';DROP TABLE users;--
一方、パラメータ化されたクエリは安全です。彼らは次のように見えるかもしれません
PreparedStatement statement = con.prepareStatement("SELECT * FROM Users WHERE userName = ?");
または実際に
PreparedStatement statement = con.prepareStatement("exec proc_SearchForUser ?");
これが安全な理由は、値を入力するときに...たとえば、
statement.setString(1, userName);
その場合、文字列 ("';DROP TABLE users;--" のようなものであっても) は DB エンジンによって適切にエスケープされ、無害になります。
それを台無しにすることはまだ可能です。たとえば、ストアド プロシージャが内部的に SQL 文字列を作成して実行し、入力を信頼している場合などです。その攻撃ベクトルを遮断します。
BindWhatever() 呼び出しを介してパラメーターとして入力したものは、SQL として実行できません。
ht evariable データをバインドする前に、SQL は既に解析および評価されているため、このデータが SQL と間違われることはまったくありません。
もちろん、データベースが忠実に保存され、他の誰かのブラウザで実行される可能性がある場合は、JavaScript を渡すこともできます!
そのため、({[]})\ タイプの文字を入力から取り除く (または少なくともエスケープする) 必要があります。
いいえ。SQL インジェクション攻撃は、どの SQL DB のどの言語からでも発生する可能性があります。あなたが言及している攻撃の種類は、プログラマーが「USER_NAME = sName」のようなソースで動的 SQL を使用し、ユーザーがユーザー名に無制限のテキストを入力できるため、コメントを追加してから、「」などの新しい SQL ステートメントを入力できる場合です。 DROP」、「TRUNCATE」など。
パラメータとしてではありません。SQL インジェクションは、悪意のあるコードを SQL 文字列に連結し、その文字列から SQL ステートメントを実行することに依存しています。準備されたステートメントは、内容に関係なくパラメーターを取ります。準備済みステートメントでは、SQL ステートメント自体の実際のテキストは決して変更されません。
exec
唯一のリスクは、パラメータ化された文字列に対して を実行する場合です。
それ以外の場合はすべて、パラメーター化されたクエリは安全です。