Антишаблон: используйте жадные квантификаторы в политике RegularExpressionProtection.

Вы просматриваете документацию Apigee Edge .
Перейдите к документации Apigee X.
информация

Политика RegularExpressionProtection определяет регулярные выражения, которые оцениваются во время выполнения по входным параметрам или переменным потока. Обычно вы используете эту политику для защиты от угроз контента, таких как внедрение SQL или JavaScript, или для проверки неверных параметров запроса, таких как адреса электронной почты или URL-адреса.

Регулярные выражения могут быть определены для путей запроса, параметров запроса, параметров формы, заголовков, элементов XML (в полезных данных XML, определенных с помощью XPath), атрибутов объекта JSON (в полезных данных JSON, определенных с помощью JSONPath).

Следующий пример политики 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>

Антипаттерн

Кванторы по умолчанию ( * , + и ? ) являются жадными по своей природе: они начинают сопоставляться с самой длинной возможной последовательностью. Если совпадений не найдено, они постепенно возвращаются назад, чтобы попытаться сопоставить шаблон. Если результирующая строка, соответствующая шаблону, очень короткая, то использование жадных квантификаторов может занять больше времени, чем необходимо. Это особенно актуально, если полезная нагрузка велика (десятки или сотни КБ).

В следующем примере выражения используется несколько экземпляров .* , которые являются жадными операторами:

<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 МБ).
  • Больше времени для завершения выполнения политики RegularExpressionProtection.
  • Запросы API с большими полезными нагрузками (> 1 МБ) завершаются с ошибкой 504 Gateway Timeout, если на пограничном маршрутизаторе истекает предопределенный период ожидания.
  • Высокая загрузка ЦП на процессорах сообщений из-за большого объема обработки, что может еще больше повлиять на другие запросы API.

Лучшая практика

  • Избегайте использования жадных квантификаторов, таких как .* в регулярных выражениях с помощью политики RegularExpressionProtection . Вместо этого используйте неохотные квантификаторы, такие как .*? или притяжательные кванторы, такие как .*+ (реже), где это возможно.

Дальнейшее чтение