Antipatrón: Usa cuantificadores expansivos en la política RegularExpressionProtection

Estás viendo la documentación de Apigee y Apigee Hybrid.
Consulta la documentación de Apigee Edge.

La política RegularExpressionProtection define expresiones regulares que se evalúan en los parámetros de entrada o del entorno de ejecución o en las variables de flujo. En general, se usa esta política para proporcionar protección contra amenazas de contenido como la inserción de código de SQL o JavaScript, o para verificar si hay parámetros de solicitud con formato incorrecto, como direcciones de correo electrónico o URL.

Las expresiones regulares se pueden definir para rutas de solicitud, parámetros de consulta, parámetros de formato, encabezados, elementos XML (en una carga útil de XML definida mediante XPath) y atributos de objetos JSON (en una carga útil JSON definida mediante JSONPath).

En la siguiente política de ejemplo RegularExpressionProtection, se protege el backend de los ataques de inyección de 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>

Antipatrón

Los cuantificadores predeterminados (*, + y ?) son expansivos por naturaleza: comienzan a coincidir con la secuencia más larga posible. Cuando no se encuentra ninguna coincidencia, retroceden gradualmente para hacer coincidir el patrón. Si la string resultante que coincide con el patrón es muy corta, entonces, usar cuantificadores expansivos puede tardar más de lo necesario. Esto es así, especialmente si la carga útil es grande (en decenas o cientos de KB).

En la siguiente expresión de ejemplo, se usan varias instancias de .*, que son operadores voraces:

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

En este ejemplo, la política RegularExpressionProtection primero intenta hacer coincidir la secuencia más larga posible: toda la string. Si no se encuentra ninguna coincidencia, la política busca coincidencias desde el final hacia el inicio de forma gradual. Si la string coincidente está cerca del inicio o en la mitad de la carga útil, usar un cuantificador voraz como .* puede llevar mucho más tiempo y potencia de procesamiento que los calificadores reacios como .*? o (con menos frecuencia) cuantificadores posesivos como .*+.

Los cuantificadores reacios (como X*?, X+? y X??) comienzan a buscar coincidencias a un solo carácter del principio de la carga útil y agregan caracteres de manera gradual. Los cuantificadores posesivos (como X?+, X*+, X++) intentan hacer coincidir la carga útil completa solo una vez.

Dado el siguiente texto de muestra para el patrón anterior, haz lo siguiente:

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

En este caso, el uso de .* voraz no cumple con los requisitos. Al patrón .*Exception in thread.* le toma 141 pasos realizar una coincidencia. Si, en cambio, usaras el patrón .*?Exception in thread.* (que utiliza un cuantificador reacio), el resultado solo tendría 55 pasos.

Impacto

El uso de cuantificadores voraces como comodines (*) con la política RegularExpressionProtection puede generar lo siguiente:

  • Un aumento en la latencia general de las solicitudes a la API para un tamaño de carga útil moderado (de hasta 1 MB)
  • Un tiempo más prolongado para completar la ejecución de la política RegularExpressionProtection
  • Solicitudes a la API con cargas útiles grandes (mayores de 1 MB) que fallan debido a errores 504 en el tiempo de espera de la puerta de enlace si el tiempo de espera predefinido se agota en el router de Apigee
  • El uso elevado de CPU en los procesadores de mensajes debido a la gran cantidad de procesamiento, que puede tener un impacto mayor en otras solicitudes a la API

Práctica recomendada

  • Evita usar cuantificadores voraces como .* en expresiones regulares con la política RegularExpressionProtection. En su lugar, usa cuantificadores reacios como .*? o cuantificadores posesivos como .*+ (menos común) siempre que sea posible.

Lecturas adicionales