任何在與Internet
連網的電腦上使用MySQL
的使用者都應仔細閱讀本節,以避免最常見的安全問題。
討論安全時,我們強調必須完全保護整個伺服器主機的安全(
而不只是MySQL
伺服器)
防範各種類型的可能的攻擊:偷聽、修改、重放和拒絕服務。我們在這裡不能覆蓋各方面的內容和措施。
MySQL
根據存取控制清單(ACL)
對所有串連、查詢和其它使用者嘗試執行的操作進行安全管理。MySQL
用戶端和伺服器之間還支援SSL-
加密串連。這兒討論的許多概念並不是MySQL
專有的;該思想幾乎同樣適合所有應用程式。
運行MySQL
時,應盡量遵從下面的指導:
·
不要讓任何人(
除了MySQL
root
賬戶)
訪問
mysql
資料庫中的
user
表!
這很關鍵。加密的密碼才是MySQL
中的真正的密碼。
知道user
表中所列的密碼並且能訪問該賬戶客訪問的主機的人可以很容易地用該使用者登入
。
·
學習MySQL
存取權限系統。用GRANT
和REVOKE
語句來控制對MySQL
的訪問。不要授予超過需求的許可權。決不能為所有主機授權。
檢查清單:
o
試試mysql -u root
。如果你能夠成功串連伺服器而沒有要任何密碼,則說明有問題。任何人可以作為MySQLroot
使用者用它的全部許可權來串連MySQL
伺服器!查閱MySQL
安裝說明,應特別注意關於設定root
密碼的資訊。
o
通過SHOW GRANTS
語句檢查查看誰已經訪問了什麼。然後使用REVOKE
語句刪除不再需要的許可權。
·
不要將純文字密碼儲存到資料庫中。如果你的電腦有安全危險,入侵者可以獲得所有的密碼並使用它們。相反,應使用MD5()
、SHA1()
或單向雜湊函數。
·
不要從詞典中選擇密碼。有專門的程式可以破解它們。即使象“xfish98”
這樣的密碼也很差。而“duag98”
要好得多,雖然包含了相同的字“fish
”
,但從標準QWERTY
鍵盤向左輸入。另一種方法是使用“Mhall
”
,來自句子“Mary had a little lamb.
”
中每個字的第一個字元。這樣很容易記住並輸入,但是不知道的人很難猜出來。
·
購買防火牆。這樣可以保護你防範各種軟體中至少50%
的各種類型的攻擊。把MySQL
放到防火牆後或隔離區(DMZ)
。
檢查清單:
o
試試從Internet
使用nmap
工具掃描連接埠。MySQL
預設使用連接埠3306
。不應從不可信任主機訪問該連接埠。另一種檢查是否MySQL
連接埠開啟的簡單方式是從遠程機器試試下面的命令,其中server_host
是MySQL
伺服器啟動並執行主機:
o shell> telnet server_host 3306
如果得到串連並得到一些垃圾字元,則連接埠開啟著,則應從防火牆或路由器上關閉,除非你有合理的理由讓它開著。如果telnet
掛起或串連被拒絕,則連接埠被阻塞,這是你所希望的。
不要信任應用程式的使用者輸入的任何資料。它們可以用Web
形式、URL
或構建的應用程式輸入特殊或逃溢字元序列來嘗試欺騙你的代碼。如果某個使用者輸入“;
DROP DATABASE mysql;”
等內容,應確保你的應用程式保持安全。這是特例,但當駭客使用類似技術時,如果你沒有做好準備,結果可能會出現大的安全性漏洞和資料丟失。
一個常見的錯誤是只保護字串資料值。一定要記住還應檢查數字資料。如果當使用者輸入值234
時,應用程式產生查詢SELECT * FROM table WHERE
ID=234
,使用者可以輸入值234 OR 1=1
使應用程式產生查詢SELECT * FROM table WHERE ID=234 OR 1=1
。結果是伺服器尋找表內的每個記錄。這樣會暴露每個記錄並造成過多的伺服器負載。保護防範這類攻擊的最簡單的方法是使用單引號將數字常量引起來:SELECT * FROM table WHERE ID='234'
。如果使用者輸入其它資訊,均變為字串的一部分。在數字部分,MySQL
自動將字串轉換為數字並剝離字串包含的附加的非數字字元。
有時候人們會認為如果資料庫只包含供公用使用的資料,則不需要保護。這是不正確的。即使允許顯示資料庫中的任何記錄,你仍然應保護防範拒絕服務的攻擊(
例如,基於前面段落中所述的技術的攻擊,會使伺服器浪費資源)
。否則,你的伺服器不再響應合法使用者。
檢查清單:
o
試試用Web
形式輸入單引號和雙引號(‘'’
和‘"’)
。如果得到任何形式的MySQL
錯誤,立即分析原因。
o
試試修改動態URL
,可以在其中添加%22(‘"’)
、%23(‘#’)
和%27(‘'’)
。
o
試試在動態URL
中修改資料類型,使用前面樣本中的字元,包括數字和字元類型。你的應用程式應足夠安全,可以防範此類修改和類似攻擊。
o
試試輸入字元、空格和特殊符號,不要輸入數值欄位的數字。你的應用程式應在將它們傳遞到MySQL
之前將它們刪除或建置錯誤。將未經過檢查的值傳遞給MySQL
是很危險的!
o
將資料傳給MySQL
之前先檢查其大小。
o
用管理賬戶之外的使用者名稱將應用程式串連到資料庫。不要給應用程式任何不需要的存取權限。
·
許多API提供了措施逃逸資料值中的特殊字元。如果使用正確,可以防止應用程式使用者輸入使應用程式產生不期望的效果的語句的數值:
o MySQL C API
:使用mysql_real_escape_string() API
調用。
o MySQL++
:查詢流使用escape
和quote
修訂符。
o PHP
:使用mysql_escape_string()
函數基於MySQL C API
中的同名函數。(
在PHP 4.0.3
之前,
使用addslashes()
)。在PHP
5
中,
可以使用mysqli
副檔名,它支援改進的MySQL
評鑑協議和密碼,以及用預留位置編寫的語句。
o Perl DBI
:使用quote()
方法或使用預留位置。
o Java JDBC
:使用一個PreparedStatement
對象和預留位置。
其它編程介面有類似的功能。
·
不要通過Internet
傳送明文(
未加密的)
資料。該資訊可以被有足夠時間和能力來截取它並用於個人目的的任何人訪問。相反,應使用加密協議,例如SSL
或SSH
。MySQL
支援內部SSL
串連,例如版本 4.0.0
。可以使用SSH
連接埠映射為通訊建立加密(
並壓縮)
的隧道。
·
學會使用tcpdump
和strings
工具。在大多數情況下,你可以使用下面的命令檢查是否MySQL
資料流未加密:
· shell> tcpdump -l -i eth0 -w - src or dst port 3306 | strings
(
該命令在Linux
中可以工作,在其它系統中經過小小的修改後應可以工作)。
警告:如果你沒有看見明文資料,並不一定說明資訊實際上被加密了。如果你需要較進階別的安全,你應諮詢安全專家。