2011-01-09 50 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%' 

,以迅速確定什麼「祕密」的字母,然後繼續前進,以確定字母的順序,最終揭示的「祕密」的價值。