La decadencia de las expresiones regulares

Vicepresidente de Producto, Seguridad, Fastly
«Algunas personas, cuando se enfrentan a un problema, piensan “ya sé, usaré expresiones regulares”. Ahora tienen dos problemas» – Jamie Zawinski
Las expresiones regulares son una forma concisa de describir cómo identificar patrones o secuencias de tokens, generalmente texto. Cabe preguntarse, no obstante, si comparar cadenas de texto resulta efectivo para detectar malware o ataques a aplicaciones web. si hilamos más fino, para qué tipos de ataques a aplicaciones web conviene utilizar expresiones regulares. Al fin y al cabo, no queremos arriesgarnos a mantener el statu quo y seguir utilizando métodos ineficaces que pueden poner en peligro la seguridad.
Las expresiones regulares resultan útiles para las tareas de copiar y pegar que tanto gustan a los atacantes novatos, cuando el atacante no entiende cómo funciona el ataque porque alguien lo ha creado para él. El «atacante novato» (es decir, amateur) simplemente lo operacionaliza y merodea por internet usando una herramienta como Shodan. Sin embargo, las expresiones regulares no sirven para cosas más complejas.
Quienes crean los fragmentos reutilizables de un ataque saben que pueden adaptarlos para eludir un mecanismo tan sencillo como la comprobación de coincidencia de patrones en la que se basan las expresiones regulares. De hecho, la secuencia precisa de los tokens no es realmente tan significativa, sino la expresión completa de esos tokens lo que importa.
Lo que importa es el comportamiento del ataque: cómo se despliegan las acciones a lo largo del espacio-tiempo. Más que una descripción de un ataque, los fragmentos de texto ofrecen detalles acerca de su implementación.
A modo de analogía, imaginemos que alguien utiliza un destornillador para retirar un televisor de la pared. ¿Es necesario saber si es plano o de estrella? Igual somos nosotros quienes lo hemos utilizado para ajustar la altura del televisor, no un ladrón con la intención de llevárselo. Pero si la ventana del salón está destrozada y luego alguien arranca el televisor de la pared, ese comportamiento rezuma malicia.
Lo que queremos decir con esto es que un patrón de texto tiene un significado distinto y produce unos resultados u otros dependiendo del entorno. El contexto lo es todo. No es lo mismo aprovecharse de la descripción textual de una inyección de código SQL (SQLi) en la entrada de un blog que lanzar un ataque por SQLi contra quien aloja dicho blog. El patrón de texto que representa el tipo de ataque está presente en ambos casos, pero solo uno de ellos se puede considerar un ataque como tal.
Esto no significa que las expresiones regulares sean inútiles siempre y en todo lugar. Las expresiones regulares son representaciones eficientes para la comprobación de coincidencia de patrones: son idiomáticas y relativamente legibles. El problema reside en la comprobación de coincidencia de patrones, ya que los tokens encargados de ella, como el texto de los parámetros de consulta y los campos POST del cuerpo, solo detectan los ataques más rudimentarios. Lo mismo ocurre fuera del ámbito de las aplicaciones web; una expresión regular para un hash de archivo específico supone que el atacante está tan desmotivado y descuidado como para renunciar al esfuerzo de transfigurar el archivo para eludir una detección tan simple. Puede que sea así, pero no ocurre en la mayoría de los casos.
Más allá de la precisión, la realidad es que las expresiones regulares pueden obstaculizar la protección. Muchas de ellas son inflexibles, poco manejables y difíciles de mantener, sobre todo cuando intentas añadir más contexto. Por ejemplo, intentar capturar una lista de comandos válidos de Linux o Windows para detectar la inyección de comandos sería ilegible o directamente imposible de hacer bien con expresiones regulares, y lo mismo ocurre con la SQLi. El patrón resultante sería ilegible para una persona, lo cual no es sostenible (incluso si construyes gramáticas de expresiones regulares).
Considera esta expresión regular «simple» para validar direcciones de correo electrónico:
(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])
Sencilla, ¿verdad? Esperamos que no te hayas dejado los ojos intentando descifrar este jeroglífico.

Fuente de imagen
Seguir el ritmo a las técnicas y los patrones de ataque, ya sean nuevos o cambiantes, requiere tiempo, esfuerzo y mucha cafeína, razón por la cual la solución se acaba actualizando cada vez menos y pierde eficacia. Trabajar con expresiones regulares es un proceso lento al que se le deben dedicar muchos recursos, sobre todo si son complejas y, por tanto, difíciles de optimizar. La inversión en términos de trabajo y rendimiento que exige la detección de ataques mediante expresiones regulares no se suele amortizar.
Las expresiones regulares tienen sus cosas buenas, pero la detección de ataques no es una de ellas. Muchos proveedores no quieren que sus clientes se enteren porque mantener la tecnología existente sale mucho más barato que innovar. El problema es que las expresiones regulares no intimidan a los atacantes ni suponen un mayor coste para ellos.
Algunas técnicas, como el análisis de peticiones HTTP, son una inversión más segura, ya que permiten a los equipos de seguridad añadir más contexto para aplicar la comprobación de coincidencia de patrones a los comportamientos maliciosos y, ya de paso, reducir la carga de trabajo de humanos y máquinas. La disección del comportamiento de ataque permitirá detectar tanto los ataques rudimentarios como los más complejos, así como cualquier variante de ellos, sin necesidad de una nueva regla para cada nueva vulnerabilidad que surja (lo cual es frecuente). Si nos fijamos en el contexto de un ataque y la forma en que se procesa una petición en tiempo de ejecución, podemos tomar decisiones más acertadas que con las expresiones regulares.
Así, llegamos a la distorsión del mercado actual: las listas de verificación de los compradores de seguridad aún incluyen la «coincidencia de expresiones regulares» como una capacidad clave en sus productos de seguridad para aplicaciones web (y a menudo en otros productos, como las reglas YARA en herramientas de punto final) a pesar de su insuficiencia. En su momento tenía sentido, sobre todo cuando la mayoría de los productos de los proveedores utilizaban expresiones regulares y no había nada mejor, pero ahora vivimos en otro mundo.
Mejor seguridad sin expresiones regulares. Aprende cómo las señales de Fastly te dan mejor visibilidad para la toma de decisiones.
Toma las riendas y actualiza tus listas
Imagina la siguiente escena con fines ilustrativos: un cliente entra en un concesionario de coches y pregunta si el coche tiene viseras.
«No», responde el vendedor, confundido «No necesitas anteojeras en un coche.» El cliente tuerce el morro y le enseña su lista de requisitos.
—¿Y una fusta? —le pregunta.
"Tampoco necesitas látigos de carruaje. «Ya no hacemos azotes.»
—¡Ahora me dirá que tampoco viene con riendas y bridas! —espeta el cliente.
"Eso es correcto. «Es un coche.» El vendedor se pellizca el puente de la nariz con un suspiro y pregunta: «¿Qué necesitas lograr exactamente?»
—Algo que me lleve del punto A al punto B lo más rápido posible —explica el cliente con total convicción.
“Claro, un coche es mucho mejor para eso que un carruaje de caballos Está diseñado de esta manera por una razón. «Es innovación para mejorar tu vida.»
—¡Usted dirá lo que quiera, pero a mí me faltan muchas cosas! —concluye el cliente.
Este ejemplo es totalmente absurdo, pero guarda cierto parecido con algunas de las conversaciones que se oyen en el mundo de la ciberseguridad. Cuando vamos a comprar algo, es perfectamente comprensible que nos ciñamos a una lista de cosas que ya conocemos. Preguntar por estribos, riendas y bridas tiene todo el sentido del mundo si buscamos un coche de caballos. No obstante, estas listas invariables por naturaleza nos pueden llevar por el camino de la obsolescencia.
Nos quejamos mucho de que los atacantes sean cada vez más rápidos y certeros, pero a veces elegimos productos con tecnologías ancladas en el pasado. Los atacantes manejan multitud de opciones y pueden elegir las herramientas adecuadas para alcanzar sus objetivos, así que nosotros debemos hacer lo mismo como responsables de la seguridad. Conviene tener en cuenta técnicas más modernas y de eficacia probada, como el análisis de los parámetros de las peticiones y la observación de los resultados en tiempo de ejecución, para disfrutar de más velocidad, precisión y flexibilidad.
No es fácil asumir que nuestras soluciones a un problema son incorrectas o están anticuadas y que la realidad ha evolucionado más rápido que nuestra percepción de ella, sobre todo después de apostar una cantidad ingente de recursos a un caballo perdedor. pero esa reticencia a cambiar y replantearse las cosas es nuestro punto más débil. Si queremos ganar la carrera a los atacantes, debemos dejar atrás las expresiones regulares y adentrarnos en la nueva era de la detección.
Descubre cómo Fastly ayuda a los defensores a ir más allá de las expresiones regulares mediante el análisis. Consulta nuestra hoja de datos sobre la detección de SmartParse o nuestro blog sobre cómo utilizamos el análisis para el ataque Log4Shell. O solicita una demostración – nos encantaría mostrarte cómo funciona.