SQL クエリからすべての ' 文字を削除した場合、データベースに対して SQL インジェクション攻撃を行う他の方法はありますか?
どうすればそれができますか?誰でも例を挙げてもらえますか?
SQL クエリからすべての ' 文字を削除した場合、データベースに対して SQL インジェクション攻撃を行う他の方法はありますか?
どうすればそれができますか?誰でも例を挙げてもらえますか?
はいあります。ウィキペディアからの抜粋
"SELECT * FROM data WHERE id = " + a_variable + ";"
このステートメントから、作成者が a_variable を「id」フィールドに関連する数値にすることを意図していたことは明らかです。ただし、それが実際に文字列である場合、エンド ユーザーはステートメントを好きなように操作できるため、エスケープ文字を使用する必要がなくなります。たとえば、a_variable を次のように設定します。
1;DROP TABLE users
SQL は次のようにレンダリングされるため、データベースから「users」テーブルをドロップ (削除) します。
SELECT * FROM DATA WHERE id=1;DROP TABLE users;
SQL インジェクションは、戦うだけの単純な攻撃ではありません。私があなただったら、非常に注意深く調査します。
はい、使用しているステートメントによって異なります。ストアド プロシージャを使用するか、少なくともパラメーター化されたクエリを使用して、自分自身を保護することをお勧めします。
予防のサンプルについては、ウィキペディアを参照してください。
はい、それは間違いなく可能です。
次のSELECTステートメントを作成する整数を期待するフォームがある場合は、次のようなものを入力できます。
SELECT * FROM thingy
WHERE attributeID =
users
; (悪い、悪い、悪い...)次のWebサイトでは、さらに古典的なSQLインジェクション技術について詳しく説明しています。SQLインジェクションのチートシート。
パラメータ化されたクエリまたはストアドプロシージャを使用することは、これ以上良いことではありません。これらは、渡されたパラメータを使用して事前に作成されたクエリであり、インジェクションのソースにもなります。このページでも説明されています:SQLでのストアドプロシージャの攻撃。
ここで、単純な引用を抑制すると、特定の攻撃セットのみを防ぐことができます。しかし、それらのすべてではありません。
いつものように、外部からのデータは信用しないでください。これらを次の3つのレベルでフィルタリングします。
楽しんで、ウィキペディアで答えを確認することを忘れないでください。
独自の SQL を作成するのではなく、変数をパラメーターとして渡すことをお勧めします。それ以外の場合は、現在認識されていない方法で SQL インジェクションを実行する方法が常に存在します。
作成するコードは次のようになります。
' Not Tested
var sql = "SELECT * FROM data WHERE id = @id";
var cmd = new SqlCommand(sql, myConnection);
cmd.Parameters.AddWithValue("@id", request.getParameter("id"));
私のような名前に ' が含まれている場合。すべての '-文字が削除されたり、無効としてマークされたりするのは非常に面倒です。
このStackoverflow question about SQL Injectionsも参照してください。
パラメーター化されたインライン SQL またはパラメーター化されたストアド プロシージャは、自分自身を保護する最善の方法です。他の人が指摘したように、単一引用符文字を単純に削除/エスケープするだけでは不十分です。
特に「パラメータ化された」ストアド プロシージャについて話していることに気付くでしょう。ストアド プロシージャを単に使用するだけでは、プロシージャの渡されたパラメータを連結することに戻る場合も十分ではありません。つまり、まったく同じ脆弱な SQL ステートメントをストアド プロシージャにラップしても、安全性が向上するわけではありません。インライン SQL の場合と同様に、ストアド プロシージャでパラメーターを使用する必要があります。
これは比較的古い質問なので、完全で包括的な回答を書くことはしません。その回答のほとんどの側面が、ここで何らかのポスターによって言及されているからです。
ただし、ここでは誰も触れていない別の問題、SQL密輸を提起する必要があると思います。特定の状況では、引用符を削除しようとしても、引用符をクエリに「密輸」することができます。実際、これは、適切なコマンド、パラメーター、ストアード・プロシージャーなどを使用した場合でも可能である可能性があります。
http://www.comsecglobal.com/FrameWork/Upload/SQL_Smuggling.pdf(開示、私はこれに関する主要な研究者でした)または単にグーグル「SQL密輸」で完全な研究論文をチェックしてください。
. . . ええと、約50000000の他の方法
多分何か5; drop table employees; --
結果の sql は次のようになります。
select * from somewhere where number = 5; drop table employees; -- and sadfsf
(--
コメントを開始します)
また、アポストロフィを探すだけでも、削除したくありません。あなたはそれを逃れたい。これを行うには、すべてのアポストロフィを 2 つのアポストロフィに置き換えます。
しかし、パラメーター化されたクエリ/ストアド プロシージャははるかに優れています。
はい、もちろんです。SQL の方言などによっては、アポストロフィを使用しないインジェクションを実現する方法がたくさんあります。
SQL インジェクション攻撃に対する唯一の信頼できる防御策は、データベース インターフェイスによって提供されるパラメーター化された SQL ステートメントのサポートを使用することです。
除外する文字を見つけようとするのではなく、代わりにパラメーター化されたクエリに固執し、問題を完全に取り除きます。
私は他の人が言ったことを繰り返すことができるだけです。パラメータ化されたSQLがその方法です。確かに、それをコーディングするのは少し面倒ですが、一度実行すると、そのコードをカットアンドペーストして、必要な変更を加えることは難しくありません。Webサイトの訪問者が検索条件の全範囲を指定できるようにする多くの.Netアプリケーションがあり、コードはその場でSQL Selectステートメントを作成しますが、ユーザーが入力できた可能性のあるものはすべてパラメーターに入力されます。
数値パラメーターを想定している場合は、常に入力を検証して数値であることを確認する必要があります。インジェクションから保護するだけでなく、検証ステップによってアプリがよりユーザーフレンドリーになります。
id = 1044 を予期していたときに id = "hello" を受け取った場合は、データベースにエラーを返させるのではなく、ユーザーに有用なエラーを返す方が常に優れています。
クエリをどのようにまとめるかによって異なりますが、本質的にはそうです。
たとえば、Java でこれを行う場合 (意図的に悪質な例):
String query = "SELECT name_ from Customer WHERE ID = " + request.getParameter("id");
その場合、インジェクション攻撃にさらされる可能性が高くなります。
Java には、PreparedStatements ("SELECT name_ from Customer WHERE ID = ?" のような文字列を渡すと、JDBC レイヤーが ? トークンを置き換えながらエスケープを処理する) など、これらから保護するための便利なツールがいくつかありますが、他の言語もあります。これにはあまり役に立ちません。
Thing はアポストロフィのおそらく本物の入力であり、コードでインライン SQL を使用している場合は、それらを 2 倍にしてエスケープする必要があります。探しているのは、次のような正規表現パターンです。
\;.*--\
正規のステートメントを早期に終了するためにセミコロンが使用され、元の正規のステートメントから末尾の SQL をコメントアウトするために、SQL が挿入され、その後に 2 つのハイフンが続きます。攻撃ではハイフンを省略できます。
したがって、答えは次のとおりです。いいえ、単純にアポストロフィを削除しても、SQL インジェクションからの安全は保証されません。