RegularExpressionProtection ポリシーは正規表現を定義します。正規表現は、ランタイム時に入力パラメータまたはフロー変数に対して評価されます。このポリシーは通常、コンテンツに対する脅威(SQL インジェクション、JavaScript インジェクションなど)からの保護、あるいは不正な形式のリクエスト パラメータ(メールアドレス、URL など)のチェックに使用されます。
正規表現を定義する場所として、リクエストパス、クエリ パラメータ、フォーム パラメータ、ヘッダー、XML 要素(XPath を使用して定義された XML ペイロード内)、JSON オブジェクト属性(JSONPath を使用して定義された JSON ペイロード内)が可能です。
次に、RegularExpressionProtection ポリシーを使用して、SQL インジェクション攻撃からバックエンドを保護する例を示します。
<!-- /antipatterns/examples/greedy-1.xml --> <RegularExpressionProtection async="false" continueOnError="false" enabled="true" name="RegexProtection"> <DisplayName>RegexProtection</DisplayName> <Properties/> <Source>request</Source> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> <QueryParam name="query"> <Pattern>[\s]*(?i)((delete)|(exec)|(drop\s*table)| (insert)|(shutdown)|(update)|(\bor\b))</Pattern> </QueryParam> </RegularExpressionProtection>
アンチパターン
デフォルトの数量氏子(*
、+
、?
)は、「欲張り(greedy)」な性質を持ちます。つまり最初から、可能な限り最長の文字列を一致させようとします。一致する文字が見つからなければ、徐々にバックトラックを行い、パターン一致を試みます。結果的にパターンに一致する文字列が極端に短い場合は、欲張りな数量子を使用することで、必要以上に長い処理時間がかかる可能性があります。これは、大きなペイロード(数十 KB、数百 KB の規模)であればなおさらです。
次の正規表現の例では、欲張りな演算子 .*
のインスタンスをいくつか使用します。
<Pattern>.*Exception in thread.*</Pattern>
この例では、RegularExpressionProtection ポリシーは最初に、可能な限り最長の文字列(文字列全体)を一致させようとします。一致する文字が見つからなければ、徐々にバックトラックを行います。一致文字列がペイロードの先頭または中心に近い位置にある場合は、欲張りな数量子(.*
など)を使用することで、「無欲(reluctant)」な数量子(.*?
など)、または、あまり一般的ではないながら「独占的(possessive)」な数量子(.*+
など)を使用する場合に比べ、より多くの処理時間と処理能力を費やす可能性があります。
無欲な数量子(X*?
、X+?
、X??
など)は、ペイロードの先頭から 1 文字ずつ一致を試み、徐々に文字を追加していきます。無欲な数量子(X?+
、X*+
、X++
など)は、ペイロード全体の一致を一度だけ試行します。
上述のパターンを、次のサンプル テキストに適用するとします。
Hello this is a sample text with Exception in thread with lot of text after the Exception text.
この場合は、欲張りな .*
の使用は効率が悪すぎます。.*Exception in thread.*
パターンは、一致までのステップ数が 141 となります。代わりに、無欲な数量子を使う .*?Exception in thread.*
パターンを使用すると、ステップ数はわずか 55 で済みます。
影響
RegularExpressionProtection ポリシーで、ワイルドカード(*
)などの欲張りな数量子を使用すると、次の結果が生じる可能性があります。
- あまり大きくないペイロード サイズ(最大 1 MB)の場合、API リクエスト全体のレイテンシが大きくなります。
- RegularExpressionProtection ポリシーの実行完了までの時間が長くなります。
- ペイロードの大きな(1 MB 超)API リクエストの場合、Edge Router で事前定義したタイムアウト時間が経過すると、504 ゲートウェイ タイムアウト エラーが生じ、リクエストが失敗します。
- 処理量が大きいため、Message Processor の CPU 使用率も高くなり、他の API リクエストにまで影響が及ぶ可能性があります。
ベスト プラクティス
- RegularExpressionProtection ポリシーで正規表現を使用する場合は、
.*
などの欲張りな数量子の使用を避けます。代わりに、可能であれば無欲な数量子(.*?
など)や独占的な数量子(.*+
など - あまり一般的ではない)を使用します。