5

私はプロジェクト (プライベート、ASP.net Web サイト、https で保護されたパスワード) を持っています。要件の 1 つは、ユーザーがデータベースを直接クエリする Sql クエリを入力できることです。これらのクエリがデータベース自体に損害を与えたり、アクセス/更新できないはずのデータにアクセスまたは更新したりしないようにしながら、これらのクエリを許可できる必要があります。

実装のために次のルールを考え出しました。

  1. Select Table/View および Update Table の権限のみを持つdb ユーザーを使用します(したがって、drop/alter/truncate/insert/delete などの他のコマンドは実行されません)。
  2. ステートメントが「Select」または「Update」という単語で始まっていることを確認します
  3. (Regex を使用して) 単一引用符、空白、および文字で囲まれていないステートメントにセミコロンのインスタンスがないことを確認します。(ここで考えられるのは、2 番目のクエリを含めることができる唯一の方法は、入力文字列の一部ではないセミコロンで最初のクエリを終了することであるということです)。
  4. (正規表現を使用して) ユーザーが、クエリ/更新されている、結合に含まれているなどのテーブルにアクセスする権限を持っていることを確認します。これには、サブクエリが含まれます。(これを達成する方法の一部は、ユーザーが実際にはデータベースに存在しないテーブル名のセットを使用することです。クエリ解析の一部は、正しい対応するテーブル名をクエリに代入することです) .

何か不足していますか?

目標は、ユーザーが適切と思われる方法でアクセスできるテーブルをクエリ/更新できるようにし、データベースを損傷する偶発的または悪意のある試みを防ぐことです。(そして、ユーザーがSQLを生成することが要件であるため、クエリをパラメータ化する方法や、私が知っている組み込みツールを使用してサニタイズする方法はありません)。

4

15 に答える 15

16

これは悪い考えであり、注射防止の観点からだけではありません。よくわからないユーザーが、すべてのデータベースリソース(メモリ/ CPU)を占有するクエリを誤って実行し、サービス拒否攻撃を効果的に引き起こすことは非常に簡単です。

これを許可する必要がある場合は、これらのクエリ用に完全に別個のサーバーを維持し、レプリケーションを使用して、本番システムの正確なミラーにかなり近い状態に保つのが最善です。もちろん、それはあなたのUPDATE要件では機能しません。

しかし、もう一度言いたいのですが、これはうまくいきません。ユーザーがアドホッククエリを実行できる場合、データベースを保護することはできません。

于 2009-01-14T19:20:31.677 に答える
4

このようなものはどうですか、選択がEXECであると想像してください

select convert(varchar(50),0x64726F70207461626C652061)
于 2009-01-14T19:09:53.477 に答える
4

私の直観的な反応は、アカウントの権限と付与をできるだけ厳密に設定することに集中する必要があるというものです。RDBMS のセキュリティ ドキュメントをよく調べてください。よく知られていない便利な機能があるかもしれません (たとえば、Oracle の Virtual Private Database は、この種のシナリオで役立つと思います)。

特に、「(正規表現を使用して)ユーザーがクエリ/更新されている、結合などに含まれているテーブルにアクセスする権限を持っていることを確認する」という考え。データベースにすでに組み込まれているセキュリティ機能を再実装しようとしているようです。

于 2009-01-14T19:34:47.140 に答える
3

あなたが見逃しているのは、アプリケーションの穴を見つける攻撃者の創意工夫です。

これを許可すれば、すべての穴を塞ぐことはできないと事実上保証できます。データベース エンジンには、あなたが知らないバグさえあるかもしれませんが、それらは、安全だと思われる SQL ステートメントがシステムに大混乱をもたらすことを可能にします。

要するに、これは途方もなく悪い考えです!

于 2009-01-14T19:37:09.833 に答える
3

ええと、 「これはやめて」と言う人がすでに十分にいるので、彼らがあなたを思いとどまらせることができない場合は、いくつかのアイデアがあります。

良いものを含め、悪いものを除外しようとしないでください(適切な用語は ホワイトリストブラック
リスト だと思います) つまり、捨てるために悪や無効なものを探してはいけません(それを書く方法が多すぎます)または偽装)、代わりに有効なものを探して含め、他のすべてを破棄します。

ユーザーフレンドリーなテーブル名のリストを探していて、実際のスキーマテーブル名に置き換えていることを別のコメントで既に述べました。これが私が話していることです。これを行う場合は、フィールド名も使用してください。

ただし、私はまだある種のグラフィカル UI に傾倒しています。ここで表示するテーブルを選択し、ここで表示するフィールドを選択し、いくつかのドロップダウンを使用して where 句を作成するなどです。面倒ですが、それでもおそらく簡単です。

于 2009-01-14T20:11:52.650 に答える
2

Dynamic LINQ のような一見安全なテクノロジは、コード インジェクションの問題から安全ではなく、低レベルのアクセスを提供することについて話しています。

クエリのサニタイズとパーミッションの調整にどれだけ苦労しても、CPU を集中的に使用するクエリを送信することで DB をフリーズさせる可能性があります。

したがって、「保護オプション」の 1 つは、メッセージ ボックスを表示して、制限されたオブジェクトにアクセスしたり、悪い副作用を引き起こしたりするすべてのクエリがユーザーのアカウントに対してログに記録され、すぐに管理者に報告されることを伝えることです。

別のオプション - より良い代替手段を探してみてください (つまり、本当にデータを処理および更新する必要がある場合は、これを安全に行うために API を公開してみませんか?)

于 2009-01-15T05:01:38.603 に答える
2

他の人が示しているように、エンドユーザーにこれをさせるのは良い考えではありません。要件は、ユーザーがアドホック SQL を実際に必要としているということではなく、当初は予期されていなかった方法でデータを取得および更新する方法であると思われます。クエリを許可するには、Joel の提案に従って "読み取り専用" データベースを保持しますが、Microsoft Reporting Services や Data Dynamics Active レポートなどのレポート アプリケーションを使用して、ユーザーがアドホック レポートを設計および実行できるようにします。どちらも、ユーザーに「自分の」データのフィルター処理されたビューを提示する方法があると思います。

更新の場合は、さらに注意が必要です。これを行うための既存のツールについては知りません。1 つのオプションとして、開発者がプラグインをすばやく記述して、データを更新するための新しいフォームを公開できるように、アプリケーションを設計することが考えられます。プラグインは、UI フォーム、現在のユーザーがそれを実行できることを確認するためのコード、およびそれを実行するためのコードを公開する必要があります。アプリケーションはすべてのプラグインをロードし、ユーザーがアクセスできるフォームを公開します。

于 2009-01-14T19:57:32.773 に答える
1

1 つの (おそらくやり過ぎの) オプションは、削減された SQL 言語にコンパイラを使用することです。SELECT ステートメントのみを許可する変更された SQL 文法で JavaCC を使用するようなもので、クエリを受け取ってコンパイルし、コンパイルされた場合は実行できます。

C# の場合、私はIronyを知っていますが、使用したことはありません。

于 2009-01-14T19:11:33.507 に答える
1

update ステートメントを使用すると、多大な損害を与えることができます。

私はこれに似たプロジェクトを持っていました.私たちの解決策は、非常に面倒なウィザードをユーザーに案内して選択を許可することでしたが、クエリ自体はアプリケーションコードによって舞台裏で構築されています. 作成するのは非常に骨の折れるものでしたが、少なくとも、最終的に実行されるコードを制御できました。

于 2009-01-14T19:30:57.007 に答える
1

問題は、ユーザーを信頼していますか? ユーザーがシステムにログインする必要があり、HTTPS を使用しており、XSS 攻撃に対する予防措置を講じている場合、SQL インジェクションは小さな問題です。正当なユーザーを信頼する場合は、制限されたアカウントでクエリを実行するだけで十分です。何年もの間、Web 上で MyLittleAdmin を実行してきましたが、まだ問題は発生していません。

適切に制限された SQL アカウントの下で実行すると、 select convert(varchar(50),0x64726F70207461626C652061) はそれほど遠くまで到達せず、データベース要求に短いタイムアウトを設定することで、リソースを大量に消費するクエリを防ぐことができます。人々は依然として間違った更新を行う可能性がありますが、それはあなたのユーザーを信頼しているかどうかにかかっています。

データベースを Web に接続するという管理されたリスクを常に負っていますが、それがバックアップの目的です。

于 2009-01-14T19:42:31.710 に答える
0

それは悪い考えだと言っているたくさんの答えが、要件が主張していることです。ただし、「とにかくやらなければならない場合」の提案で言及されていない1つの落とし穴があります。更新ステートメントにWHERE句が含まれていることを確認してください。実行するのはとても簡単です

UPDATE ImportantTable
SET VitalColumn = NULL

重要なものを見逃します

WHERE UserID = @USER_NAME

テーブル全体で更新が必要な場合は、簡単に追加できます。

WHERE 1 = 1

where句を要求しても、悪意のあるユーザーが悪いことをするのを防ぐことはできませんが、テーブル全体の偶発的な変更を減らすことができます。

于 2013-01-15T17:31:25.137 に答える
0

本当に高度なクエリを実行する必要がない場合は、「更新、削除、選択」のドロップダウンリストなど、特定の選択肢のみを許可するUIを提供すると、次のddlに使用可能なテーブルのリストなどが自動的に入力されます。 .SQLManagementStudioのクエリビルダーに似ています。

次に、サーバー側のコードで、これらのui要素のグループをsqlステートメントに変換し、パラメーター化されたクエリを使用して悪意のあるコンテンツを停止します。

于 2009-01-14T19:15:57.663 に答える
0

これはひどく悪い習慣です。より高度なクエリであっても、やりたいことすべてを処理するために、いくつかのストアド プロシージャを作成します。それらをユーザーに提示し、必要なものを選択させ、パラメーターを渡します。

私の上記の答えも非常に良いです。

于 2009-01-14T19:33:27.487 に答える
0

私は Joel Coehoorn と SQLMenace に同意しますが、「要件」を持っている人もいます。アドホック クエリを送信する代わりに、asp.net にある MS サンプル アプリケーションにあるようなビジュアル クエリ ビルダーを作成するか、このリンクを試してみてください。

私は Joel の主張に反対しているわけではありません。彼は正しい。ユーザー (ここではユーザーのことを言っていることを思い出してください。強制したいことをユーザーはあまり気にしない可能性があります) をスローすることは、「ビジネス ロジック レイヤー」のないアプリのようなものです。特定の結果が一致しない場合に回答する追加の質問は言うまでもありませんその他のサポート アプリケーションの結果。

于 2009-01-14T19:50:01.587 に答える
0

ここに別の例があります

ハッカーは実際のテーブル名を知る必要はありません。このような文書化されていないプロシージャを実行できます。

sp_msforeachtable 'print ''?''' 

印刷する代わりにドロップします

于 2009-01-14T20:43:42.273 に答える