反模式:在 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.

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

影響

使用窮盡量詞 (例如萬用字元 *) 搭配 RegularExpressionProtection 政策,可能會導致以下情況:

  • 對於酬載大小適中的 API 要求,整體延遲時間會增加 (最多 1 MB)
  • 執行 RegularExpressionProtection 政策所需的時間較長
  • 如果 Apigee Router 上的預設逾時時間到期,則含有大型酬載 (超過 1MB) 的 API 要求會失敗,並顯示 504 閘道逾時錯誤
  • 訊息處理器的 CPU 使用率偏高,因為大量處理作業可能會進一步影響其他 API 要求

最佳做法

  • 請勿在使用RegularExpressionProtection 政策的規則運算式中使用 .* 等窮盡量詞。請盡可能使用 .*? 等不情願量詞,或 .*+ 等占有量詞 (較不常見)。

延伸閱讀