会社のイントラネットに小さな調査 Web ページを作成しました。このウェブページは外部からアクセスできません。
フォームは、いくつかのラジオ ボタンとコメント ボックスだけです。
適切なコーディング プラクティスを維持し、SQL インジェクションを防止したいと考えています。
テキストボックスからのコメントを含む挿入ステートメントで SQL インジェクションが発生する可能性はありますか? もしそうなら、.NET 2.0 を使用してそれを防ぐにはどうすればよいですか?
会社のイントラネットに小さな調査 Web ページを作成しました。このウェブページは外部からアクセスできません。
フォームは、いくつかのラジオ ボタンとコメント ボックスだけです。
適切なコーディング プラクティスを維持し、SQL インジェクションを防止したいと考えています。
テキストボックスからのコメントを含む挿入ステートメントで SQL インジェクションが発生する可能性はありますか? もしそうなら、.NET 2.0 を使用してそれを防ぐにはどうすればよいですか?
インジェクションは、正しく実行されていないSQLステートメントで発生する可能性があります。
たとえば、コメントテーブルに整数IDとコメント文字列の2つのフィールドがあるとします。したがってINSERT
、次のようになります。
INSERT INTO COMMENTS VALUES(122,'I like this website');
次のコメントを入力する人を考えてみましょう。
'); DELETE FROM users; --
処理せずにコメント文字列をSQLに入れるだけの場合、これにより、シングルINSERT
が次の2つのステートメントになり、その後にコメントが続く可能性があります。
INSERT INTO COMMENTS VALUES(123,''); DELETE FROM users; -- ');
これにより、テーブルからすべてが削除されますusers
。そして、試行錯誤やさまざまなトリックを使って、空にする正しいテーブル名を見つけるために一日中費やすことをいとわない人々がいます。 SQLインジェクション攻撃を実行する方法の説明は次のとおりです。
これを防ぐには、パラメーター化されたSQLステートメントを使用する必要があります。
そして、これはセキュリティ上の理由だけではありません。たとえば、SQLステートメントを素朴に作成している場合は、次のコメントを参照してください。
I'm just loving this website
アポストロフィがSQLによって終了引用符として解釈されるため、SQL構文エラーが発生します。
パラメータ化されたクエリを使用して、テキストが自動的に引用されるようにします。
SqlCommand command = connection.CreateCommand();
command.CommandText = "insert into dbo.Table (val1,val2,txt) values (@val1,@val2,@txt)";
command.AddParameterWithValue( "val1", value1 );
command.AddParameterWithValue( "val2", value2 );
command.AddParameterWithValue( "txt", text );
...
SQL インジェクションは、クエリをデータベースに戻すたびに発生する可能性があります。簡単なデモンストレーションを次に示します。
.NET 内での重要な点は、Dave Webb が示したようにすることです。送信される 1 つのパラメーターとして文字列全体を包含し、SQL Server によって解釈される可能性のあるすべての文字を処理して、クエリを変更したり、追加のコマンドを追加したりすることで、インジェクションの試みを防ぎます。
また、Web アプリケーションだけでなく、あらゆるアプリケーションで SQL インジェクションが発生する可能性があることに注意してください。そして、通常、組織にとって最もコストがかかるのは内部攻撃です。攻撃が内部から発生しないと安全に想定することはできません。
はい、発生する可能性があります。これを防ぐ最も簡単な方法は、SQLを手動で作成するのではなく、プリペアドステートメントを使用することです。
だから、これではなく:
String sql =
String.Format("INSERT INTO mytable (text_column) VALUES ( '{0}' )",
myTextBox.Text); // Unsafe!
あなたはこのようなことをするでしょう:
String sql = "INSERT INTO mytable (text_column) VALUES ( ? )"; // Much safer
次に、テキストボックスのテキストをパラメータとしてDbCommandに追加します。これにより、テキストボックスが自動的にエスケープされ、「?」が置き換えられます。SQLで。
準備済みステートメントを使用して SQL インジェクションを防止します。placehoder(?) を使用すると、SQL インジェクションの脆弱性が完全に排除されます。example String sql=Select * from user_table where username='+request.getparameter("username")+'; statement.executeQuery(sql);
上記のステートメントは、SQL インジェクションに対して脆弱です。
SQLインジェクションに対して安全にするため。スニペットに従って使用する
String sql=Select * from user_table where username=?; statement.setString(1,ユーザー名);
はい、できます。クライアントがこれを送信するとします。
OR 1 = 1
それはあなたにとって非常に苦痛になる可能性があります
SELECT * FROM admin WHERE name = @name AND password = @password
あなたはこれを防ぐことができます
この形式のSQLインジェクションを防ぐ最も簡単な方法は、実行するSQLステートメントを作成するのではなく、パラメーターとストアドプロシージャを使用することです。(C#またはSQL Serverの内部)。
ただし、これに時間を費やす必要があるかどうかは完全にはわかりません。もちろん、それが企業ポリシーでない限り、内部で発生する可能性はせいぜい最小限であり、発生した場合は、誰がすぐにわかることを願っています。です。