2011-01-09 62 views
3

如果我允许一组用户将"explain $whatever"提交给mysql(通过Perl的DBI使用DBD::mysql),是否有任何用户可以将任何数据库更改,泄漏不重要的信息,甚至导致重大数据库负载?如果是这样,怎么样?在mysql中,“解释...”总是安全吗?

我知道,通过"explain $whatever"一个可以找出表/列存在什么(你必须猜测的名字,虽然)和大约多少条记录在一个表或多少记录有一个索引字段中的特定值。我不希望一个人能够获得有关未索引字段内容的任何信息。

DBD::mysql不应该允许多个语句,所以我不期望它有可能运行任何查询(只是解释一个查询)。即使子查询不应该执行,只是解释。

但我不是一个mysql专家,并且肯定有我甚至没有意识到的mysql特性。

在试图提出一个查询计划时,优化程序可能会真正执行一个表达式,以便拿出索引字段将与之进行比较的值。

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

其中atable.class被索引,而不是唯一的,class='unused'会发现没有任何记录,但class='common'会发现一百万条记录。可能'解释'评估somefunction(...)?然后可以编写somefunction(...)以修改数据吗?

+3

可能它是安全的,但我不会这样做;)任何有理由与`explain`混淆的人应该被给予DB和mysql CLI的测试副本。任何不需要测试数据库的人都应该从写入查询中保存,因此不需要`explain`;) – hobbs 2011-01-09 08:55:11

回答

6

“解释”可能需要很长时间才能执行,并且使用任意数量的服务器资源,包括在某些事情耗尽(例如由嵌套的子查询过多导致堆栈溢出)时导致崩溃。

“解释”可能会轻易地耗尽临时磁盘空间,服务器地址空间(在32位系统上,在64位系统上的虚拟内存)或线程堆栈(用于故意恶意构建的查询)。

通常,您不能允许完全不受信任的用户提交任何SQL的任何部分。即使没有访问单个表,他们仍然可能会崩溃服务器,如果他们努力工作。


编辑:进一步信息

其使用匿名视图的查询/物化子查询,经常执行在解释整个内部查询,到临时表。

所以形式

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

的查询将采取永远解释和消耗TMPDIR磁盘空间。

1

如果您希望用户能够连接到数据库但不能更改它,则应该使用用户权限执行该操作 - 如果它们只具有SELECT权限,则它们不应该能够更改任何内容。

+0

谢谢。这是非常好的建议。添加一个只读用户,并在做“解释”时使用它,完全消除了主要风险(人们通过“解释”找出如何更新)。 – tye 2011-01-10 23:39:09

+0

权限系统将阻止人们更改数据,但不会导致服务器崩溃或导致拒绝服务,请参阅我的答案。 – MarkR 2011-01-11 07:25:11

3

我能够使用'explain'来获得与精确查询匹配的行的准确计数。因此,人们可以使用

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

,以迅速确定什么“秘密”的字母,然后继续前进,以确定字母的顺序,最终揭示的“秘密”的价值。