Quiero agregar la capacidad de búsqueda de expresiones regulares a mi página web pública. Además de la codificación HTML de la salida, ¿debo hacer algo para protegerme de las entradas maliciosas de los usuarios?
Las búsquedas en Google están inundadas por personas que resuelven el problema inverso, usando expresiones regulares para detectar entradas maliciosas, lo que no me interesa. En mi escenario, la entrada del usuario es una expresión regular.
Voy a usar la expresión regular de la biblioteca en .NET (C #).
Respuestas:
Problemas de denegación de servicio
La preocupación más común con las expresiones regulares es un ataque de denegación de servicio a través de patrones patológicos que se vuelven exponenciales, ¡o incluso súper exponenciales! - y parece que tardan una eternidad en resolverse. Estos solo pueden aparecer en datos de entrada particulares, pero generalmente se puede crear uno en el que esto no importa.
Cuáles serán estos dependerán en cierta medida de cuán inteligente sea el compilador de expresiones regulares que está utilizando, porque algunos de estos pueden detectarse durante el tiempo de compilación. Los compiladores de expresiones regulares que implementan la recursividad generalmente tienen un contador de profundidad de recursión incorporado para verificar la no progresión.
El excelente artículo de 2007 de Russ Cox sobre la coincidencia de expresiones regulares puede ser simple y rápido (pero es lento en Java, Perl, PHP, Python, Ruby, ...) habla sobre las formas en que la mayoría de los NFA modernos, que parecen derivar del código de Henry Spencer , sufren una severa degradación del rendimiento, pero donde un NFA de estilo Thompson no tiene tales problemas.
Si solo admite patrones que los DFA pueden resolver, puede compilarlos como tales y se ejecutarán más rápido, posiblemente mucho más rápido. Sin embargo, lleva tiempo hacer esto. El documento de Cox menciona este enfoque y sus problemas relacionados. Todo se reduce a una clásica compensación tiempo-espacio.
Con un DFA, pasas más tiempo construyéndolo (y asignando más estados), mientras que con un NFA pasas más tiempo ejecutándolo, ya que pueden ser múltiples estados al mismo tiempo, y el retroceso puede comer tu almuerzo y tu CPU.
Soluciones de denegación de servicio
Probablemente, la forma más razonable de abordar estos patrones que están en el extremo perdedor de una carrera con la muerte por calor del universo es envolverlos con un temporizador que coloque efectivamente la cantidad máxima de tiempo permitido para su ejecución. Por lo general, esto será mucho, mucho menos que el tiempo de espera predeterminado que proporcionan la mayoría de los servidores HTTP.
Hay varias formas de implementar esto, desde un simple
alarm(N)
nivel C hastatry {}
bloquear algunas excepciones de tipo alarma de captura, hasta generar un nuevo hilo especialmente creado con una restricción de tiempo incorporada.Código de llamadas
En lenguajes de expresiones regulares que admiten llamadas de código, algún mecanismo para permitir o impedir éstos de la cadena que se va a compilar debe ser proporcionada. Incluso si las llamadas de código son solo para codificar en el idioma que está utilizando, debe restringirlas; no tienen que poder llamar a código externo, aunque si pueden, tienes problemas mucho mayores.
Por ejemplo, en Perl no se pueden tener códigos de llamadas en expresiones regulares creadas a partir de la interpolación de cadenas (como serían, ya que se compilan durante el tiempo de ejecución) a menos que el pragma especial de ámbito léxico esté
use re "eval";
activo en el ámbito actual.De esa manera, nadie puede colarse en una llamada de código para ejecutar programas del sistema como
rm -rf *
, por ejemplo. Debido a que las llamadas de código son tan sensibles a la seguridad, Perl las deshabilita de manera predeterminada en todas las cadenas interpoladas, y tiene que hacer todo lo posible para volver a habilitarlas.Definido por el usuario \ P {propiedades}
Sigue existiendo una cuestión más sensible a la seguridad relacionados con las propiedades de estilo Unicode - como
\pM
,\p{Pd}
,\p{Pattern_Syntax}
, o\p{Script=Greek}
- que puede existir en algunos compiladores de expresiones regulares que el apoyo que la notación.El problema es que en algunos de estos, el conjunto de propiedades posibles es extensible por el usuario. Eso significa que puede tener propiedades personalizadas que son llamadas de código reales a funciones con nombre en algún espacio de nombre en particular, como
\p{GoodChars}
o\p{Class::Good_Characters}
. Merece la pena mirar cómo maneja su idioma.Sandboxing
En Perl, un compartimento de espacio aislado a través del
Safe
módulo daría control sobre la visibilidad del espacio de nombres. Otros idiomas ofrecen tecnologías de sandboxing similares. Si tales dispositivos están disponibles, es posible que desee examinarlos, porque están diseñados específicamente para la ejecución limitada de código no confiable.fuente
Además de la excelente respuesta de tchrist: ¡el mismo Russ Cox que escribió la página "Expresión regular" también ha publicado un código! re2 es una biblioteca de C ++ que garantiza el tiempo de ejecución de O (length_of_regex) y el límite de uso de memoria configurable. Se usa dentro de Google para que pueda escribir una expresión regular en la búsqueda de código de Google, lo que significa que ha sido probada en batalla.
fuente
Si.
Las expresiones regulares se pueden utilizar para realizar ataques de DOS .
No hay una solución simple.
fuente
Querrás leer este artículo:
Cambio de contexto inseguro: inoculación de expresiones regulares para la supervivencia El documento trata más sobre lo que puede salir mal con los motores de expresión regular (por ejemplo, PCRE), pero puede ayudarlo a comprender a qué se enfrenta.
fuente
No solo debe preocuparse por la coincidencia en sí misma, sino también por cómo hacerla. Por ejemplo, si su entrada pasa por algún tipo de fase de evaluación o sustitución de comando en su camino hacia el motor de expresión regular, podría haber código que se ejecute dentro del patrón. O, si su sintaxis de expresión regular permite comandos incrustados, también debe tener cuidado con eso. Como no especificó el idioma en su pregunta, es difícil decir con certeza cuáles son todas las implicaciones de seguridad.
fuente
Una buena forma de probar sus RegEx's por problemas de seguridad (al menos para Windows) es la herramienta de fuzzing SDL RegEx lanzada recientemente por Microsoft. Esto puede ayudar a evitar una construcción RegEx patológicamente mala.
fuente