Conexiones de usuario con base de datos agotada conduce a DoS

3

Quiero pedirle aclaraciones y consejos sobre la siguiente situación que surgió durante una prueba de penetración de la tienda de comercio electrónico de mi cliente.

Mi cliente está utilizando un software de tienda xt: commerce en combinación con un MariaDB. Durante un descubrimiento inicial automatizado de posibles vulnerabilidades de SQLi y XSS, el middleware que informa sobre varios errores (servidor web, PHP y errores de base de datos) repentinamente arrojó varios errores de que se excedió el número máximo de conexiones de usuario permitidas:

(HY000/1203): User xyz already has more than 'max_user_connections' active connections.

Posteriormente, se generaron mensajes de error similares:

exception 'Exception' with message 'Unable to connect to database server!'
Error-Nr.: 1045 Access denied for user 'abc'@'localhost' (using password: NO)

Efectivamente, para los visitantes de la página ya no era posible navegar por los artículos o comprarlos, ya que nadie podía conectarse a la base de datos utilizando el usuario estándar.

La pregunta era, por qué internamente la base de datos mantenía algunas conexiones abiertas. Parecía que algunos trabajos no terminaban. Después de algunas investigaciones más, encontramos que el 99% de las conexiones abiertas relacionadas con este usuario en particular se encontraban en un estado de zombie con el estado Waiting for table flush . Inmediatamente, pensé que el cliente estaba usando un script de copia de seguridad no reportado que ejecutaría algún tipo de ANALYZE TABLE según lo informado aquí , que desafortunadamente se asoció con la prueba de penetración. Y de hecho, hubo un trabajo de CRON no reportado haciendo precisamente esto. Sin embargo, encontramos que este trabajo no se ejecutó en este momento y, por lo tanto, podría ser la causa del comportamiento.

Entonces, mi primera pregunta es: ¿Cuál podría ser la razón que llevó a esta situación de bloqueo, que solo se pudo resolver reiniciando el servicio de la base de datos?

En segundo lugar, durante una segunda fase, que no involucró pruebas de SQLi en absoluto, sino durante las cuales se probaron diferentes vectores XSS contra un script potencialmente vulnerable de manera automática, nuevamente vimos que se agotó el número máximo de conexiones de usuarios. Esto efectivamente es un DoS contra la base de datos que hace que no esté disponible para usuarios legítimos del sitio web. Verificamos las entradas de configuración de la base de datos relacionadas y se ajustaron de la siguiente manera:

max_connections=250
max_user_connections=30

A medida que los usuarios legítimos se conectan a través de PHP utilizando el mismo usuario de base de datos, hay 30 conexiones disponibles.

Entonces, mi segunda pregunta es: ¿Cómo puede mitigar ataques DoS fáciles contra la base de datos, donde simplemente agota la conexión disponible mediante la ejecución de numerosas consultas SQL (es decir, al consultar repetidamente un formulario de búsqueda)? Un enfoque ingenuo sería establecer max_user_connections=0 . Sin embargo, habrá una compensación y tengo un mal presentimiento al respecto. Por un lado, te liberas del cuello de la botella de conexiones limitadas. Sin embargo, los recursos de DB se enfatizarán mucho más. ¿Existe una forma más inteligente de evitar una situación similar a DoS y, al mismo tiempo, mantener un uso razonable de los recursos de DB?

P.S .: Sí, nunca realice una prueba con lápiz activa / agresiva en un sistema en vivo. El cliente explícitamente le pidió (le rogó) que lo hiciera de todas formas, sin importar cuánto le dijera que esta es una muy mala idea.

    
pregunta user1192748 06.04.2018 - 09:18
fuente

2 respuestas

0

Espero que dimensione su sistema de base de datos para que pueda atender tantas solicitudes paralelas como su sistema general debería permitir. Si cada solicitud genera una nueva conexión de base de datos (que en sí misma podría verse como un defecto de diseño), 30 parece muy bajo. ¿Realmente has probado la sobrecarga de una conexión zombie y el tiempo que tarda el servidor de la base de datos en cerrarla? Mi sospecha es que estás luchando contra fantasmas aquí, y puedes usar fácilmente un orden de magnitud más conexiones.

No conozco su aplicación web, pero a menudo encontrará algo como N trabajadores de servicio, cada uno de los cuales mantiene una conexión persistente con la base de datos (que por lo tanto solo necesita aceptar conexiones N), y estos trabajadores dividen las sesiones de usuario "bastante" entre ellos. No creo que PHP se preste a diseños de servicios de red tan "sanos", pero, de nuevo, siempre me he sentido predispuesto contra PHP.

    
respondido por el Marcus Müller 06.04.2018 - 16:11
fuente
0

Lo mejor en lo que podría pensar es arreglar la aplicación y el entorno para que funcione correctamente y cierre todas las conexiones DB después de su uso. Y si CronJob se ejecuta algún tiempo y no cierra, es Connections, esto también podría ser un problema.

    
respondido por el Serverfrog 06.04.2018 - 10:00
fuente

Lea otras preguntas en las etiquetas