設計資料庫
第一步一般都是建立資料庫,除非是使用第三方的資料庫服務。當建立一個資料庫的時候,會指定一個擁有者來執行和新建語句。通常,只有擁有者(或超級使用者)才有權對資料庫中的物件進行任意操作。如果想讓其他使用者使用,就必須賦予他們權限。
應用程式永遠不要使用資料庫擁有者或超級使用者帳號來連接資料庫,因為這些帳號可以執行任意的操作,例如修改資料庫結構(例如刪除表)或清空整個資料庫的內容。
應該為程式的每個方面建立不同的資料庫帳號,並賦予對資料庫物件的極有限的權限。僅分配給能完成其功能所需的權限,避免同一個使用者可以完成另一個使用者的事情。這樣即使攻擊者利用程式漏洞取得了資料庫的存取權限,也最多只能做到和該程式一樣的影響範圍。
鼓勵使用者不要把所有的事務邏輯都用 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.'; } ?>