3

ユーザー入力から文字列を取得し、それを空白で (\w を使用して) 文字列の配列に分割しています。次に、配列をループして、次のように where 句の一部を追加します。

            query += " AND ( "

                 + "field1 LIKE '%" + searchStrings[i] +"%' "
                 + " OR field2 LIKE '%" + searchStrings[i] +"%' "
                 + " OR field3 LIKE '%" + searchStrings[i] +"%' "
                 + ") ";

ユーザー入力をクエリに追加しているので、これは危険だと思います。ただし、最初の入力を空白で分割したため、どの検索文字列にも空白がないことはわかっています。

これを SQL インジェクションで攻撃することは可能ですか? Robert');DROP TABLE students;--そこには空白が必要なので、与えても実際には何もドロップしません。その例では、適切に動作しませんが、損傷はありません。

SQL インジェクションとの戦いの経験が豊富な人は、これを修正したり、安心したりするのに役立ちますか?

ありがとう!

編集:

うわー、それはたくさんの素晴らしいインプットです。回答してくださった皆様、ありがとうございました。全文検索を調査し、少なくともクエリをパラメーター化します。

問題をよりよく理解できるように、すべての空白と一重引用符がエスケープされている場合、注入することは可能でしょう?

4

7 に答える 7

14

このようなクエリ文字列へのデータの入力をユーザーに許可すると、SQL インジェクションに対して脆弱になるため、疫病のように回避する必要があります。

searchStrings[] 配列への入力を許可する方法には十分注意する必要があります。パラメータ オブジェクトを使用して、常に変数データをクエリに追加する必要があります。

+ field1 like @PropertyVal Or field2 like @PropertyVal Or field3 like @PropertyVal etc...

たとえば、SQL Serverを使用している場合

Query.Parameters.Add(new SqlParameter("PropertyVal", '%' + searchStrings[i] + '%'));

実稼働サーバーに対して実行するクエリ文字列の作成方法には十分注意してください。特に重要なデータが含まれている場合は注意してください。

あなたの例では、Little Bobby Tablesについて言及しました

Robert');DROP TABLEの学生;--

そして、空白が必要なため、それを行うことはできませんでしたが、悪意のあるユーザーが次のようなものを使用してエンコードした場合:

Robert');Exec(Replace('Drop_Table_students','_',Char(32)));--

私は言うでしょう - 安全で正しい方法でそれを行う方が良い. それ以外の場合、すべてのシナリオを確実にキャッチする簡単な方法はありません...

于 2008-12-16T22:16:48.240 に答える
13

はい、このスクリプトには空白は含まれていません。SQL がデコードして実行したエンコードされた文字だけです

挿入されたスクリプトは次のようなものでした。

DECLARE%20@S%20NVARCHAR(4000);SET%20@S=CAST(0x440045004300 4C00410052004500200040005400200076006100720063006800610072 00280032003500350029002C0040004300200076006100720063006800 610072002800320035003500290020004400450043004C004100520045 0020005400610062006C0065005F0043007500720073006F0072002000 43005500520053004F005200200046004F0052002000730065006C0065 0063007400200061002E006E0061006D0065002C0062002E006E006100 6D0065002000660072006F006D0020007300790073006F0062006A0065 00630074007300200061002C0073007900730063006F006C0075006D00 6E00730020006200200077006800650072006500200061002E00690064 003D0062002E0069006400200061006E006400200061002E0078007400 7900700065003D00270075002700200061006E0064002000280062002E 00780074007900700065003D003900390020006F007200200062002E00 780074007900700065003D003300350020006…</p>

にデコードされたSQL:

DECLARE @T varchar(255)'@C varchar(255) DECLARE Table_Cursor
CURSOR FOR select a.name'b.name from sysobjects a'syscolumns b where a.id=b.id and a.xtype='u' and ( b.xtype=99 または b.xtype=35 または b…</p>

など、空白を使用せずに、データベース内のすべてのテーブルで必要なことを行うことができます。

于 2008-12-16T22:17:39.083 に答える
5

これを誤解する方法が多すぎるため、誰かが「いいえ、これは安全です....

なんらかの形式 (URL エンコードまたは何か) で空白をエスケープするのはどうですか。簡単なテストではチェックされない、明白でない Unicode 空白文字の使用についてはどうでしょうか。DB が、空白を必要としない悪意のある操作をサポートしている場合はどうなるでしょうか?

正しい方法を実行してください: PreparedStatement (またはプラットフォームがインジェクションセーフのパラメーター化に使用するもの) を使用し、ユーザー入力に "%" を追加して先頭に追加し、それをパラメーターとして使用します。

于 2008-12-16T22:13:54.317 に答える
2

経験則は次のとおりです。追加する文字列が SQL でない場合は、準備されたステートメントまたは DB クライアント ライブラリの正しい「エスケープ」関数を使用してエスケープする必要があります。

于 2008-12-16T22:20:11.433 に答える
2

クエリ パラメータが絶対的に安全な方法であることに完全に同意します。それらを使用すると、SQL インジェクションのリスクはまったくなく (パラメーターで愚かなことをしない限り)、エスケープのオーバーヘッドもありません。

DBMS がクエリ パラメータをサポートしていない場合は、文字列のエスケープをサポートする必要があります。最悪の場合、一重引用符を自分でエスケープすることもできますが、これを回避できる Unicode エクスプロイトがまだ存在します。ただし、DBMS がクエリ パラメーターをサポートしていない場合は、Unicode もサポートしていない可能性があります。:)

追記:また。あなたが書いたようなクエリには、パフォーマンスのキラーがあります-インデックスは使用できません。DBMS のフルテキスト インデックス作成機能を調べることをお勧めします。これらはまさにこのような場合を対象としています。

于 2008-12-16T22:25:42.250 に答える
1

はい、アイテムを挿入することはできますが、スペースがないとあまり機能しない可能性がありますが、それでも脆弱性があります.

一般に、やみくもにユーザー入力をクエリに追加することはお勧めできません。

于 2008-12-16T22:14:57.810 に答える
1

field1 をこれに設定すると、データベース内のすべての行がリストされます。これはセキュリティに悪いかもしれません...

'+field1+'

パラメータを使用する必要があります (これらはインライン SQL でも有効です)。

AND Field1 = @Field1
于 2008-12-16T22:19:48.703 に答える