Antywzór: użyj kwantyfikatorów zachłannych w zasadzie RegularExpressionProtection

Przeglądasz dokumentację Apigee Edge.
Otwórz dokumentację Apigee X.
Informacje

Zasada RegularExpressionProtection definiuje wyrażenia regularne oceniane w czasie działania pod kątem parametrów wejściowych lub zmiennych przepływu. Ta zasada służy zwykle do ochrony przed zagrożeniami związanymi z treścią, takimi jak wstrzyknięcie kodu SQL lub JavaScript, oraz sprawdzanie przed nieprawidłowymi parametrami żądania, takimi jak adresy e-mail czy adresy URL.

Wyrażenia regularne można definiować dla ścieżek żądań, parametrów zapytań, parametrów formularzy, nagłówków, elementów XML (w ładunku XML zdefiniowanych za pomocą XPath) oraz atrybutów obiektów JSON (w ładunku JSON zdefiniowanego za pomocą JSONPath).

Poniższa przykładowa zasada RegularExpressionProtection chroni backend przed atakami polegającymi na wstrzyknięciu kodu 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>

Antywzór

Domyślne kwantyfikatory (*, + i ?) są z natury zachłanne – zaczynają się dopasowywać do najdłuższej możliwej sekwencji. Jeśli nie uda się dopasować żadnych wartości, próby znaleźć dopasowanie stopniowo, Jeśli wynikowy ciąg pasujący do wzorca jest bardzo krótki, użycie zachłannych kwantyfikatorów może zająć więcej czasu, niż jest to konieczne. Jest to szczególnie ważne, jeśli ładunek jest duży (w dziesiątkach lub setkach KB).

To przykładowe wyrażenie zawiera wiele wystąpień .*, które są operatorami zachłannymi:

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

W tym przykładzie zasada RegularExpressionProtection próbuje najpierw dopasować najdłuższą możliwą sekwencję, czyli cały ciąg. Jeśli nie uda się znaleźć dopasowania, zasada stopniowo się cofa. Jeśli pasujący ciąg znaków znajduje się na początku lub w środku ładunku, użycie zachłannego kwantyfikatora, takiego jak .*, może zająć o wiele więcej czasu i mocy obliczeniowej niż w przypadku niechętnych kwalifikatorów, takich jak .*?, lub (rzadziej) z kwantyfikatorów Posiadanych, takich jak .*+.

Kwantyfikatory oporne (takie jak X*?, X+?, X??) zaczynają od próby dopasowania pojedynczego znaku od początku ładunku i stopniowego dodawania znaków. Kwantyfikatory dodatnie (takie jak X?+, X*+, X++) próbują dopasować cały ładunek tylko raz.

Biorąc pod uwagę ten przykładowy tekst dla powyższego wzorca:

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

W tym przypadku użycie zachłannego parametru .* nie zadziała. Dopasowanie wzorca .*Exception in thread.* wymaga 141 kroków. Jeśli zamiast tego użyjesz wzorca .*?Exception in thread.* (który używa kwantyfikatora niestabilnego), otrzymamy tylko 55 kroków.

Wpływ

Stosowanie kwantyfikatorów zachłannych, takich jak symbole wieloznaczne (*), w zasadach RegularExpressionProtection może prowadzić do:

  • Zwiększenie ogólnego czasu oczekiwania na żądania do interfejsu API w przypadku umiarkowanego ładunku (do 1 MB)
  • Dłuższy czas wykonania zasady RegularExpressionProtection
  • Żądania API z dużymi ładunkami (>1 MB) kończą się niepowodzeniem z błędem 504 przekroczenia limitu czasu bramy, jeśli w routerze brzegowym upłynie wstępnie zdefiniowany okres oczekiwania
  • Wysokie wykorzystanie procesora przez procesory wiadomości ze względu na dużą ilość przetwarzania, co może mieć nadal wpływ na inne żądania do interfejsu API

Sprawdzona metoda

  • Unikaj używania zachłannych kwantyfikatorów, takich jak .*, w wyrażeniach regularnych, używając zasady RegularExpressionProtection. W miarę możliwości zamiast tego używaj niechętnych kwantyfikatorów, takich jak .*?, lub kwantyfikatorów Posiadanych, takich jak .*+ (rzadziej).

Więcej informacji