English 中文(简体)
In mysql, is "explain ..." always safe?
原标题:

If I allow a group of users to submit "explain $whatever" to mysql (via Perl s DBI using DBD::mysql), is there anything that a user could put into $whatever that would make any database changes, leak non-trivial information, or even cause significant database load? If so, how?

I know that via "explain $whatever" one can figure out what tables / columns exist (you have to guess names, though) and roughly how many records are in a table or how many records have a particular value for an indexed field. I don t expect one to be able to get any information about the contents of unindexed fields.

DBD::mysql should not allow multiple statements so I don t expect it to be possible to run any query (just explain one query). Even subqueries should not be executed, just explained.

But I m not a mysql expert and there are surely features of mysql that I m not even aware of.

In trying to come up with a query plan, might the optimizer actual execute an expression in order to come up with the value that an indexed field is going to be compared against?

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

where atable.class is indexed and not unique and class= unused would find no records but class= common would find a million records. Might explain evaluate somefunction(...)? And then could somefunction(...) be written such that it modifies data?

最佳回答

"Explain" can take an arbitrarily long time to execute, and use an arbitrary amount of server resources, including causing it to crash if some things are exhausted (for example, a stack overflow caused by too many nested subqueries).

"Explain" can easily exhaust temporary disc space, server address space (on 32-bit systems, virtual memory on 64-bit systems) or the thread stack (for queries constructed deliberately maliciously).

In general, you cannot allow entirely untrusted users to submit any part of any SQL at all. Even without access to a single table, they can probably still crash the server if they try hard enough.


EDIT: further info

A query which uses an anonymous view / materialised subquery, often executes the entire inner query upon EXPLAIN, into a temporary table.

So queries of the form

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

will take forever to explain and consume the disc space in tmpdir.

问题回答

I was able to use explain to get an accurate count of rows matching precise queries. So one could use

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

to quickly determine the letters of whatever secret and then move on to determining the order of the letters, eventually revealing the value of secret .

If you want users to be able to connect to the database but not changing it, you should enforce that using user privileges-- if they only have SELECT privileges, they should not be able to change anything.





相关问题
SQL SubQuery getting particular column

I noticed that there were some threads with similar questions, and I did look through them but did not really get a convincing answer. Here s my question: The subquery below returns a Table with 3 ...

please can anyone check this while loop and if condition

<?php $con=mysql_connect("localhost","mts","mts"); if(!con) { die( unable to connect . mysql_error()); } mysql_select_db("mts",$con); /* date_default_timezone_set ("Asia/Calcutta"); $date = ...

php return a specific row from query

Is it possible in php to return a specific row of data from a mysql query? None of the fetch statements that I ve found return a 2 dimensional array to access specific rows. I want to be able to ...

Character Encodings in PHP and MySQL

Our website was developed with a meta tag set to... <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> This works fine for M-dashes and special quotes, etc. However, I ...

Pagination Strategies for Complex (slow) Datasets

What are some of the strategies being used for pagination of data sets that involve complex queries? count(*) takes ~1.5 sec so we don t want to hit the DB for every page view. Currently there are ~...

Averaging a total in mySQL

My table looks like person_id | car_id | miles ------------------------------ 1 | 1 | 100 1 | 2 | 200 2 | 3 | 1000 2 | 4 | 500 I need to ...

热门标签