stringtranslate.com

Rehacer

Una denegación de servicio de expresión regular ( ReDoS ) [1] es un ataque de complejidad algorítmica que produce una denegación de servicio al proporcionar una expresión regular y/o una entrada que tarda mucho tiempo en evaluarse. El ataque aprovecha el hecho de que muchas [2] implementaciones de expresiones regulares tienen una complejidad superlineal en el peor de los casos ; en ciertos pares de entradas y expresiones regulares, el tiempo necesario puede crecer polinomial o exponencialmente en relación con el tamaño de entrada. Por lo tanto, un atacante puede hacer que un programa dedique mucho tiempo proporcionando una expresión regular o una entrada especialmente diseñada. Entonces el programa se ralentizará o dejará de responder. [3] [4]

Descripción

La coincidencia de expresiones regulares ("regex") se puede realizar construyendo un autómata de estados finitos . Las expresiones regulares se pueden convertir fácilmente en autómatas no deterministas (NFA), en los que para cada estado y símbolo de entrada, puede haber varios estados siguientes posibles. Una vez construido el autómata existen varias posibilidades:

De los algoritmos anteriores, los dos primeros son problemáticos. La primera es problemática porque un autómata determinista podría tener hasta estados donde es el número de estados en el autómata no determinista; por lo tanto, la conversión de NFA a DFA puede llevar un tiempo exponencial . El segundo es problemático porque un autómata no determinista podría tener un número exponencial de caminos de longitud , de modo que recorrer una entrada de longitud también tomará un tiempo exponencial. [7] Los dos últimos algoritmos, sin embargo, no exhiben un comportamiento patológico.

Tenga en cuenta que para expresiones regulares no patológicas, los algoritmos problemáticos suelen ser rápidos y, en la práctica, se puede esperar que " compilen " una expresión regular en tiempo O(m) y la igualen en tiempo O(n); en cambio, la simulación de un NFA y el cálculo diferido del DFA tienen una complejidad de O (m 2 n) en el peor de los casos. [a] La denegación de servicio de expresiones regulares ocurre cuando estas expectativas se aplican a una expresión regular proporcionada por el usuario, y las expresiones regulares maliciosas proporcionadas por el usuario desencadenan la complejidad del peor de los casos del comparador de expresiones regulares.

Si bien los algoritmos de expresiones regulares se pueden escribir de manera eficiente, la mayoría de los motores de expresiones regulares que existen amplían los lenguajes de expresiones regulares con construcciones adicionales que no siempre se pueden resolver de manera eficiente. Estos patrones extendidos esencialmente obligan a la implementación de expresiones regulares en la mayoría de los lenguajes de programación a utilizar el retroceso.

Ejemplos

Retroceso exponencial

El tipo de problema más grave ocurre con el retroceso de coincidencias de expresiones regulares, donde algunos patrones tienen un tiempo de ejecución exponencial en la longitud de la cadena de entrada. [8] Para cadenas de caracteres, el tiempo de ejecución es . Esto sucede cuando una expresión regular tiene tres propiedades:

La segunda condición se explica mejor con dos ejemplos:

En ambos ejemplos utilizamos $para hacer coincidir el final de la cadena, cumpliendo la tercera condición, pero también es posible usar otro carácter para esto. Por ejemplo (a|aa)*ctiene la misma estructura problemática.

Las tres expresiones regulares anteriores exhibirán un tiempo de ejecución exponencial cuando se apliquen a cadenas de la forma . Por ejemplo, si intenta compararlos con un motor de expresión de retroceso, tardará mucho en completarse y el tiempo de ejecución se duplicará aproximadamente para cada archivo adicional antes del archivo .aaaaaaaaaaaaaaaaaaaaaaaa!a!

También es posible retroceder, que es en tiempo polinómico , en lugar de exponencial. Esto también puede causar problemas durante entradas de tiempo suficiente, aunque se ha prestado menos atención a este problema ya que las entradas maliciosas deben durar mucho más tiempo para tener un efecto significativo. Un ejemplo de tal patrón es " ", cuando la entrada es una secuencia arbitrariamente larga de " ".a*b?a*xa

Regexes vulnerables en repositorios en línea

Se han encontrado expresiones regulares llamadas "malvadas" o vulnerables en repositorios de expresiones regulares en línea. Tenga en cuenta que es suficiente encontrar una subexpresión vulnerable para atacar la expresión regular completa:

  1. RegExLib, id=1757 (validación de correo electrónico) - ver parte roja
    ^([a-zA-Z0-9])(([\-.]|[_]+)?([a-zA-Z0-9]+))*(@){1}[a-z0-9]+[.]{1}(([a-z]{2,3})|([a-z]{2,3}[.]{1}[a-z]{2,3}))$
  2. Repositorio de expresiones regulares de validación de OWASP, nombre de clase de Java: consulte la parte roja
    ^(([a-z])+.)+[A-Z]([a-z])+$

Estos dos ejemplos también son susceptibles a la entrada aaaaaaaaaaaaaaaaaaaaaaaa!.

Ataques

Si la propia expresión regular se ve afectada por la entrada del usuario, como un servicio web que permite a los clientes proporcionar un patrón de búsqueda, entonces un atacante puede inyectar una expresión regular maliciosa para consumir los recursos del servidor. Por lo tanto, en la mayoría de los casos, la denegación de servicio mediante expresiones regulares se puede evitar eliminando la posibilidad de que el usuario ejecute patrones arbitrarios en el servidor. En este caso, las aplicaciones web y las bases de datos son las principales aplicaciones vulnerables. Alternativamente, una página maliciosa podría bloquear el navegador web del usuario o hacer que utilice cantidades arbitrarias de memoria.

Sin embargo, si ya existe una expresión regular vulnerable en el lado del servidor, entonces un atacante puede proporcionar una entrada que desencadene su peor comportamiento. En este caso, los escáneres de correo electrónico y los sistemas de detección de intrusiones también podrían ser vulnerables.

En el caso de una aplicación web, el programador puede utilizar la misma expresión regular para validar la entrada tanto en el lado cliente como en el servidor del sistema. Un atacante podría inspeccionar el código del cliente, buscar expresiones regulares malignas y enviar información manipulada directamente al servidor web para bloquearlo. [9]

Mitigación

ReDoS se puede mitigar sin cambios en el motor de expresiones regulares, simplemente estableciendo un límite de tiempo para la ejecución de expresiones regulares cuando se trata de entradas que no son de confianza. [10]

ReDoS se puede evitar por completo utilizando una implementación de expresión regular no vulnerable. Después de que un PCRE ReDoS derribara el firewall de aplicaciones web (WAF) de CloudFlare en 2019, la compañía reescribió su WAF para usar la biblioteca de expresiones regulares Rust sin retroceso, utilizando un algoritmo similar a RE2 . [11] [12]

Las expresiones regulares vulnerables pueden detectarse mediante programación mediante un linter . [13] Los métodos van desde el análisis estático puro [14] [15] hasta la fuzzing . [16] En la mayoría de los casos, las expresiones regulares problemáticas se pueden reescribir como patrones "no malvados". Por ejemplo, (.*a)+se puede reescribir en ([^a]*a)+. La coincidencia posesiva y la agrupación atómica , que desactivan el retroceso de partes de la expresión, [17] también se pueden utilizar para "pacificar" las partes vulnerables. [18] [19]

Ver también

Referencias

  1. ^ El cálculo diferido del DFA generalmente puede alcanzar la velocidad de los autómatas deterministas manteniendo el peor comportamiento similar a la simulación de un NFA. Sin embargo, es considerablemente más complejo de implementar y puede utilizar más memoria.
  1. ^ OWASP (10 de febrero de 2010). "Denegación de servicio de Regex" . Consultado el 16 de abril de 2010 .
  2. ^ Davis, James; Luis, Miguel; Coghlan, Christy; Siervo, Francisco; Lee, Dongyoon (2019). "¿Por qué las expresiones regulares no son una lengua franca? Un estudio empírico sobre la reutilización y portabilidad de las expresiones regulares" (PDF) . Conferencia y simposio europeo conjunto de ingeniería de software de ACM sobre los fundamentos de la ingeniería de software : 443–454.
  3. ^ Software RiverStar (18 de enero de 2010). "Boletín de seguridad: precaución al utilizar expresiones regulares". Archivado desde el original el 15 de julio de 2011 . Consultado el 16 de abril de 2010 .
  4. ^ Rístico, Ivan (15 de marzo de 2010). Manual de seguridad mod. Londres, Reino Unido: Feisty Duck Ltd. p. 173.ISBN 978-1-907117-02-2. Archivado desde el original el 8 de agosto de 2016 . Consultado el 16 de abril de 2010 .
  5. ^ Crosby y Wallach, Usenix Security (2003). "Denegación de servicio con expresión regular". Archivado desde el original el 1 de marzo de 2005 . Consultado el 13 de enero de 2010 .
  6. ^ Bryan Sullivan, Revista MSDN (3 de mayo de 2010). "Ataques y defensas de denegación de servicio de expresión regular" . Consultado el 6 de mayo de 2010 . {{cite web}}: Enlace externo en |author=( ayuda )Mantenimiento CS1: nombres numéricos: lista de autores ( enlace )
  7. ^ Kirrage, J.; Rathnayake, A.; Thielecke, H. (2013). "Análisis estático para ataques de denegación de servicio de expresiones regulares". Seguridad de redes y sistemas . Madrid, España: Springer. págs. 135-148. arXiv : 1301.0849 . doi :10.1007/978-3-642-38631-2_11.
  8. ^ Jim Manico y Adar Weidman (7 de diciembre de 2009). "Podcast 56 de OWASP (ReDoS)" . Consultado el 2 de abril de 2010 .
  9. ^ Barlas, Efe; Du, Xin; Davis, James (2022). "Explotación de la desinfección de entradas para la denegación de servicio de expresiones regulares" (PDF) . Conferencia internacional ACM/IEEE sobre ingeniería de software : 1–14. arXiv : 2303.01996 .
  10. ^ "Retroceso en expresiones regulares .NET - .NET". aprender.microsoft.com . 11 de agosto de 2023. Cuando utilice System.Text.RegularExpressions para procesar entradas que no sean de confianza, pase un tiempo de espera. Un usuario malintencionado puede proporcionar información a RegularExpressions, provocando un ataque de denegación de servicio. Las API del marco ASP.NET Core que usan RegularExpressions pasan un tiempo de espera.
  11. ^ "Hacer el WAF un 40% más rápido". El blog de Cloudflare . 1 de julio de 2020.
  12. ^ Cox, Russ (2007). "La coincidencia de expresiones regulares puede ser sencilla y rápida" . Consultado el 20 de abril de 2011 .– describe el algoritmo RE2
  13. ^ Véase, por ejemplo, Schmidt, Michael (30 de marzo de 2023). "EjecutarDesarrollo/scslre"., TSUYUSATO, Kitsune. "Vuelva a comprobar la Introducción".y Davis, James. "vuln-regex-detector/src/detect/README.md". GitHub .
  14. ^ H. Thielecke, A. Rathnayake (2013). "Análisis estático de denegación de servicio de expresión regular (ReDoS) Archivado el 3 de agosto de 2014 en Wayback Machine ". Consultado el 30 de mayo de 2013.
  15. ^ B. van der Merwe, N Weideman (2017). "Análisis estático de expresiones regulares". Consultado el 12 de agosto de 2017.
  16. ^ "Difuminación con análisis estático | volver a comprobar". makenowjust-labs.github.io .
  17. ^ "Clases esenciales: Expresiones regulares: Cuantificadores: Diferencias entre cuantificadores codiciosos, reacios y posesivos". Los tutoriales de Java . Oráculo . Archivado desde el original el 7 de octubre de 2020 . Consultado el 23 de diciembre de 2016 .
  18. ^ "compose-regexp.js", coincidencia atómica"". GitHub . 2 de enero de 2024.
    "tc39/propuesta-regexp-operadores-atómicos". ECMA TC39. 31 de diciembre de 2023.
  19. ^ "Prevención de la denegación de servicio de expresiones regulares (ReDoS)". www.expresiones-regulares.info .

enlaces externos