Regla
Proteger contra lento regulares lentas.
Expresiones regulares regulares con anidadas anidados o
ambiguos ambiguos pueden causar catastróficas
retroceso y rendimiento rendimiento.
Idiomas compatibles: 45+Introducción
Las expresiones regulares pueden congelar su aplicación durante segundos o minutos con la entrada correcta. El retroceso catastrófico se produce cuando los motores de expresiones regulares exploran caminos que aumentan exponencialmente al intentar coincidir con un patrón. Una expresión regular como (a+)+b tarda microsegundos en coincidir con una entrada válida, pero puede tardar horas en rechazar una cadena de a's sin una b al final. Los atacantes se aprovechan de esto mediante ataques de denegación de servicio de expresiones regulares (ReDoS), enviando una entrada manipulada que hace que el motor regex consuma el 100% de la CPU hasta que se agota el tiempo de espera de la solicitud o el proceso se bloquea.
Por qué es importante
Implicaciones para la seguridad (ataques ReDoS): Un atacante puede paralizar su aplicación con una sola petición que contenga una entrada manipulada. La validación del correo electrónico y los patrones de análisis de URL son objetivos habituales. A diferencia de los ataques DoS tradicionales que requieren ancho de banda, ReDoS sólo necesita pequeñas cargas útiles.
Disminución del rendimiento: Una entrada normal del usuario puede desencadenar un retroceso catastrófico, haciendo que los tiempos de respuesta aumenten de milisegundos a segundos. Esto crea una latencia impredecible que es difícil de depurar porque solo se manifiesta con patrones de entrada específicos.
Incidentes de producción: Una regex vulnerable bloquea el bucle de eventos en Node.js o consume recursos del grupo de hilos. A medida que se acumulan las peticiones, aumenta la memoria y el sistema deja de responder. En microservicios, una regex vulnerable provoca fallos en cascada en los servicios dependientes.
Dificultad de detección: Los patrones que funcionan bien en pruebas con entradas cortas se vuelven exponencialmente lentos con entradas más largas. La vulnerabilidad suele pasar desapercibida hasta la fase de producción, lo que requiere un despliegue de emergencia durante un incidente activo.
Ejemplos de códigos
❌ No conforme:
function validateEmail(email) {
const regex = /^([a-zA-Z0-9_\-\.]+)+@([a-zA-Z0-9_\-\.]+)+\.([a-zA-Z]{2,5})$/;
return regex.test(email);
}
function extractURLs(text) {
const regex = /(https?:\/\/)?([\w\-])+\.(\w+)+([\w\-\.,@?^=%&:/~\+#]*)+/g;
return text.match(regex);
}
Por qué es inseguro: Los cuantificadores anidados ([a-zA-Z0-9_\\-\\.]+)+ crean un retroceso exponencial. Para un correo electrónico como ¡aaaaaaaaaaaaaaaaaaaa!el motor regex intenta innumerables combinaciones antes de fallar. La expresión regular de la URL tiene varios cuantificadores anidados que agravan el problema, por lo que es trivialmente explotable con entradas como largas cadenas de caracteres válidos sin la estructura esperada.
✅ Conforme:
function validateEmail(email) {
const regex = /^[a-zA-Z0-9_\-\.]+@[a-zA-Z0-9_\-\.]+\.[a-zA-Z]{2,5}$/;
return regex.test(email);
}
function extractURLs(text) {
const regex = /https?:\/\/[\w\-]+\.[\w\-]+(?:[\w\-\.,@?^=%&:/~\+#]*)?/g;
return text.match(regex);
}
Por qué es seguro: La eliminación de cuantificadores anidados elimina el retroceso catastrófico. Los cuantificadores simples como [a-zA-Z0-9_\-\.]+ se ejecutan en tiempo lineal. El patrón URL utiliza grupos no capturadores con sufijo opcional (?:...)? en lugar de la repetición anidada, lo que garantiza un rendimiento predecible independientemente de la longitud o el contenido de la entrada.
Conclusión
El rendimiento de las expresiones regulares es una preocupación de seguridad, no sólo una optimización. Revise todos los patrones regex en busca de cuantificadores anidados, clases de caracteres solapadas en grupos de repetición y alternativas ambiguas. Pruebe los patrones regex con entradas patológicas (cadenas largas de caracteres válidos seguidas de finales no válidos) para identificar retrocesos catastróficos antes de la implantación. Cuando sea posible, sustituya las regex complejas por funciones de análisis sintáctico de cadenas que tengan características de rendimiento predecibles.
.avif)
