SQL インジェクション攻撃を回避するにはどうすればよいですか?
-
18-09-2019 - |
質問
昨日、私は開発者と話していて、彼はデータベースフィールドへの挿入の制限について言及しました。たとえば、次のような文字列です。 --
(マイナスマイナス)。
同じ型で、私が知っているのは、次のような HTML 文字をエスケープするための良いアプローチであるということです。 <
, >
等ない --
. 。これは本当ですか?心配する必要がありますか --
, ++
?それは神話のようなものですか、それとも古いものですか?
アップデート
すべての回答に感謝します。私はこれらすべてに慣れていないので、そのように理解するのは簡単です。そうですね、この場合、より具体的に言うと、開発中の C# ASP.NET MVC Web サイトに関する議論だったので、重要な情報が記載された複雑なアカウント開設フォームがそこにあるため、MVC が Linq を使用してデータベースとのインターフェースには、この種の保護がすでに備わっているかどうか。したがって、誰かがそれについてヒントを提供できれば、それは素晴らしいことです。再度、感謝します
解決
SQL インジェクション攻撃を回避する適切な方法は、単に特定の問題のある文字を禁止するのではなく、パラメータ化された SQL を使用することです。つまり、パラメータ化された SQL は、データベースが SQL コマンドの一部として生のユーザー入力を実行することを防ぎ、これにより、「テーブルの削除」などのユーザー入力が実行されなくなります。文字をエスケープするだけでは、あらゆる形式の SQL インジェクション攻撃を阻止できるわけではありません。また、「Drop」などの特定の単語を除外しても、すべての場合に機能するとは限りません。特定のフィールドでは、「ドロップ」がデータ入力の完全に有効な部分になる場合があります。
パラメータ化された SQL の主題に関するいくつかの優れた記事をここで見つけることができます。
https://blog.codinghorror.com/give-me-parameterized-sql-or-give-me-death/
http://www.codeproject.com/KB/database/ParameterizingAdHocSQL.aspx
ASP.net を使用しているとのことでしたので、特に ASP での SQL インジェクションを扱うリンクをいくつか紹介します。
https://dzone.com/articles/aspnet-preventing-sql-injectio http://www.codeproject.com/KB/aspnet/SQL_Injection_.aspx?msg=3209511
ASP の安全性を高めるためのより一般的な記事は次のとおりです。http://www.codeproject.com/KB/web-security/Securing_ASP_NET_Apps.aspx
そしてもちろん、SQL インジェクションに関する MSDN の記事:http://msdn.microsoft.com/en-us/library/ms998271.aspx
他のヒント
SQL インジェクションは、データベース上で実行されるステートメントにユーザーがパラメーターを吹き込むことができるほとんどの Web サイトにとって、高いセキュリティ リスクです。
簡単な例は次のとおりです。
入力フィールド「名前:_________
"SELECT * FROM tblCustomer WHERE Name = '" + nameInputField + "'"
「Bob」と入力すると、次のようになります。
"SELECT * FROM tblCustomer WHERE Name = 'Bob'"
しかし、「」と入力すると;DROP TABLE tblCustomer" を実行すると、最終的にはさらに邪悪な結果になります。
"SELECT * FROM tblCustomer WHERE Name = ''; DROP TABLE tblCustomer"
これらの問題を回避する方法はたくさんあり、その多くは使用している言語に組み込まれています。そのため、「;」、「--」、「/*」などの危険な可能性をすべて考えるのではなく、次のようなものを使用してみてください。もう存在している。
使用している言語を大声で知らせていただければ、これらの攻撃を回避する方法をお伝えできると思います。
彼が話していたのは SQLインジェクション 彼の言ったことはまさにその通りです。
問題は、そのようなデータがデータベース内に存在することではなく、入力データをサニタイズせずにデータベースに直接渡すことにあります。
クリーンアップせずに、誰かが末尾の文字列を渡した場合、 ;
その後、その後に好きなものを続けることができます (select * from sys.objects
, 、たとえば)または、いくつかのテーブルを削除するなど、より悪意のあるもの。
これを完全に防ぐことは困難ですが、コードから適切な DB ライブラリを使用し、パラメータ化されたクエリの使用などの既知の慣行に従えば、起こり得る被害を制限できます。
たくさん保管してください --
ただし、クリーンアップ プロセスを経ずにそれをデータベースに渡さないでください (ここで優れた DB ライブラリが重要です。引用符やその他の潜在的に有害な入力をクリーンアップする必要があります)。
以下を含む文字列を挿入することに「危険」はありません。 --
データベース内で。
差し込むと危険です 何でも ユーザー入力を処理せずに直接取得したデータベース テーブルに保存します。そうしないと、無防備なままになります。 SQLインジェクション攻撃. 。例:コーダーはユーザーに自分の名前をフィールドに入力させ、ユーザーは次のように入力します。
Joe '); drop table users; commit transaction; --
そしてプログラマーはそれを次のように MySQL データベースに置きます。
conn.execute("insert into users (username) values ('" + userInput + "')");
ブーム ユーザーがユーザー テーブルを削除しました (データベース ログインに削除する権限があると仮定しますが、削除すべきではありませんが、それは別の話です)。コーダーがユーザーからの文字列が正しくエスケープされていることを確認しなかったため、そのため、DB エンジンに直接送信され、攻撃者は大笑いしました。:-)
環境が提供するあらゆるツールを使用して、文字列が正しくエスケープされていることを確認します。たとえば、JDBC は PreparedStatement
このためのクラス。ほとんどの環境でも同様のものがあります。
パラメータ化されたクエリを使用します。これらのクエリは、SQL 内のプレースホルダーとして変数を表します。たとえば、 select * from person where name = ?
. 。SQL クエリを作成した後、クエリにパラメータ値を設定します。パラメーター化されたクエリでは、プレースホルダーに置き換えられたものは SQL ステートメントの一部とはみなされません。
見る ジェフ・アトウッドの記事 パラメータ化されたクエリの概要を説明します。
INSERT/UPDATE/... を実行するときにデータを正しくエスケープする限り、危険ではありません。
HTML 文字をエスケープするのは、 ない 良いアプローチです。このような文字をエスケープする関数を作成し、エスケープされたテキストをデータベースに保存したと想像してください。次に、関数が '<' をエスケープしていないことに気づき、関数を変更します...では、データベースにすでに存在するレコードはどうなるでしょうか?- 「<」文字はエスケープされないままになります。したがって、 一度もない データベースに保存する前にテキストをエスケープします (もちろん、SQL クエリをエスケープします)。エスケープは、HTML/XML/... の場合に発生する必要があります。ページはテキストから、つまりデータベースから元のテキストをクエリした後に生成されます。