質問

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 ステートメントに整数が必要なフォームがある場合は、同様のものを入力できます。

選択 * から thingy WHERE 属性ID=

  • 5 (良い答え、問題なし)
  • 5;DROPテーブル users;(悪い、悪い、悪い...)

次の Web サイトでは、古典的な SQL インジェクション技術について詳しく説明しています。 SQL インジェクションのチートシート.

パラメーター化されたクエリやストアド プロシージャを使用することは、それほど良いことではありません。これらは渡されたパラメータを使用した事前に作成されたクエリであり、同様にインジェクションのソースになる可能性があります。このページでも説明されています: SQL のストアド プロシージャを攻撃する.

ここで、単純な引用符を抑制すると、特定の一連の攻撃のみが防止されます。しかし、それらすべてではありません。

いつものことですが、外部から来るデータは信用しないでください。次の 3 つのレベルでフィルタリングします。

  • 明らかなもののインターフェイス レベル (フリー テキスト フィールドよりもドロップダウン選択リストの方が優れています)
  • データの性質 (int、string、length)、権限 (このページでこのユーザーがこのタイプのデータを使用できるか) に関連するチェックの論理レベル...
  • データベースのアクセス レベル (単純な引用符をエスケープします...)。

楽しんでチェックを忘れないでください ウィキペディア 答えのために。

/ヴェイ

独自の 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"));

私のような名前に ' が含まれている場合。すべての '-文字が削除されたり、無効としてマークされたりするのは非常に迷惑です。

こちらもご覧になるとよいでしょう SQL インジェクションに関する Stackoverflow の質問.

パラメータ化されたインライン SQL またはパラメータ化されたストアド プロシージャは、身を守るための最良の方法です。他の人が指摘しているように、単一引用符を単に削除/エスケープするだけでは十分ではありません。

特に「パラメータ化された」ストアド プロシージャについて説明していることに気づくでしょう。プロシージャに渡されたパラメータを連結する方法に戻った場合も、単にストアド プロシージャを使用するだけでは十分ではありません。つまり、まったく同じ脆弱な SQL ステートメントをストアド プロシージャにラップしても、安全性はまったく向上しません。インライン SQL の場合と同様に、ストアド プロシージャでパラメータを使用する必要があります。

また、アポストロフィを探すだけであっても、それを削除する必要はありません。あなたはしたい 逃げる それ。これを行うには、すべてのアポストロフィを 2 つのアポストロフィに置き換えます。

ただし、パラメーター化されたクエリ/ストアド プロシージャの方がはるかに優れています。

これは比較的古い質問であるため、回答のほとんどの側面が投稿者によってここで言及されているため、完全かつ包括的な回答をわざわざ書くつもりはありません。
ただし、ここでは誰も触れていない別の問題、SQL 密輸について取り上げる必要があると思います。特定の状況では、引用符文字 ' をクエリに「密輸」する可能性があります。 たとえそれを取り除こうとしても. 。実際、適切なコマンド、パラメータ、ストアド プロシージャなどを使用した場合でも、これが可能になる可能性があります。

研究論文の全文は次の URL でご覧ください。 http://www.comsecglobal.com/FrameWork/Upload/SQL_Smuggling.pdf (開示しますが、私はこの問題の主な研究者でした) あるいは、Google で「SQL Smuggling」を検索してください。

. 。。。うーん、他の方法は約 50000000 通り

たぶん次のようなもの 5; drop table employees; --

結果の SQL は次のようになります。select * from somewhere where number = 5; drop table employees; -- and sadfsf

(-- コメントを開始します)

そのとおり:SQL 言語などに応じて、アポストロフィを使用せずにインジェクションを実現する方法がたくさんあります。

SQL インジェクション攻撃に対する唯一の信頼できる防御方法は、データベース インターフェイスが提供するパラメータ化された SQL ステートメントのサポートを使用することです。

どの文字を除外するかを考えるのではなく、代わりにパラメータ化されたクエリに固執し、問題を完全に取り除くことにします。

クエリをどのように組み立てるかによって異なりますが、本質的にはそうです。

たとえば、Java でこれを実行するとします (意図的にひどい例です)。

 String query = "SELECT name_ from Customer WHERE ID = " + request.getParameter("id");

その場合、注射攻撃にさらされる可能性が高くなります。

Java には、PreparedStatements (「SELECT name_ from Customer WHERE ID = ?」のような文字列を渡すと、JDBC レイヤーが ? を置き換える際にエスケープを処理します) など、これらを防ぐための便利なツールがいくつかあります。ただし、他の言語の中にはこれにはあまり役に立たないものもあります。

これはアポストロフィのおそらく本物の入力であり、コード内でインライン SQL を使用している場合は、それらを 2 倍にしてエスケープする必要があります。探しているのは次のような正規表現パターンです。

\;.*--\

セミコロンは本物のステートメントを途中で終了するために使用され、一部の挿入された SQL の後に二重ハイフンが続き、元の本物のステートメントから末尾の SQL をコメントアウトします。攻撃ではハイフンを省略できます。

したがって、答えは次のようになります。いいえ、アポストロフィを削除するだけでは SQL インジェクションからの安全性が保証されません。

私は他の人が言ったことを繰り返すことしかできません。パラメータ化された SQL が最適な方法です。確かに、コーディングするのは少し面倒ですが、一度コーディングしてしまえば、そのコードをカット アンド ペーストして必要な変更を加えるのは難しくありません。Web サイト訪問者があらゆる範囲の検索条件を指定できる .Net アプリケーションが多数あり、コードはその場で SQL Select ステートメントを構築しますが、ユーザーが入力できるものはすべてパラメーターに入ります。

数値パラメーターが必要な場合は、常に入力を検証して数値であることを確認する必要があります。インジェクションから保護するだけでなく、検証ステップによりアプリがよりユーザーフレンドリーになります。

id = 1044 を期待したときに id = "hello" を受け取った場合は、データベースにエラーを返させるのではなく、有用なエラーをユーザーに返す方が常に適切です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top