公開Webページに正規表現検索機能を追加したい。出力をHTMLエンコードする以外に、悪意のあるユーザー入力を防ぐために何かする必要がありますか?
Googleの検索は、逆の問題を解決する人々-正規表現を使用して悪意のある入力を検出-には興味がありません。私のシナリオでは、ユーザー入力は正規表現です。
.NET(C#)のRegexライブラリを使用します。
公開Webページに正規表現検索機能を追加したい。出力をHTMLエンコードする以外に、悪意のあるユーザー入力を防ぐために何かする必要がありますか?
Googleの検索は、逆の問題を解決する人々-正規表現を使用して悪意のある入力を検出-には興味がありません。私のシナリオでは、ユーザー入力は正規表現です。
.NET(C#)のRegexライブラリを使用します。
回答:
正規表現に関する最も一般的な懸念は、指数関数的、または超指数関数的になる病理学的パターンによるサービス拒否攻撃です。—そして、解決するのに永遠にかかるようです。これらは特定の入力データでのみ表示される場合がありますが、一般的にはこれを問題としないデータを作成できます。
これらのどれがコンパイル時に検出される可能性があるため、これらがどれであるかは、使用している正規表現コンパイラがどれほど賢いかに依存します。再帰を実装するRegexコンパイラには通常、非進行をチェックするための組み込みの再帰深さカウンタがあります。
正規表現マッチングに関するRuss Coxの優れた2007年の論文は、単純で高速である可能性があります(ただし、Java、Perl、PHP、Python、Rubyなどでは遅い)は、ほとんどすべての最新のNFAがHenry Spencerのコードから派生しているように見える方法について述べています、パフォーマンスが大幅に低下しますが、トンプソンスタイルのNFAにはそのような問題はありません。
DFAで解決できるパターンのみを認める場合は、そのようにしてそれらをコンパイルすることができ、パターンはより高速に、場合によってはより高速に実行されます。ただし、これには時間がかかります。コックス紙はこのアプローチとそれに付随する問題について言及しています。それはすべて、古典的な時間と空間のトレードオフに帰着します。
DFAを使用すると、DFAの作成(およびより多くの状態の割り当て)に多くの時間を費やしますが、NFAを使用すると、DFAを同時に複数の状態にすることができるため、実行に多くの時間を費やします。
おそらく、宇宙の熱死でレースの敗北にあるこれらのパターンに対処する最も合理的な方法は、実行に許可される最大時間を効果的に配置するタイマーでそれらをラップすることです。通常、これはほとんどのHTTPサーバーが提供するデフォルトのタイムアウトよりもはるかに小さくなります。
これらの実装にはさまざまな方法がありalarm(N)
、Cレベルでの単純なものから、何らかの種類のtry {}
ブロックによるアラームタイプの例外のキャッチまで、タイミング制約が組み込まれた特別に作成された新しいスレッドを生成するすべての方法があります。
コードコールアウトを許可する正規表現言語では、コンパイルする文字列に対してこれらを許可または禁止するためのメカニズムを提供する必要があります。コードコールアウトが使用している言語のコードのみである場合でも、それらを制限する必要があります。外部コードを呼び出すことができる必要はありませんが、可能であれば、はるかに大きな問題が発生します。
たとえば、Perl use re "eval";
では、現在のスコープでアクティブな特別な字句スコーププラグマがない限り、文字列補間から作成された正規表現にコードコールアウトを含めることはできません(実行時にコンパイルされるため)。
このようrm -rf *
にして、たとえばのようなシステムプログラムを実行するためのコードコールアウトに誰も忍び込むことはできません。コードコールアウトはセキュリティに非常に敏感であるため、Perlはすべての補間された文字列でデフォルトでそれらを無効にし、それらを再度有効にするために邪魔をする必要があります。
以下のような-そこのUnicodeスタイルのプロパティに関連する1つ以上のセキュリティに敏感な問題が残っている\pM
、\p{Pd}
、\p{Pattern_Syntax}
、または\p{Script=Greek}
その- もサポートしていることを表記することを、いくつかの正規表現のコンパイラに存在します。
問題は、これらのいくつかでは、可能なプロパティのセットがユーザー拡張可能であることです。あなたには、いくつかの特定のnamepaceで名前の関数に実際のコードのコールアウトされているカスタムプロパティを持つことができる手段、のようなもの\p{GoodChars}
か\p{Class::Good_Characters}
。あなたの言語がそれらをどのように扱うかは、一見の価値があるかもしれません。
Perlでは、Safe
モジュールを介してサンドボックス化されたコンパートメントにより、名前空間の可視性を制御できます。他の言語も同様のサンドボックステクノロジーを提供しています。そのようなデバイスが利用可能な場合は、信頼できないコードの実行を制限するように特別に設計されているため、それらを調べることをお勧めします。
はい。
正規表現を使用して、DOS攻撃を実行できます。
簡単な解決策はありません。
あなたはこの論文を読みたくなるでしょう:
安全でないコンテキスト切り替え:生存可能性 のための正規表現の接種このペーパーでは、正規表現エンジン(PCREなど)で問題が発生する可能性について詳しく説明していますが、問題の理解に役立つ場合があります。
あなたはマッチング自体についてだけでなく、どのようにマッチングを行うかについて心配する必要があります。たとえば、入力が正規表現エンジンに向かう途中で何らかの評価フェーズまたはコマンド置換を通過する場合、パターン内で実行されるコードが存在する可能性があります。または、正規表現構文で埋め込みコマンドが許可されている場合は、それにも注意する必要があります。質問で言語を指定しなかったので、すべてのセキュリティへの影響が何であるかを確認するのは難しいです。
RegExのセキュリティ問題(少なくともWindowsの場合)をテストする良い方法は、Microsoftが最近リリースしたSDL RegExファジングツールです。これは、病理学的に悪いRegEx構造を回避するのに役立ちます。