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

您正在查看 Apigee Edge 說明文件。
查看 Apigee X 說明文件
資訊

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

您可以針對要求路徑、查詢參數、表單參數、標頭、XML 元素 (在使用 XPath 定義的 XML 酬載中)、JSON 物件屬性 (使用 JSONPath 定義的 JSON 酬載) 定義規則運算式。

以下的 regexProtection 政策範例可以保護後端不受 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.

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

影響程度

將萬用字元 (*) 等管制量詞與 RegularExpressionProtection 政策搭配使用,可能會導致:

  • 中等酬載大小的 API 要求整體延遲時間增加 (最多 1 MB)
  • 完成 regexProtection 政策的執行時間較長
  • 如果在邊緣路由器發生預先定義的逾時時間,含有大量酬載 (超過 1 MB) 的 API 要求會失敗,並顯示 504 閘道逾時錯誤
  • 由於處理量龐大,訊息處理器的 CPU 使用率偏高,進一步影響其他 API 要求

最佳做法

  • 避免在規則運算式中使用 RegularExpressionProtection 政策,使用如 .* 等管制量詞。請盡可能改用不相關的量詞 (例如 .*?) 或正面的量詞,例如 .*+ (較少使用)。

其他資訊