2010-11-27 16 views
12

Editar: tchrist me ha informado que mis acusaciones originales sobre la inseguridad de Perl son infundadas. Sin embargo, la pregunta sigue en pie.¿En qué idiomas es un agujero de seguridad utilizar la expresión regular proporcionada por el usuario?

Sé que en Perl, puede incrustar código arbitrario en una expresión regular, por lo que aceptar obviamente una expresión regular proporcionada por el usuario y su coincidencia permite la ejecución de código arbitrario y es un claro agujero de seguridad. ¿Pero esto es cierto para todos los idiomas que usan expresiones regulares? ¿Es cierto para todos los idiomas que usan expresiones regulares "compatibles con Perl"? ¿En qué idiomas son confiables las expresiones regulares proporcionadas por el usuario y en qué idiomas permiten la ejecución de código arbitrario u otros agujeros de seguridad?

+3

Sospecho que la respuesta más práctica va a ser "No hagas eso." –

+1

Estoy bastante seguro de que podría usarse como un ataque DoS en la mayoría de los idiomas, recuerdo haber leído algo acerca de cómo los anidados * pueden hacer que la expresión corresponda REALMENTE lenta – Bwmat

+0

"Expresiones regulares compatibles con Perl" es una especie de frase extraña. Dado que Perl puede integrarse en ellos, en realidad no son expresiones regulares (creo que los documentos de Perl los llaman "patrones" o "equivalentes" o algo así), y para ser realmente compatible necesita todo Perl. :-) – Ken

Respuesta

17

En la mayoría de los idiomas, permitir a los usuarios proporcionar expresiones regulares significa que permite un ataque de denegación de servicio.

Algunos tipos de expresiones regulares requieren mucha CPU para su ejecución. Por lo tanto, en general, es una mala idea permitir que los usuarios ingresen expresiones regulares que se ejecutarán en un sistema remoto.

Para obtener más información, lea esta página: expresiones http://www.regular-expressions.info/catastrophic.html

+0

... a menos que lo areneros. – Ken

+2

No puedo estar de acuerdo con la parte "en general es una mala idea permitir que los usuarios ingresen expresiones regulares". Tal vez eso sea cierto para una aplicación web, pero no creo que sea una regla general que se aplique a todo el software. ¿Dónde estaríamos como programadores si nuestras herramientas no nos permitieran usar expresiones regulares para buscar? –

+2

@Bryan Oakley: ¿Cómo sería la seguridad un problema cuando estés usando las herramientas en tu computadora local? Ya estás ejecutando un programa, ejecutar algo de una expresión regular casi no parece ser un problema en este caso. Creo que la pregunta aquí apunta hacia la ejecución remota, en cuyo caso tanto la ejecución del código como los ataques DoS son relevantes. – Wolph

0

AFAIK, puedes hacerlo de forma segura en C#: puedes suministrar la cadena de expresiones regulares al constructor de Regex, y si no lo analiza, lo lanzará. No estoy seguro acerca de los demás.

+3

No hacer un análisis no es un problema de seguridad. Analizar y luego hacer algo malicioso es. –

+0

Es cierto. En casos como ese, depende de para qué se usa la expresión regular. Si es tan simple como hacer coincidir el título de una canción en una máquina de discos, diría que es seguro. Si coincide con una ruta de sistema de archivos arbitraria, tal vez no. – Reinderien

+0

En general, es seguro ejecutar regexes en C#. – Gabe

1

regulares son un lenguaje de programación. No creo que sean completamente completos, pero son lo suficientemente cercanos como para permitir que los usuarios los ingresen en su sitio web, lo que permite que otras personas ejecuten código en su servidor. QED, sí, es un agujero de seguridad.

Es posible que se salga con la suya permitiendo un subconjunto del lenguaje de expresiones regulares que desee usar, incluya en la lista blanca un conjunto particular de construcciones para que no sea un agujero lo suficientemente grande para sudar ... las personas ya han mencionado las posibles defunciones de anidación y *. Lo que está dispuesto a dejar que la gente cargue en su servidor depende de usted. Personalmente, me sentiría cómodo al dejarles tener una declaración SQL "CONTAINS" y tal vez un "BETWEEN()". :)

+2

¿Por qué permitir que * cualquier * código en su servidor sea necesariamente un agujero de seguridad? – Gabe

2

En general, los lenguajes dinámicos con una instalación eval tienden a tener la capacidad de ejecutar código de expresiones regulares. En los lenguajes estáticos (es decir, aquellos que requieren un paso de compilación por separado), generalmente no hay forma de ejecutar el código que no se compiló, por lo que es imposible evaluar el código dentro de una expresión regular.

Sin una forma de incrustar código en una expresión regular, lo peor que puede hacer un usuario es escribir una expresión regular que demora mucho tiempo en evaluarse.

6

Esto no es cierto: no se pueden ejecutar devoluciones de código en Perl escondiéndolos en una expresión regular evaluada. Esto está prohibido. Tiene que reemplazar específicamente que con un ámbito léxico

use re "eval"; 

si esperan tener tanto la interpolación y el código escapa pasando en el mismo patrón.

reloj:

% perl -le '$x = "(?{ die 'naughty' })"; "aaa" =~ /$x/' 
Eval-group not allowed at runtime, use re 'eval' in regex m/(?{ die naughty })/ at -e line 1. 
Exit 255 

% perl -Mre=eval -le '$x = "(?{ die 'naughty' })"; "aaa" =~ /$x/' 
naughty at (re_eval 1) line 1. 
Exit 255 
+0

¿Alguna vez fue la opción predeterminada permitir callbacks de código en expresiones regulares? Recuerdo vagamente haber leído sobre esta posibilidad cuando aprendí Perl, hace casi una década. Pero no puedo recordar si dijo "esto es posible" o "esto está activado por defecto". –

+0

@Ryan, puede haber sido brevemente así. Me parece recordar saltar sobre el tema de seguridad, diciendo que no podíamos liberarlo con este problema, y ​​que el 'use re 'eval'' pragma apareció como la solución. No sé si alguna vez fue lanzado inseguramente. Pero eso fue hace más de diez años, y tendría que revisar el registro de correo p5p para actualizar mi memoria al respecto. – tchrist

+0

¿Hay alguna manera estúpida de que un programador pueda usar 'qr //' para deslizar algún valor proporcionado por el usuario en una expresión regular de modo que eval funcione? – Gabe

1

Sospecho rubí permitiría /#{system("rm -rf really_important_directory")}/ - es que el tipo de cosas que te preocupa?

+0

Sí, eso es más o menos lo que tenía en mente cuando hice la pregunta. Ni siquiera pensé en DoS hasta que las respuestas comenzaron a mencionarlo. –

2

1) Las vulnerabilidades se encuentran en las bibliotecas de expresiones regulares, como esta buffer overflow that affects Webkit y permite a cualquier atacante obtener la ejecución remota de código accediendo a la biblioteca de expresiones regulares desde javascript.

2) It is a DoS condition in C#.

3) adquiridos por el usuario de expresiones regulares pueden ser para php a causa de modificadores. Al agregar el modificador/e se evalúa la coincidencia. En este caso, el sistema será eval() 'ed.

preg_replace("/.*/e","system('echo /etc/passwd')");

o en la forma de una vulnerabilidad:

preg_replace($_GET['regex'],$_GET['check']);

Cuestiones relacionadas