首頁  >  文章  >  後端開發  >  PHP 應用程式的安全性 -- 不能違反的四個安全性規則_PHP教程

PHP 應用程式的安全性 -- 不能違反的四個安全性規則_PHP教程

WBOY
WBOY原創
2016-07-21 16:00:08780瀏覽

大家都知道安全性是重要的,但是產業中的趨勢是直到最後一刻才加入安全性。既然不可能完全保護 Web 應用程序,那麼為什麼要費這個勁兒呢,不是嗎?不對。只要採用一些簡單的步驟就能夠大幅提升 PHP Web 應用程式的安全性。




開始之前

在本教學中,您將學習如何在自己的 PHP Web 應用程式中加入安全性。本教學假設您至少有一年編寫 PHP Web 應用程式的經驗,所以這裡不涉及 PHP 語言的基本知識(約定或語法)。目標是讓您了解應該如何保護自己建立的 Web 應用程式。



目標
本教學說明如何防禦最常見的安全威脅:SQL 注入、操控 GET 與 POST 變數、緩衝區溢位攻擊、跨站點腳本攻擊、瀏覽器內的資料操縱和遠端表單提交。



前提條件
本教學是為至少有一年程式設計經驗的 PHP 開發人員所寫的。您應該了解 PHP 的語法和約定;這裡不解釋這些內容。有使用其他語言(例如 Ruby、Python 和 Perl)的經驗的開發人員也能夠從本教程中受益,因為這裡討論的許多規則也適用於其他語言和環境。



系統需求

需要一個正在運作 PHP V4 或 V5 和 MySQL 的環境。可使用 Linux、OS X 或 Microsoft Windows。如果是在 Windows 上,那麼下載 WAMPServer 二進位文件,並在機器上安裝 Apache、MySQL 和 PHP。




安全性快速簡介
Web 應用程式最重要的部分是什麼?根據回答問題的人不同,這個問題的答案可能是五花八門。業務人員需要可靠性和可擴展性。 IT 支援團隊需要健全的可維護的程式碼。最終用戶需要漂亮的使用者介面和執行任務時的高效能。但是,如果回答 “安全性”,那麼每個人都會同意這對 Web 應用程式很重要。

但是,大多數討論到此就打住了。儘管安全性在專案的檢查表中,但是往往到了專案交付之前才開始考慮解決安全性問題。採用這種方式的 Web 應用程式專案的數量多得驚人。開發人員工作幾個月,只在最後才添加安全特性,從而讓 Web 應用程式向公眾開放。

結果往往是一片混亂,甚至需要返工,因為程式碼已經經過檢驗、單元測試並集成為更大的框架,之後才在其中添加安全特性。添加安全性之後,主要組件可能會停止工作。安全性的整合使得原本順暢(但不安全)的過程增加額外負擔或步驟。

本教學提供將安全性整合到 PHP Web 應用程式中的好方法。它討論幾個一般性安全主題,然後深入討論主要的安全漏洞以及如何堵住它們。在學完本教學之後,您會對安全性有更好的理解。



主題包括:
SQL 注入攻擊 
操縱 GET 字串 
緩衝區溢位攻擊 
跨站點腳本攻擊(XSS) 
緩衝區溢位攻擊 
跨站點腳本攻擊(XSS) 內的資料操縱 
遠端表單提交




Web 安全性 101
在討論實現安全性的細節之前,最好先從比較高的角度討論 Web應用程式安全性。本節介紹安全哲學的一些基本信條,無論正在創建何種 Web 應用程序,都應該牢記這些信條。這些想法的一部分來自 Chris Shiflett(他關於 PHP 安全性的書是無價的寶庫),有些來自 Simson Garfinkel(參見 參考資料),還有一些來自多年累積的知識。



規則 1:絕不信任外部資料或輸入

關於 Web 應用程式安全性,必須認識到的第一件事是不應該信任外部資料。外部資料(outside data) 包含任何不是由程式設計師在 PHP 程式碼中直接輸入的資料。在採取措施確保安全之前,任何其他來源(例如 GET 變數、表單 POST、資料庫、個人資料、會話變數或 cookie)的資料都是不可信任的。

例如,下面的資料元素可以被認為是安全的,因為它們是在 PHP 中設定的。


清單 1. 安全無瑕的程式碼

$myUsername = 'tmyer';
$array , 'tommy');
define("GREETING", 'hello there' . $myUsername);
?>
但是,下面的資料元素都是瑕疵的。

清單 2. 不安全、有瑕疵的程式碼

$myUsername = $_POST['username']; //tainted!
$arrayUsers =arrayUsers =array ($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!
?>


為什麼第一個變數 $myUsername 是有瑕疵的?因為它直接來自表單 POST。使用者可以在這個輸入域中輸入任何字串,包括用來清除檔案或運行以前上傳的檔案的惡意命令。您可能會問,「難道不能使用只接受字母 A-Z 的客戶端(JavaScript)表單檢驗腳本來避免這種危險嗎?」是的,這總是一個有好處的步驟,但是正如在後面會看到的,任何人都可以將任何表單下載到自己的機器上,修改它,然後重新提交他們需要的任何內容。

解決方案很簡單:必須對 $_POST['username'] 執行清理程式碼。如果不這麼做,那麼在使用 $myUsername 的任何其他時候(例如在陣列或常數中),就可能污染這些物件。

對使用者輸入進行清理的一個簡單方法是,使用正規表示式來處理它。在這個範例中,只希望接受字母。將字串限制為特定數量的字符,或要求所有字母都是小寫的,這可能也是個好主意。

清單 3. 使用戶輸入變得安全

$myUsername = cleanInput($_POST['username']); //clean!
$arraysUser = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!
    $clean = strtolower($input);
    $clean = preg_replace("/[^a-z]/",$3", p. ,0,12);
    return $clean;
}
?>



規則已經知道不能信任使用者輸入,也應該知道不應該信任機器上設定 PHP 的方式。例如,請確保停用 register_globals。如果啟用了 register_globals,就可能做一些粗心的事情,例如使用 $variable 來取代同名的 GET 或 POST 字串。透過停用這個設置,PHP 強迫您在正確的名稱空間中引用正確的變數。要使用來自表單 POST 的變量,則應引用 $_POST['variable']。這樣就不會將這個特定變數誤會成 cookie、會話或 GET 變數。

要檢查的第二個設定是錯誤報告等級。在開發期間,希望獲得盡可能多的錯誤報告,但是在交付專案時,希望將錯誤記錄到日誌檔案中,而不是顯示在螢幕上。為什麼呢?因為惡意的駭客會使用錯誤報告資訊(例如 SQL 錯誤)來猜測應用程式正在做什麼。這種偵察可以幫助駭客突破應用程式。為了封鎖這個漏洞,需要編輯 php.ini 文件,為 error_log 條目提供適當的目的地,並將 display_errors 設定為 Off。



規則 3:如果不能理解它,就不能保護它

一些開發人員使用奇怪的語法,或者將語句組織得很緊湊,形成簡短但是含義模糊的程式碼。這種方式可能效率高,但是如果您不理解程式碼正在做什麼,那麼就無法決定如何保護它。

例如,您喜歡下面兩段程式碼中的哪一段?

清單 4. 讓程式碼容易受到保護

//obfuscated code
$input = (isset($_POST['username)
$input = (isset($_POST['username']) ['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
    $input = $_POST['username'];
}else{
    $input = '';
}
}
>



規則 4:「縱深防禦」 是新的法寶

本教學將用範例來說明如何保護線上表單,同時在處理表單的 PHP 程式碼中採用必要的措施。同樣,即使使用 PHP regex 來確保 GET 變數完全是數位的,仍可採取措施確保 SQL 查詢使用轉義的使用者輸入。

縱深防禦不只是一種好思想,它可以確保您不會陷入嚴重的麻煩。
既然已經討論了基本規則,現在就來研究第一種威脅:SQL 注入攻擊。




防止 SQL 注入攻擊

在 SQL 注入攻擊 中,使用者透過操縱表單或 GET 查詢,將資訊加入資料庫中。例如,假設有一個簡單的登入資料庫。這個資料庫中的每個記錄都有一個使用者名字段和一個密碼欄位。建立一個登入表單,讓使用者能夠登入。

清單 5. 簡單的登入表單



Login

Login

Login











陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn