Protección de la entrada del usuario de expresiones regulares contra ataques

9

Soy consciente de la Denegación de servicio de expresión regular (ReDoS). ¿Hay alguna forma razonable de permitir a los usuarios crear expresiones regulares personalizadas y garantizar que no presenten un patrón exponencialmente lento?

icirellik
fuente
Te faltan detalles. Plataforma, uso, etc.
whatsisname
8
En lugar de tratar de evitar que el usuario envíe una expresión regular incorrecta, ¿tal vez una solución en la que, después de un cierto período de tiempo, cancele la ejecución?
Samuel

Respuestas:

8

El problema con las expresiones regulares no es la expresión regular en sí misma, sino que es el motor de expresión regular que tiene todo tipo de características "convenientes" como retroceder. Por lo tanto, el uso de un motor regex sin estas características evita.

Expresiones regulares el concepto de informática siempre puede coincidir en tiempo lineal después de que se compilan en una máquina de estados finitos. Por lo tanto, un motor de expresiones regulares basado en máquinas de estado no se puede utilizar para ReDoS. Sin embargo, las máquinas de estado necesarias pueden volverse bastante grandes en ejemplos patológicos. Pero limitar la memoria disponible tiende a ser más fácil que limitar el tiempo de cálculo disponible.

El motor RE2 se desarrolló específicamente para tratar expresiones regulares no confiables y se diseñó para la ejecución en tiempo lineal.

Otra alternativa es ensamblar las expresiones regulares usted mismo a partir de una notación simplificada. Por ejemplo, puede permitir que los usuarios usen patrones globales (como *.txt). Luego puede analizarlo de una manera que evite el retroceso, por ejemplo, al no permitir el anidamiento y solo usando cuantificadores codiciosos. Para muchos casos de uso, una notación de patrón simplificada es completamente suficiente.

amon
fuente
11

Analizar una expresión regular para ver si será lenta o no, sin que el análisis se vuelva lento , equivale a resolver el problema de detención. En otras palabras, no es posible encontrar una solución correcta y completa.

Puede, por supuesto, encontrar una solución que es correcto y en completa. Por ejemplo, podría trabajar con una lista blanca restrictiva de características que son seguras de usar (por ejemplo, clases de caracteres sí, repetición no ...). Esto le permitiría pasar muchas expresiones regulares no críticas, rechazar todas las críticas y (erróneamente) rechazar algunas que estén bien, pero que sean demasiado complicadas para demostrar que son seguras automáticamente.

Kilian Foth
fuente
3
¿Tiene una cita para su primera declaración? Me interesaría ver tal prueba. Las expresiones regulares no son completas de Turing, por lo que el problema de detención puede no aplicarse.
Sebastian Redl
3
@SebastianRedl Es cierto que, estrictamente hablando, las expresiones regulares no son completas de Turing, pero todas las bibliotecas de expresiones regulares de uso popular tienen extensiones que las hacen no más regulares. Restringir a sus usuarios a expresiones literalmente regulares podría, de hecho, ser una buena solución para esta situación.
Kilian Foth
2
@KilianFoth: IIRC, incluso las expresiones regulares verdaderas (en el sentido CompSci de la palabra) pueden requerir una cantidad exponencial de retroceso. Pero como no están completos de Turing, para cualquier expresión regular teóricamente es posible establecer este límite superior. Sin embargo, esto deja abiertos dos problemas: determinar el límite superior automáticamente es una tarea no trivial, y el resultado puede dar resultados irrazonablemente altos (como en un límite superior mucho más alto que el tiempo esperado ).
MSalters
@msalters cualquier expresión regular verdadera es mecánicamente convertible a un autómata determinista de estado finito, es decir, siempre es posible hacer coincidir la expresión sin retroceder en absoluto. Su FSA puede ser excesivamente grande, por supuesto, pero eso sugiere que un límite para el número de estados en la FSA generada es una solución suficiente para prevenir el ataque en cuestión.
Jules
1

Como autor del analizador para el proyecto Lazarus , diría que no hay formas de comprender para una expresión regular determinada qué recursos consumirá en un texto dado.

Sin gastar los mismos recursos, quiero decir (al menos en el significado de O grande).

Entonces, el mejor enfoque: ejecutar el analizador en un hilo separado y eliminarlo después del tiempo de espera.

ANDgineer
fuente
0

Además de las otras respuestas, una solución también puede ser rodar su propia biblioteca de expresiones regulares, que permite la instrumentación de rendimiento durante la ejecución y, por lo tanto, proporciona los medios para matar la ejecución a la mitad si se cumplen algunos criterios.

Del mismo modo, puede ejecutar las expresiones regulares en otro hilo y matar los hilos si tardan demasiado.

whatsisname
fuente