如果我允许一组用户将"explain $whatever"
提交给mysql(通过Perl的DBI使用DBD::mysql
),那么用户可以放入任何可以使任何数据库更改的内容,泄漏非平凡的信息,甚至造成重大的数据库负载?如果是这样,怎么样?
我知道通过"explain $whatever"
可以找出存在哪些表/列(但是你必须猜测名称)以及表中大约有多少记录或者有多少条记录具有索引字段的特定值。我不希望人们能够获得有关未编制索引字段内容的任何信息。
DBD::mysql
不应该允许多个语句,所以我不希望它可以运行任何查询(只解释一个查询)。即使是子查询也不应该被执行,只是解释了。
但我不是一个mysql专家,我肯定不知道mysql的功能。
在尝试提出查询计划时,优化器可能会实际执行一个表达式,以便提出索引字段将要与之进行比较的值吗?
explain select * from atable where class = somefunction(...)
其中atable.class
已编入索引且不唯一,class='unused'
将找不到记录,但class='common'
会找到一百万条记录。可能'解释'评估somefunction(...)
?然后可以编写somefunction(...)
以便修改数据吗?
答案 0 :(得分:6)
“Explain”可能需要花费任意长的时间来执行,并使用任意数量的服务器资源,包括在某些事情耗尽时导致崩溃(例如,由于嵌套子查询太多而导致堆栈溢出)。 / p>
“Explain”可以轻松耗尽临时磁盘空间,服务器地址空间(在32位系统上,64位系统上的虚拟内存)或线程堆栈(故意恶意构建的查询)。
通常,您不能允许完全不受信任的用户提交任何SQL的任何部分。即使没有访问单个表,如果他们努力尝试,他们仍然可能会崩溃服务器。
编辑:进一步信息
使用匿名视图/具体化子查询的查询通常在EXPLAIN上执行整个内部查询到临时表中。
所以表格的查询
SELECT * FROM (
SELECT h1.*, h2.* FROM huge_table h1, huge_table h2) AS rediculous
将永远解释和使用tmpdir中的光盘空间。
答案 1 :(得分:3)
我能够使用'explain'来获得与精确查询匹配的准确行数。所以可以使用
explain select * from user where name='tye' and secret like '%a%'
快速确定任何“秘密”的字母,然后继续确定字母的顺序,最终揭示“秘密”的价值。
答案 2 :(得分:1)
如果您希望用户能够连接到数据库但不能更改它,则应该使用用户权限强制执行 - 如果用户只拥有SELECT权限,则他们应该无法更改任何内容。