PHP安全之數據庫安全——設計、連接和加密
第一步一般都是創建數據庫,除非是使用第三方的數據庫服務。當創建一個數據庫的時候,會指定一個所有者來執行和新建語句。通常,只有所有者(或超級用戶)才有權對數據庫中的對象進行任意操作。如果想讓其他用戶使用,就必須賦予他們權限。
應用程序永遠不要使用數據庫所有者或超級用戶帳號來連接數據庫,因為這些帳號可以執行任意的操作,比如說修改數據庫結構(例如刪除一個表)或者清空整個數據庫的內容。
應該為程序的每個方面創建不同的數據庫帳號,并賦予對數據庫對象的極有限的權限。僅分配給能完成其功能所需的權限,避免同一個用戶可以完成另一個用戶的事情。這樣即使攻擊者利用程序漏洞取得了數據庫的訪問權限,也最多只能做到和該程序一樣的影響范圍。
鼓勵用戶不要把所有的事務邏輯都用 web 應用程序(即用戶的腳本)來實現。最好用視圖(view)、觸發器(trigger)或者規則(rule)在數據庫層面完成。當系統升級的時候,需要為數據庫開辟新的接口,這時就必須重做所有的數據庫客戶端。除此之外,觸發器還可以透明和自動地處理字段,并在調試程序和跟蹤事實時提供有用的信息。
連接數據庫把連接建立在 SSL 加密技術上可以增加客戶端和服務器端通信的安全性,或者 SSH 也可以用于加密客戶端和數據庫之間的連接。如果使用了這些技術的話,攻擊者要監視服務器的通信或者得到數據庫的信息是很困難的。
加密存儲模型SSL/SSH 能保護客戶端和服務器端交換的數據,但 SSL/SSH 并不能保護數據庫中已有的數據。SSL 只是一個加密網絡數據流的協議。
如果攻擊者取得了直接訪問數據庫的許可(繞過 web 服務器),敏感數據就可能暴露或者被濫用,除非數據庫自己保護了這些信息。對數據庫內的數據加密是減少這類風險的有效途徑,但是只有很少的數據庫提供這些加密功能。
對于這個問題,有一個簡單的解決辦法,就是創建自己的加密機制,然后把它用在 PHP 程序內。PHP 有幾個擴展庫可以完成這個工作,比如說?Mcrypt?和?Mhash?等,它們包含多種加密運算法則。腳本在插入數據庫之前先把數據加密,以后提取出來時再解密。
對某些真正隱蔽的數據,如果不需要以明文的形式存在(即不用顯示),可以考慮用散列算法。使用散列算法最常見的例子就是把密碼經過 MD5 加密后的散列存進數據庫來代替原來的明文密碼。
Example #1 對密碼字段進行散列加密
<?php // 存儲密碼散列 $query = sprintf('INSERT INTO users(name,pwd) VALUES(’%s’,’%s’);', pg_escape_string($username), md5($password)); $result = pg_query($connection, $query); // 發送請求來驗證用戶密碼 $query = sprintf('SELECT 1 FROM users WHERE name=’%s’ AND pwd=’%s’;', pg_escape_string($username), md5($password)); $result = pg_query($connection, $query); if (pg_num_rows($result) > 0) {echo ’Welcome, $username!’; } else {echo ’Authentication failed for $username.’; }?>
相關文章: