PHP開發安全設定

cnbird發表於2008-07-22

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移除。

  例項指令碼:

<?php

session_start

();
$_SESSION[`data`] = time();
session_regenerate_id();
?>

檢測URL以及/tmp路徑

sess_82c6980017e100277a63983142fd454c
sess_a4bab88e6dfa6e900ade21e3fbd27a53

再次檢測

sess_984c5230acca90b5a75eddb89bb48354
sess_a4bab88e6dfa6e900ade21e3fbd27a53
sess_82c6980017e100277a63983142fd454c

  然後你可以看到如下情況

sess_984c5230acca90b5a75eddb89bb48354
  sess_a4bab88e6dfa6e900ade21e3fbd27a53
  sess_82c6980017e100277a63983142fd454c
  sess_dd88c05b724d80b30c90309847f2e919

  這些session仍然很活躍。當重新生成ID的時候移除它們採用如下程式碼:

<?php

session_start

();
$_SESSION[`data`] = time();
session_regenerate_id(true);
?>

  如果你正在使用自己的session處理器的話,這可能導致你的destroy callback功能被啟用。

  8.使用php安全主題,實際上不止一種方法可以完成任務。在很多情況下,戰術的重組可以達到最好的安全效果。我們一直在談論資訊的過濾,我們還需要警惕來自於使用者的驗證資訊。這是在日常的php應用中需要加以注意的。

  確認使用者的輸入資訊

  程式碼例項:

<?php

$myFile

= filter_var($_GET[`file`], FILTER_SANITIZE_STRING);
include(
$myFile);
?>

  點選http://example.com/file.php?file=home.php可能會導致你的指令碼包含在你的目前的目錄中的檔案home.php。但是如果有人請求http://example.com/file.php?file=badcode.php的話,你就會置身於執行程式碼的危險中,或是你不想執行的程式碼被執行。

  不要僅僅依靠file_exists(). 因為本地檔案並不意味著這是一個正確的檔案甚至那根本就不是你的檔案。不要讓黑客輕易的執行程式碼。

  為了保證安全,記住一定要過濾和確認:

<?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);
?>

  9.有時最簡單的也就是最安全的。以下的建議很簡單,但是我們很驚訝在現實生活中很少有人理解以及使用。

  不要將敏感資訊放於網上

  思考一下下面這個目錄結構:

/htdocs
  /includes
  /images
  /js

  如果你將你的資料庫的信任狀儲存於一個名為db.inc的檔案中,然後將其放於這一目錄之下,很可能就有人下載這一資料夾名下的資訊,只要他們訪問http://example.com/includes/db.inc.站點,因為絕大多數的網站伺服器並不知道如何處理這一.inc檔案,如果有訪問請求的話,它們直接被認為是純文字。後果是可怕的。如果你儲存信任狀的檔案使用的是非.php字尾名的話並且位於你的網路伺服器的根目錄之下,很可能你的資訊正在洩露。

  解決方法很簡單。將所有的敏感資訊置於網路伺服器的根目錄之外。現在也有很多專家提倡把絕大多數的php程式碼放於網路伺服器根目錄之外。因為php程式碼不限於同一個限制,你可以在根目錄的同一檔案層次之下建立一個目錄,然後將你的所有的機密資訊和程式碼放在那。

/phpinc
  /includes
  /htdocs
  /images
  /js

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檔案,然後就在你的系統內胡作非為。

  例如:

<?php

echo system("locate config");
?>

  很有可能上述程式碼會提供攻擊者位於伺服器之內的配置名。這種攻擊的可能性是永恆的,僅僅是因為你的伺服器未保護的一個上傳。

  一定要重視檔案上傳的問題,確保使用白名單政策。確保上傳檔案的形式是所允許的檔案型別。有幾種方式可以實現這一目的,最簡單的就是檢查上傳檔案的副檔名。這樣那些不適當的副檔名就會被排除。但是,這不是最安全的做法。

  要想實現更加安全的監管,檢查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》

 


相關文章