1.時刻更新你的php版本
正如其它程式設計語言一樣,PHP的缺陷也會逐漸暴露出來。使用和及時更新最新的php版本将有助于你保證應用程式的安全,高效和穩定。
2.朦胧的安全根本就不是安全,同時你也不想洩露關于你的網站的資訊。以下的建議看似簡單,實則在現實生活中很容易被人們忽視。
確定在你的網站上不展現錯誤以及關于你網站潛在的資訊洩露
隻要在你的産品伺服器的php.ini中如下設定即可:display_errors = Off,這樣就可以有效防範資訊洩露進而給防止黑客知曉關于你的系統結構的的資訊。一般的預設設定是display_errors = On.
3.有安全意識固然不錯,但這是遠遠不夠的。
開發者在面臨安全問題的時候一定要有警惕之心。即使你不能單獨處理這一問題。隻要是應用程式都不可避免的存在大量的安全隐患,隻不過是沒有爆發出來而已。第三方安全軟體有助于找出你沒有注意到的安全缺陷。
作為網站開發人員,手頭上一定要有專門的工具幫助你找出應用程式的缺陷。Chorizo可以幫助你自動掃描代碼。諸如PHPSecInfo一樣的程式幫助你確定配置環境的安全。
使用諸如此類的掃貓工具并不足以保證100%的安全。盡管如此,仍然是組安全政策中很重要的一部分。一定是使用值得信賴的開發商幫助你建構和維護安全的應用程式。
4.模糊的安全根本就不是安全,但模糊安全政策必不可少。
盡管如此,實際當你恰當的使用模糊安全政策的時候也不是為一個好的選擇。那些心懷不軌的人實際上就是想把事情弄的很複雜。
裝有機密資訊的檔案夾和檔案不要使用預設的名稱。
不要使用使用艱深晦澀的檔案名保證你的應用程式的安全。應該不斷的檢查網絡許可,使用測試工具測試漏洞,利用網絡日志監視異常行為。當你設計應用程式和網站的時候,不要讓壞人輕易的如願以償。檔案名和目錄名不要使用預設的或是很簡單的名稱。
5.php是一個永恒的使命,它要求程式員跳出程式的參數思考問題。僅僅思考“我所設計的東西會按照我的想法一樣嗎”,你還要思考,“其他人會利用我設計的東西幹些什麼,我允許他們這樣做嗎”。以下的安全建議是所有的程式員都應該知道的。
永遠不要相信使用者
這樣說也許是有點悲觀,但是使用者确實就是惡魔。使用者隻不過是想找出你的程式的缺陷。一旦你自己降低安全要求,并且認為“我隻不過是賣點小玩意,客戶能有什麼能耐呢”,這時候你已經輸掉了這場戰争。
過濾入流量,遠離出流量(FIEO)
确實,FIEO是所有的程式員都應該牢記的安全咒語。
6.在PHP中編寫安全程式不僅僅是編寫一長串PHP代碼就夠了。
許多程式使用資料庫或是類似的東西。很多情況下,導緻整個應用程式漏洞的就是在建構SQL代碼的時候。以下有一條簡單的解決之道。
處理SQL字元串中的數字的時候,一定要計算。
即使你是在過濾入流量,一個簡單而行之有效的安全政策就是把所有的數值都放到SQL報表中。我們以這個代碼為例子。
$myId = filter_var($_GET['id'],FILTER_VALIDATE_INT);
$sql = 'SELECT * FROM table WHERE id = '.$myId;
盡管你使用的是PHP 5.2版本内置的php過濾器,你還可以有其它的選擇,試一下下面這個:
$myId = filter_var($_GET['id'],FILTER_VALIDATE_INT );
$sql = 'SELECT * FROM table WHERE id = '.(int)$myId;
最後的變量就是變成一個int就會讓所有的可以變量遠離MySQL.上面的例子故意簡化了。在實際情況中,代碼更加複雜,産生錯誤的風險也更大。通過使用最後的計算建構一個精選的報表,這樣你就提高了應用程式的安全等級。
7.當你使用session_regenerate_id()來阻止session固定的時候,最好是将之前的session ID移除。
執行個體腳本:
<code><?php session_start(); $_SESSION['data'] = time(); session_regenerate_id(); ?></code>
檢測URL以及/tmp路徑
sess_82c6980017e100277a63983142fd454c
sess_a4bab88e6dfa6e900ade21e3fbd27a53
再次檢測
sess_984c5230acca90b5a75eddb89bb48354
然後你可以看到如下情況
sess_a4bab88e6dfa6e900ade21e3fbd27a53
sess_82c6980017e100277a63983142fd454c
sess_dd88c05b724d80b30c90309847f2e919
這些session仍然很活躍。當重新生成ID的時候移除它們采用如下代碼:
<code><?php session_start(); $_SESSION['data'] = time(); session_regenerate_id(true); ?></code>
如果你正在使用自己的session處理器的話,這可能導緻你的destroy callback功能被激活。
8.使用php安全主題,實際上不止一種方法可以完成任務。在很多情況下,戰術的重組可以達到最好的安全效果。我們一直在談論資訊的過濾,我們還需要警惕來自于使用者的驗證資訊。這是在日常的php應用中需要加以注意的。
确認使用者的輸入資訊
代碼執行個體:
<code><?php $myFile = filter_var($_GET['file'], FILTER_SANITIZE_STRING); include($myFile); ?></code>
點選http://example.com/file.php?file=home.php可能會導緻你的腳本包含在你的目前的目錄中的檔案home.php。但是如果有人請求http://example.com/file.php?file=badcode.php的話,你就會置身于執行代碼的危險中,或是你不想執行的代碼被執行。
不要僅僅依靠file_exists(). 因為本地檔案并不意味着這是一個正确的檔案甚至那根本就不是你的檔案。不要讓黑客輕易的執行代碼。
為了保證安全,記住一定要過濾和确認:
<code><?php // filter $myFile = filter_var($_GET['file'], FILTER_SANITIZE_STRING); // Then validate $valid = array('home.php', 'about.php'); If (!in_array($myFile, $valid)) { die('Leave, evil hacker'); } include($myFile); ?></code>
9.有時最簡單的也就是最安全的。以下的建議很簡單,但是我們很驚訝在現實生活中很少有人了解以及使用。
不要将敏感資訊放于網上
思考一下下面這個目錄結構:
/htdocs
/includes
/images
/js
如果你将你的資料庫的信任狀存儲于一個名為db.inc的檔案中,然後将其放于這一目錄之下,很可能就有人下載下傳這一檔案夾名下的資訊,隻要他們通路http://example.com/includes/db.inc.站點,因為絕大多數的網站伺服器并不知道如何處理這一.inc檔案,如果有通路請求的話,它們直接被認為是純文字。後果是可怕的。如果你存儲信任狀的檔案使用的是非.php字尾名的話并且位于你的網絡伺服器的根目錄之下,很可能你的資訊正在洩露。
解決方法很簡單。将所有的敏感資訊置于網絡伺服器的根目錄之外。現在也有很多專家提倡把絕大多數的php代碼放于網絡伺服器根目錄之外。因為php代碼不限于同一個限制,你可以在根目錄的同一檔案層次之下建立一個目錄,然後将你的所有的機密資訊和代碼放在那。
/phpinc
/htdocs
10.即時所有的事情都做的完美無缺,你建構的php代碼仍然存在安全隐患。安全需要永恒的警惕之心。有一件事情你需要時刻保持注意,那就是依賴入流量發送郵件的腳本。許多使用php編寫的應用程式使用内置的mail()功能來回應郵件觸發的使用者流量。
不要盲目的使用資訊發送郵件
正如我們在其它的關于php的安全建議中談到的一樣,你要確定适當的過濾和确認使用者的輸入。如果你沒有恰當的過濾入流的話,很可能就有人在你沒有注意之前使用電子郵件注入以及發送成千的垃圾郵件。
11.我們都認為使用者既是我們開發的程式是天使也是魔鬼。一方面,要是沒有使用者的話也就不會存在安全問題了。再者,要是沒有使用者,我們就沒有必要開發應用程式了。是以我們認為不能讓客戶流失。這就是說必須要他們知曉相關的安全問題。我們可以采取如下措施:
最少權限原則
隻給予使用者最低層次的許可
這是最基本的程式設計原則,在絕大多數的Unix中可以看到。處理unix中的使用者和資源的時候,使用者清楚無誤的知道自己的通路權限。使用者的通路權限隻足以通路最基本的資源。我們在開發應用程式的時候也可以借鑒這一概念。
許多現代的php構架都使用了這一概念或是授權通路控制。在Zend構架中,授權是由Zend_Auth處理,但是通路控制是由另外一個Zend_Acl處理的。
不管你使用哪一個結構,一個好的安全政策就是在網頁或圖檔上設定通路限制。不管什麼時候,要将使用者的通路權限限制到最低程度。
12.我們已經談論過過濾,确認以及再次談論過濾。過濾應用程式的輸入是一個很重要的概念,它應該先于很多安全政策之前執行。盡管如此,即使你執行了良好的過濾制度和确認制度,這并不意味這你可以高枕無憂了。在程式設計的整個過程都必須謹記安全問題。
過濾輸入讓一些程式開發人員産生了安全錯覺。他們武斷的認為既然已經采取了過濾措施,就沒有必要擔心安全問題了。在一些簡單的程式中可能确實是沒有什麼問題,但是在一些複雜的程式中就不然了,你要知道使用這些輸入是幹什麼的。在使用者在eval()指令使用輸入的時候的時候就可以看出。以下是一些建議:
在使用eval()之前認真思考一下
通過在eval()中使用使用者輸入參數,你很可能給惡意使用者通路伺服器開了後門。即使你的操作界面僅僅允許他們選擇已經設定好的界面,使用你的腳本哄騙,那麼你的腳本很可能就會被别有用心之人用來即時執行罪惡的行當。
盡量少使用eval()。當你不得不使用的時候,一定要保證過濾和确認輸入的有效性。如果還有其它選擇的話,就使用另外的方法。
13.安全要常記心中,而不是偶然為之。它和代碼一樣為你的程式增彩。盡管如此,你還需要實時監控你的産品環境。那就是我們為什麼要選擇正确的工具的原因。我之前提過PHPSecInfo,這一工具足以保證自身的安全。
PHPSecInfo可以有效的監視你的産品環境。
PHPSecInfo提供與phpinfo()相似的功能,它可以提供關于php環境的安全資訊,并且提供改進建議。但是它并不是安全開發技術的替代品,也不提供任何形式的代碼或是程式監測,但是在多層次安全政策中很有效。
對于安全建議,單靠自身是遠遠不夠的。恰當的組合可以發揮很大的效用。
14.幾乎所有的應用程式都在使用網絡技術的後端使用者上運作php,因為這是前期工作。許多開發人員在php安全上苦思冥想,卻不注意前期的開發工作。以下就是關于在建構HTML和java腳本時應該考慮的一些問題。
任何位于cookie中的資料都可能被其他人看到——将其降低到最低限度
現在的網絡很令人失望,壞人太多。他們等着你的應用程式的資訊洩露然後利用這些敏感資訊擷取利益。評估應用程式安全的時候一定要綜合考慮。當你在前期輸入資料的時候,這尤其重要。
15.作為開發者,很多人做事很混亂。我曾經做過無數的項目,很多人将大量的測試檔案到處亂放。(info.php, test.php, doMe.php,等等)。這些資訊如果被别有用心者獲得,就會洩露關于系統的有價值的資訊。
建議
不要忘記清除臨時的系統診斷檔案
你很可能會感到後悔,如果你花費大量的時間保護你的應用程式而忘記了info.php,test.php 中的“quick piece of code”可能會洩露關于你的系統的危險資訊。不要助纣為戾。
16保證你現在使用的構架實時更新
如果你是在一台臨時的機器上工作的話,這尤其重要。考慮誰來維持折合站點是很重要的,如果安全更新檔是由第三方檔案提供的。
一般來說,這些站點位于一個共享的主機站點上,這就意味着提供商負責維護php,資料庫系統,網絡伺服器等等的實時更新——但是他們很可能不會維護你所安裝的構架。
使用構架是一個不錯的主意——并不是因為它省去了你很多麻煩,更因為它會及時處理相關的安全隐患。
另一方面還意味着這些構架中的網絡安全問題都會被記錄下來——也就是說黑客可以尋找出仍在使用的建構的老版本,然後輕易的發動攻擊。
現在很多站點使用老掉牙的檔案——隻是因為沒有專人負責更新。即使不是你為超額伺服器流量買單——實際上你的郵箱收到了大量的垃圾郵件。
17.應用程式的安全不是一個所有的措施都失效的情況。不是事後可以處理的。正如我們前面所提到,應用程式的安全沒有一個萬全的解決之道。安全貫穿于設計的初始,代碼編寫,測試以及産品成功開發之後的整個階段。
一位著名的php安全專家曾經給出如下的安全建議:
● 安全是一種措施,而不是特征。
● 安全必須與投入之間尋求平衡
● 安全需要與實用性之間尋找到平衡點
● 安全是設計的一部分
以上對于徘徊在安全設計織之外的人是很好的建議。
18.當你允許使用者上傳檔案,這就意味着你的系統有風險。要限制允許上傳的檔案類型。不要依賴黑名單政策。
舉個例子來說,黑名單不允許上傳.php檔案,這确實是一個不賴的主意,要是有人上傳.htaccess檔案的話,黑名單就失去了效用。将惡意代碼置于這一檔案之中實際上黑名單在客觀上幫助了那些居心叵測之人。
AddType應用程式/x-httpd-php .php .htm
它們現在可以上傳任何形式的帶有php代碼的.htm檔案,然後就在你的系統内胡作非為。
例如:
<code><?php echo system("locate config"); ?></code>
很有可能上述代碼會提供攻擊者位于伺服器之内的配置名。這種攻擊的可能性是永恒的,僅僅是因為你的伺服器未保護的一個上傳。
一定要重視檔案上傳的問題,確定使用白名單政策。確定上傳檔案的形式是所允許的檔案類型。有幾種方式可以實作這一目的,最簡單的就是檢查上傳檔案的擴充名。這樣那些不适當的檔案擴充名就會被排除。但是,這不是最安全的做法。
要想實作更加安全的監管,檢查PECL擴充名,FileInfo。FileInfo檢查 檔案的内容并且根據特定的位元組順序猜測内容形式。将FileInfo與白名單政策一起使用的話會在檔案上傳的時候更加安全的保護你的系統。
19.有時最好的應用程式安全政策就是不要斷開伺服器與網絡的的連接配接。但是現實生活中是行不通的。考慮安全問題的時候,軟體和硬體同樣重要。
最安全的應用程式就是不與外界相聯系
正如前面所說,這在現實中根本就行不通。但是你可以選擇那些伺服器可以與外部網絡相聯系,那些需要布置在防火牆之内。此外還要考慮,防火牆之外的伺服器如何與之内的伺服器溝通的問題。
Session劫持,XSS, 和XSRF都是開發者必須面臨的挑戰,我并不是危言聳聽。确實在很多情況下,這就意味着末日。對于絕大多數的黑客來說,很容易突破的技術資料庫。開發人員面臨的最嚴重的問題就是程式被劫持,資料庫受到威脅,以及使用者的信任資訊在網上的傳播。
一個簡單的方法就是把資料庫伺服器移到防火牆之後,這樣就可以限制對其的通路。一旦你認識這一問題,你發現還有其它的方法幫助你保護整個系統。
20.最後一條建議,推薦讀如下科目:
《Essential PHP Security》
《Pro PHP Security》
《Professional PHP5 Security》
《php|architect's Guide to PHP Security》