現在、Apigee と Apigee ハイブリッドのドキュメントを表示しています。
Apigee Edge のドキュメントを表示する
RegularExpressionProtection ポリシーは、実行時に入力パラメータまたはフロー変数に対して評価される正規表現を定義します。このポリシーは通常、コンテンツに対する脅威(SQL インジェクション、JavaScript インジェクションなど)からの保護や、不正な形式のリクエスト パラメータ(メールアドレス、URL など)のチェックに使用されます。
正規表現を定義する対象として、リクエストパス、クエリ パラメータ、フォーム パラメータ、ヘッダー、XML 要素(XPath を使用して定義された XML ペイロード内)、JSON オブジェクト属性(JSONPath を使用して定義された JSON ペイロード内)を設定できます。
次に、SQL インジェクション攻撃からバックエンドを保護する RegularExpressionProtection ポリシーの例を示します。
<!-- /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++
など)は、ペイロード全体の一致を 1 度だけ試行します。
上述のパターンを、次のサンプル テキストに適用するとします。
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 リクエストの場合、Apigee ルーターで事前定義したタイムアウト時間が経過すると、504 ゲートウェイ タイムアウト エラーが発生してリクエストが失敗する。
- 処理量が大きいため、Message Processor の CPU 使用率も高くなり、他の API リクエストにまで影響が及ぶ可能性がある。
ベスト プラクティス
- RegularExpressionProtection ポリシーで正規表現を使用する場合、
.*
などの欲張りな数量子の使用を避けます。代わりに、可能な限り、.*?
などの無欲な数量子や.*+
などの独占的な数量子(あまり一般的ではない)を使用します。