En mysql, ¿"explicar ..." siempre es seguro?

Si permito que un grupo de usuarios envíe "explain $whatever" a mysql (a través de DBI de Perl usando DBD::mysql), ¿hay algo que un usuario pueda poner en $ lo que sea que haga cambios en la base de datos, filtre información no trivial o incluso cause una carga significativa en la base de datos? ¿Si es así, cómo?

Lo sé a través de "explain $whatever" uno puede averiguar qué tablas / columnas existen (tiene que adivinar nombres) y aproximadamente cuántos registros hay en una tabla o cuántos registros tienen un valor particular para un campo indexado. No espero que uno pueda obtener información sobre el contenido de los campos no indexados.

DBD::mysql no debería permitir múltiples declaraciones, por lo que no espero que sea posible ejecutar ninguna consulta (solo explique una consulta). Incluso las subconsultas no deben ejecutarse, solo se explica.

Pero no soy un experto en mysql y seguramente hay características de mysql que ni siquiera conozco.

Al tratar de crear un plan de consulta, ¿podría el optimizador ejecutar una expresión para obtener el valor con el que se comparará un campo indexado?

explain select * from atable where class = somefunction(...)

dónde atable.class está indexado y no es único y class='unused' no encontraría registros pero class='common' encontraría un millón de registros. Podría 'explicar' evaluar somefunction(...)? Y luego podria somefunction(...) estar escrito de manera que modifique los datos?

preguntado el 09 de enero de 11 a las 08:01

Probablemente sea seguro, pero yo no lo haría de todos modos;) Cualquiera que tenga una razón para estar jugando con explain debe recibir una copia de prueba de la base de datos y la CLI de mysql. Cualquiera que no necesite una base de datos de prueba debe evitar escribir consultas y, por lo tanto, no necesita explain ;) -

3 Respuestas

"Explicar" puede tardar un tiempo arbitrariamente largo en ejecutarse y utilizar una cantidad arbitraria de recursos del servidor, incluso provocar que se bloquee si se agotan algunas cosas (por ejemplo, un desbordamiento de pila causado por demasiadas subconsultas anidadas).

"Explicar" puede agotar fácilmente el espacio de disco temporal, el espacio de direcciones del servidor (en sistemas de 32 bits, la memoria virtual en sistemas de 64 bits) o la pila de subprocesos (para consultas construidas deliberadamente de forma maliciosa).

En general, no puede permitir que usuarios que no son de confianza envíen ninguna parte de SQL. Incluso sin acceso a una sola tabla, es probable que aún puedan bloquear el servidor si se esfuerzan lo suficiente.


EDITAR: más información

Una consulta que utiliza una vista anónima / subconsulta materializada, a menudo ejecuta toda la consulta interna en EXPLAIN, en una tabla temporal.

Entonces consultas de la forma

SELECT * FROM (
  SELECT h1.*, h2.* FROM huge_table h1, huge_table h2) AS rediculous

llevará una eternidad explicar y consumir el espacio en disco en tmpdir.

Respondido el 11 de enero de 11 a las 10:01

¿Puede proporcionar más información? ¿Qué tipo de explicación podría tomar un tiempo arbitrariamente largo o agotar el espacio en disco o la memoria temporal? - ysth

Gracias. Esa es una buena idea. Suena como algo que podría limitarse de alguna manera tan simplemente como limitar el tamaño total del texto después de "explicar". Por lo menos, I no se puede llegar a una consulta SQL que crece en complejidad para explicar como O (n!) o incluso O (n ** 2) frente a la longitud del texto de la consulta. - teñir

Parece que esto también se puede usar para filtrar datos: construya una subconsulta que revele información en forma de la cantidad de elementos devueltos. - bdonlan

@bdonian Explicar da el número aproximado de filas de todos modos incluso para explicaciones "rápidas" (por ejemplo, uniones simples) - MarkR

Pude usar 'explicar' para obtener un recuento preciso de filas que coinciden con consultas precisas. Entonces uno podría usar

explain select * from user where name='tye' and secret like '%a%'

para determinar rápidamente las letras de cualquier "secreto" y luego pasar a determinar el orden de las letras, revelando finalmente el valor de "secreto".

Respondido el 11 de enero de 11 a las 10:01

Si desea que los usuarios puedan conectarse a la base de datos pero no cambiarla, debe hacer cumplir eso usando privilegios de usuario; si solo tienen privilegios SELECT, no deberían poder cambiar nada.

Respondido el 09 de enero de 11 a las 18:01

Gracias. Ese es un excelente consejo. Agregar un usuario de solo lectura y usarlo al hacer "explicar" elimina por completo el riesgo principal (las personas descubren cómo realizar actualizaciones a través de "explicar"). - teñir

El sistema de permisos evitará que las personas cambien los datos, pero sin bloquear el servidor o causar la denegación de servicio, vea mi respuesta. - MarkR

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.