■曾金燕
高性能Redis數據庫安全手冊
■曾金燕
Redis是一個高性能的key-value數據庫,這兩年可謂火的不行。而Redis的流行也帶來一系列安全問題,不少攻擊者都通過Redis發起攻擊。本文將講解這方面的內容,包括Redis提供的訪問控制和代碼安全問題,以及可以由惡意輸入和其他類似的手段觸發的攻擊。
Redis被設計成只能由可信環境的可信機器訪問。這意味著將它直接暴露在互聯網或者其他可以由不可信機器通過TCP或者UNIX SCOKET直接連接的環境中。
例如,在通常的WEB應用程序使用Redis作為數據庫,cache,或者消息系統。WEB應用程序的客戶端將查詢Redis生成頁面或執行請求或由用戶觸發。在這個例子中,WEB應用鏈接了Redis和不可信的客戶端。
這是一個特定的例子,但是一般來說,不授信的Redis鏈接應該被監控,驗證用戶輸入,再決定執行什么樣的操作。因為,Redis追求的不是最大的安全性,而是簡潔與高效。
Redis鏈接應該對每個受信的客戶端開放。所以,服務器運行的Redis應該只被使用Redis應用的計算機連接。在大多數直接暴露在互聯網的單個計算機,例如,虛擬化的LINUX實例(LINODE,EC2,…..)
Redis端口應該被防火墻阻止來自外部的訪問。客戶端應該仍然能通過服務器的本地回環接口訪問Redis。注意,通過在Redis.CONF添加下面一句就可以綁定本地回環,阻止外網訪問了。
因為Redis的特性,沒有對外網訪問進行限制會是一個很重大的安全問題。例如一條簡單的FLUSHALL命令就能被攻擊者用來刪除整個數據設置。
如果你們不想使用訪問限制的話,Redis提供了一個身份驗證功能,可以通過編輯Redis.CONF文件來實現它。
如果開啟了身份驗證功能,Redis將拒絕所有的未身份驗證的客戶端的所有操作。客戶端可以發送AUTH命令+密碼來驗證自己。
密碼是由系統管理員在Redis。CONFIG文件中設置的明文密碼,為了防止暴力破解攻擊他應該足夠長。原因有兩個:
Redis的執行效率非常快,外部設備每秒可以測試相當數量的密碼
Redis的密碼是存儲在Redis.conf文件和內部客戶端的配置中的,因此不需要管理員記住。所以可以使用相當長的密碼。
身份驗證的目標是提供第二層的安全保障。這樣當防火墻或者其他第一層的系統安全設置失效的話,一個外部設備在沒有密碼的情況下仍然不能訪問redia。
AUTH命令像其他的redia命令一樣是不加密傳輸的,所以他不能阻止攻擊者在內網的竊聽。
Redis不支持加密。為了受信的客戶端可以以加密形式通過互聯網可以采用加密協議(SSL)傳輸數據。
禁用Redis的一些命令是可行的,或者將他們改名。這樣來自客戶端的請求就只能執行有限的命令。
例如,虛擬的服務器提供商可能提供托管的Redis服務。在這種情況下,普通用戶不應該能夠調用Redis的配置命令來修改該配置實例,但提供和刪除服務的系統能夠有這樣的權限。
在這種情況下,從命令表中重命名命令或者完全隱藏命令是可能的。這個功能可用在Redis.conf配置文件里做為一個聲明。
還有一類攻擊,攻擊者即使沒有獲得數據庫的訪問權限也可以從外部發起攻擊。一個此類攻擊的例子是通過Redis的內部函數向Redis里插入數據。
攻擊者可以通過一個WEB表單將一組字符串提交到一個hash的同一個堆棧,引起時間復雜度從O(1)到O(n),消耗更多的CPU資源,最終導致DOS攻擊。為了防止這種特定的攻擊方式,Redis為每個執行請求隨機分配hash。
Redis使用快速排序算法來執行SORT命令。目前,這個算法不是隨機的,所以通過對輸入的精細控制可能觸發命令的二次執行。
Redis協議里面沒有字符串轉義相關的內容,所以在通常情況下是不存在注入的。Redis協議使用的是前綴長度的字符串,完全二進制,保證安全性。LUA腳本執行EVAL和EVALSHA命令時遵循相同的規則,因此這些命令也是安全的。
然而這回事一個非常奇怪的用例,應用程序應該避免使用LUA腳本獲取來自非信任源的字符串。
在經典的Redis設置里,客戶端可以執行所有的命令集,但是獲得的用例應該永遠不能導致有控制Redis所在系統的能力。內在的,Redis使用眾所周知的安全代碼規范來防止緩沖區溢出,格式錯誤和其它內存損壞問題。然而,客戶端擁有控制使用服務器配置命令CONFIG的能力使得其能夠改變程序的工作目錄和轉儲文件的名稱。這允許客戶端寫RDB Redis在隨機路徑寫文件。這是一個安全問題,容易導致客戶端有Redis運行非法代碼的能力。
Redis不需要root權限運行,也不建議以root權限運行。Redis的作者正在調查添加一條新的配置參數來防止CONFIG SET/GET目錄和其他類似的運行時配置的指令的可能性。這會阻止客戶端強制服務器在任意位置寫Redis轉儲文件。
安全研究人員可以在Github提交問題,當你感覺這個安全問題真的很重要,在文檔的末尾加上GPG標識。