反模式:在 RegularExpressionProtection 政策中使用灰色量詞

您目前查看的是 ApigeeApigee Hybrid 說明文件。
查看 Apigee Edge 說明文件。

RegularExpressionProtection 政策會定義規則運算式,在執行階段評估輸入參數或流程變數。您通常會使用這項政策防範內容威脅,例如 SQL 或 JavaScript 植入,或是檢查電子郵件地址或網址等格式錯誤的要求參數。

您可以為要求路徑、查詢參數、表單參數、標頭、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>

反模式

預設量詞 (*+?) 本質上是貪婪的,會從最長的可能序列開始比對。如果找不到相符項目,他們會逐步回溯,嘗試比對模式。如果符合模式的結果字串很短,使用貪婪量詞可能會花費不必要的時間。如果酬載內容很大 (數十或數百 KB),這種情況就特別明顯。

下列範例運算式使用多個 .* 執行個體,這些都是貪婪運算子:

<Pattern>.*Exception in thread.*</Pattern>

在本例中,RegularExpressionProtection 政策會先嘗試比對最長的可能序列,也就是整個字串。如果找不到相符項目,政策就會逐步回溯。如果相符字串接近酬載的開頭或中間,使用 .* 等貪婪量詞會比使用 .*? 等不情願量詞或 (較少見) .*+ 等佔有量詞,耗費更多時間和處理能力。

不情願量詞 (例如 X*?X+?X??) 會先嘗試從酬載開頭比對單一字元,然後逐步新增字元。占有量詞 (例如 X?+X*+X++) 只會嘗試比對整個酬載一次。

假設上述模式的範例文字如下:

Hello this is a sample text with Exception in thread
with lot of text after the Exception text.

在這種情況下,使用貪婪 .* 的效能不佳。比對這個模式需要 141 個步驟。.*Exception in thread.*如果您改用 .*?Exception in thread.* 模式 (使用不情願量詞),結果只會有 55 個步驟。

影響

RegularExpressionProtection 政策中使用萬用字元 (*) 等窮盡量詞,可能會導致:

  • 中等酬載大小 (最多 1 MB) 的 API 要求整體延遲時間增加
  • 執行 RegularExpressionProtection 政策的時間較長
  • 如果 Apigee Router 上預先定義的逾時期間已過,API 要求 (酬載大於 1MB) 會失敗,並顯示 504 閘道逾時錯誤
  • 大量處理作業導致訊息處理器 CPU 使用率偏高,進而影響其他 API 要求

最佳做法

  • 請勿在規則運算式中使用窮盡量詞 (例如 .*),並搭配 RegularExpressionProtection 政策。請盡可能改用不情願量詞 (如 .*?) 或佔有量詞 (如 .*+,較不常見)。

延伸閱讀