1. 程式人生 > >php網站開發常見的幾種攻擊以及解決方案

php網站開發常見的幾種攻擊以及解決方案

PHP網站建設中常見的安全威脅包括:SQL 注入、操縱 GET 和 POST 變數、緩衝區溢位攻擊、跨站點指令碼攻擊、瀏覽器內的資料操縱和遠端表單提交。

1、防止SQL注入攻擊

在 SQL 注入攻擊 中,使用者通過操縱表單或 GET 查詢字串,將資訊新增到資料庫查詢中。

例如,假設有一個簡單的登入資料庫。這個資料庫中的每個記錄都有一個使用者名稱欄位和一個密碼欄位。構建一個登入表單,讓使用者能夠登入。

解決這個問題的辦法是,將 PHP 的內建 mysql_real_escape_string() 函式用作任何使用者輸入的包裝器。

這個函式對字串中的字元進行轉義,使字串不可能傳遞撇號等特殊字元並讓 MySQL 根據特殊字元進行操作。清單 7 展示了帶轉義處理的程式碼。

2、防止使用者操縱變數

使用者擁有有效的密碼,並不意味著他將按照規則行事 —— 他有很多機會能夠造成損害。例如,應用程式可能允許使用者檢視特殊的內容。

比如 template.php?pid=33 或 template.php?pid=321。URL 中問號後面的部分稱為查詢字串。因為查詢字串直接放在 URL 中,所以也稱為 GET 查詢字串。

這裡有什麼錯嗎?

首先,這裡隱含地相信來自瀏覽器的 GET 變數 pid 是安全的。

這會怎麼樣呢?

大多數使用者沒那麼聰明,無法構造出語義攻擊。但是,如果他們注意到瀏覽器的 URL 位置域中的 pid=33,就可能開始搗亂。

如果他們輸入另一個數字,那麼可能沒問題;但是如果輸入別的東西,比如輸入 SQL 命令或某個檔案的名稱(比如 /etc/passwd),或者搞別的惡作劇,比如輸入長達 3,000 個字元的數值,那麼會發生什麼呢?

在這種情況下,要記住基本規則,不要信任使用者輸入。

應用程式開發人員知道 template.php 接受的個人識別符號(PID)應該是數字,所以可以使用 PHP 的 is_numeric() 函式確保不接受非數字的 PID。

需要做的只是使用 strlen() 檢查變數的長度是否非零;如果是,就使用一個全數字正則表示式來確保資料元素是有效的。如果 PID 包含字母、斜線、點號或任何與十六進位制相似的內容,那麼這個例程捕獲它並將頁面從使用者活動中遮蔽。

3、緩衝區溢位攻擊

緩衝區溢位攻擊 試圖使 PHP 應用程式中(或者更精確地說,在 Apache 或底層作業系統中)的記憶體分配緩衝區發生溢位。

請記住,您可能是使用 PHP 這樣的高階語言來編寫 Web 應用程式,但是最終還是要呼叫 C(在 Apache 的情況下)。與大多數低階語言一樣,C 對於記憶體分配有嚴格的規則。

緩衝區溢位攻擊向緩衝區傳送大量資料,使部分資料溢位到相鄰的記憶體緩衝區,從而破壞緩衝區或者重寫邏輯。這樣就能夠造成拒絕服務、破壞資料或者在遠端伺服器上執行惡意程式碼。
防止緩衝區溢位攻擊的惟一方法是檢查所有使用者輸入的長度。

注意,緩衝區溢位攻擊並不限於長的數字串或字母串。也可能會看到長的十六進位制字串(往往看起來像 \xA3 或 \xFF)。

記住,任何緩衝區溢位攻擊的目的都是淹沒特定的緩衝區,並將惡意程式碼或指令放到下一個緩衝區中,從而破壞資料或執行惡意程式碼。

對付十六進位制緩衝區溢位最簡單的方法也是不允許輸入超過特定的長度。
如果您處理的是允許在資料庫中輸入較長條目的表單文字區,那麼無法在客戶端輕鬆地限制資料的長度。在資料到達 PHP 之後,可以使用正則表示式清除任何像十六進位制的字串。

4、跨站點指令碼攻擊

在跨站點指令碼(XSS)攻擊中,往往有一個惡意使用者在表單中(或通過其他使用者輸入方式)輸入資訊,這些輸入將惡意的客戶端標記插入過程或資料庫中。

例如,假設站點上有一個簡單的來客登記簿程式,讓訪問者能夠留下姓名、電子郵件地址和簡短的訊息。

惡意使用者可以利用這個機會插入簡短訊息之外的東西,比如對於其他使用者不合適的圖片或將使用者重定向到另一個站點的 JavaScript,或者竊取 cookie 資訊。

幸運的是,PHP 提供了 strip_tags() 函式,這個函式可以清除任何包圍在 HTML 標記中的內容。strip_tags() 函式還允許提供允許標記的列表。

從安全的角度來看,對公共使用者輸入使用 strip_tags() 是必要的。如果表單在受保護區域(比如內容管理系統)中,而且您相信使用者會正確地執行他們的任務(比如為 Web 站點建立 HTML 內容),那麼使用 strip_tags() 可能是不必要的,會影響工作效率。

還有一個問題:如果要接受使用者輸入,比如對貼子的評論或來客登記項,並需要將這個輸入向其他使用者顯示,那麼一定要將響應放在 PHP 的 htmlspecialchars() 函式中。

這個函式將與符號、< 和 > 符號轉換為 HTML 實體。例如,與符號(&)變成 &。這樣的話,即使惡意內容躲開了前端 strip_tags() 的處理,也會在後端被 htmlspecialchars() 處理掉。

5、瀏覽器內的資料操縱

有一類瀏覽器外掛允許使用者篡改頁面上的頭部元素和表單元素。使用 Tamper Data(一個 Mozilla 外掛),可以很容易地操縱包含許多隱藏文字欄位的簡單表單,從而向 PHP 和 MySQL 傳送指令。

使用者在點選表單上的 Submit 之前,他可以啟動 Tamper Data。在提交表單時,他會看到表單資料欄位的列表。

Tamper Data 允許使用者篡改這些資料,然後瀏覽器完成表單提交。

要防禦這種工具,最簡單的方法是假設任何使用者都可能使用 Tamper Data(或類似的工具)。

只提供系統處理表單所需的最少量的資訊,並把表單提交給一些專用的邏輯。例如,登錄檔單應該只提交給註冊邏輯。

如果已經建立了一個通用表單處理函式,有許多頁面都使用這個通用邏輯,那該怎麼辦?

如果使用隱藏變數來控制流向,那該怎麼辦?

例如,可能在隱藏表單變數中指定寫哪個資料庫表或使用哪個檔案儲存庫。有 4 種選擇:

不改變任何東西,暗自祈禱系統上沒有任何惡意使用者。

重寫功能,使用更安全的專用表單處理函式,避免使用隱藏表單變數。

使用 md5() 或其他加密機制對隱藏表單變數中的表名或其他敏感資訊進行加密。在 PHP 端不要忘記對它們進行解密。

通過使用縮寫或暱稱讓值的含義模糊,在 PHP 表單處理函式中再對這些值進行轉換。例如,如果要引用 users 表,可以用 u 或任意字串(比如 u8y90×0jkL)來引用它。

後兩個選項並不完美,但是與讓使用者輕鬆地猜出中介軟體邏輯或資料模型相比,它們要好得多了。

6、遠端表單提交

Web 的好處是可以分享資訊和服務。壞處也是可以分享資訊和服務,因為有些人做事毫無顧忌。

以表單為例。任何人都能夠訪問一個 Web 站點,並使用瀏覽器上的 File > Save As 建立表單的本地副本。然後,他可以修改 action 引數來指向一個完全限定的 URL(不指向 formHandler.php,而是指向http://www.yoursite.com/formHandler.php,因為表單在這個站點上),做他希望的任何修改,點選 Submit,伺服器會把這個表單資料作為合法通訊流接收。

首先可能考慮檢查 $_SERVER['HTTP_REFERER'],從而判斷請求是否來自自己的伺服器,這種方法可以擋住大多數惡意使用者,但是擋不住最高明的黑客。這些人足夠聰明,能夠篡改頭部中的引用者資訊,使表單的遠端副本看起來像是從您的伺服器提交的。

處理遠端表單提交更好的方式是,根據一個惟一的字串或時間戳生成一個令牌,並將這個令牌放在會話變數和表單中。提交表單之後,檢查兩個令牌是否匹配。如果不匹配,就知道有人試圖從表單的遠端副本傳送資料。

PHP網站開發安全總結:

使用 mysql_real_escape_string() 防止 SQL 注入問題。

使用正則表示式和 strlen() 來確保 GET 資料未被篡改。

使用正則表示式和 strlen() 來確保使用者提交的資料不會使記憶體緩衝區溢位。

使用 strip_tags() 和 htmlspecialchars() 防止使用者提交可能有害的 HTML 標記。

避免系統被 Tamper Data 這樣的工具突破。

使用惟一的令牌防止使用者向伺服器遠端提交表單。