熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> PHP編程 >> 正文

理解PHP及其安全問題的入門知識

2013-11-15 12:21:04  來源: PHP編程 

  有時候您的業務可能涉及到 PHP 應用程序的安全性當您遇到審計任務時您知道如何執行查找嗎?本系列將帶您進入 PHP並幫您在一定程序上了解它讓您在進行安全審計時知道查找什麼 部分向您介紹 register_globals 設置
  
  入門知識
  
  我在此假定您對 PHP 的語法有一個大致的了解至少能夠編寫Hello World之類的程序如果您不具備基礎知識則請首先學習 PHP 手冊和某些基本的 PHP 教程(參閱 參考資料)很多出版商都有關於 PHP 的好書建議初學者一開始先看看入門書籍或食譜形式的書籍
  
  在生產環境的准確副本上執行審計您不需要復制硬件但是需要確保軟件版本盡量和實際的完全一樣PHP 配置必須精確匹配這一點在 phpini 文件中htaccess 文件的 Apache 指令中或在 中已經指定您需要准備一個單獨的環境因為您將顯示和記錄可能包含敏感的密碼及其他信息的錯誤此外您將嘗試中斷站點的安全性這一點是您在活動應用程序中極力避免的
  
  第一步是將 PHP 的 error_reporting 設置更改為 E_ALL設置更改後每當使用未初始化的變量進行錯誤的文件訪問及發生其他(大多數)無害錯誤時PHP 都會報告一條警告消息但也存在這是一個潛在攻擊矢量的可能性這些錯誤一般情況下只是表明編程草率所以如果這是您的代碼您把它們清除掉即可
  
  該設置如下所示
  
  error_reporting = E_ALL
  
  如果您不知道 phpini 文件在哪裡則可以通過創建包含以下文本的 php 腳本來查找
  
  <?php
  
  phpinfo();
  
  輸出的上面部分有一行列出了 PHP 查找 phpini 的位置
  
  
PHP 查找 phpini 的位置

  
[[The No Picture]]

  值可能會有些變化但 /usr/local/lib/phpini 是大多數 UNIX? 系統上的公共位置C:\php\phpini 或 C:\WINDOWS\phpini 是大多數 Microsoft? Windows? 系統上的公共位置如果該文件不存在則創建一個並在文件中鍵入上面的 error_reporting 行即可修改 phpini 文件後需要重啟 Web 服務器PHP 才能啟用新設置
  
  如果您以前沒有創建 phpinfo() 頁面則可以現在創建第二個主要部分的標簽是配置它包含許多關於如何設置 PHP 的有用信息該部分包括三列設置名稱本地值 和 xmaster 值主值是通過 phpini 指令為您機器上的所有 PHP 腳本全局設置的值本地值是對當前腳本生效的值對它有影響的有htaccess 設置 的 <Location> 或 <Directory> 部分中的設置和 PHP 腳本中的 ini_set 調用在運行時只有某些設置是可更改的請參閱 參考資料中的 PHP 手冊以獲取詳細信息
  
  還需要自定義的另外兩種設置是 display_errors 和 log_errors您至少需要啟用這兩種設置中的一種或者兩種都啟用log_errors 通知 PHP 將注意警告或錯誤記錄在文件中display_errors 將這些被記錄下來的注意警告和錯誤顯示在屏幕上它們不互相排斥至少啟用它們中的一個可以有效地發現可能導致安全漏洞的編程錯誤
  
  應該查找哪些種類的安全問題?
  
  值得慶幸的是導致安全漏洞的很多編程錯誤在 PHP 中不可能存在堆棧和緩沖溢出是 C 和 C++ 環境中兩個常見的問題因為 PHP 可以為您管理記憶所以 PHP 代碼不會導致堆棧和緩沖溢出
  
  然而PHP 本身也是使用 C 語言編寫的有時記憶問題深至 PHP 的核面因此您需要時時關注安全公報和更新PHP 在其 Web 站點(參見 參考資料)公布新 PHP 版本並說明是否包含安全修補程序
  
  PHP 應用程序中的大多數問題與使用用戶提供的數據有關在使用它和對它執行操作前未曾預先驗證和消毒您可能聽說過稱為 crosssite scripting (XSS) 的漏洞XSS 通過提供程序不期望的輸入然後利用程序對無賴輸入的處理方式發動進攻編寫良好的程序可以避免這些假定在機場安全方面PHP 程序用於檢查旅客的行李
  
  其他問題是一些細微的邏輯錯誤例如檢查一系列參數看看是否批准某個用戶訪問某種資源是否把括弧放錯位置以至於某些用戶進入了他們原本不該到的地方我們希望您的應用程序組織良好並具有這種集中式邏輯
  
  識別用戶輸入
  
  最棘手的一件事情是如何從外部源(如某個用戶別的 Web 站點或某些其他資源)和已經驗證的數據中區分出不受信任的輸入有人提出了不相信一切的觀點即不管來自何處對於所有函數都要驗證其數據這一做法會牽涉到以下幾件事情第一驗證在不同的上下文中意味著不同的事情第二在應用程序的所有級別上快速執行驗證是一件枯燥乏味和易於出錯的事情第三您是在審計應用程序而不是在從頭重新編寫它您需要通過現有代碼來跟蹤用戶輸入而不能用驗證函數包裝您看到的每個變量
  
  不期望的用戶輸入
  
  用戶輸入從何而來?第一個源是 GETPOST 和 COOKIE 數據一般稱為 GPC 數據此數據的可識別程序依賴於一個有爭議的 phpini 設置register_globals在 PHP V 以後register_globals 默認情況下被設置為 Off但是幾年前在 PHP 中register_globals 的默認值是打開的所以存在很多需要它的代碼
  
  register_globals 本身並非安全風險但是它為跟蹤用戶輸入和確保應用程序安全增加了難度為什麼會這樣?因為如果打開 register_globals在全局名稱空間和 $_GET$_POST 或 $_COOKIE 數組中將創建 GETPOST 和 COOKIE 傳遞到 PHP 腳本的所有變量
  
  下面是工作方式及其重要性的示例
  
  清單 COOKIE 的安全性
  
   <?php
  
   // See if the user has the secret cookie
   if (!empty($_COOKIE[secret])) {
    $authorized = true;
   }
  
   // Now lets go through a list of press releases and show them
   $releases = get_press_releases();
   foreach ($releases as $release) {
  
     // Some releases are restricted Only show them to people who can
     // see secrets
     if ($release[secret]) {
       if (!$authorized) {
         continue;
       }
     }
  
     // We must be allowed to see it
     showRelease($release);
   }
  
  您應該注意幾件事第一依靠 cookie 來判斷用戶是否已通過身份驗證不是個好主意 —— 因為人們可以很容易地設置自己的 cookie 值我們將在另外一篇文章中敘述這一點無論如何此腳本的缺點在於如果打開 register_globals它就不具備安全性了
  
  下面介紹名為 pressphp 的腳本一般來說當用戶訪問 press 發行版的腳本時其浏覽器將顯示
  
  現在注意當用戶擅自將其更改為 ?authorized= 時將發生什麼事?
  
  看看前面的代碼僅當用戶使用 cookie 時才設置 $authorized它永遠不會被設置為假後來引入了 register_globals —— 它取代了剛才使用的 $_GET[authorized]同時在全局范圍內還存在一個值為 的變量 $authorized因此即使用戶沒有通過 cookie 檢查$authorized 後來在 foreach 循環中引用時仍然會被驗證為真
  
  修復此缺陷可以使用兩種方式其一當然是關閉 register_globals如果關閉它對您的生產站點沒有影響則這是個好主意您需要測試一下應用程序確保它沒有因此中斷運行
  
  另一種方式有點像防御性編程我們只需要將 cookie 檢查更改為以下形式即可
  
  清單 使用 COOKIE 提高安全性
  
   <?php
  
   // See if the user has the secret cookie
   $authorized = false;
   if (!empty($_COOKIE[secret])) {
    $authorized = true;
   }
  
  
  
  這時當用戶將 ?authorized= 添加到腳本 URL 時$authorized 變量仍然被設置為 —— 但是它隨即會被 $authorized = false 覆蓋只有那些實際具有秘密 cookie 的用戶才能看到受限的 press 發行版他們仍然可以設計自己的 cookie
  
  審計代碼的教訓設法關閉 register_globals如果不打開 register_globals 應用程序就不能運行並且您無法修改它或者在應用程序必須運行的地方您無法控制 PHP 配置則需要在條件塊中查找所有全局變量設置或者通過某些函數調用進入全局范圍如果 register_globals 為打開狀態則這兩種情形都是由用戶將變量設置為任意值引起的
  
  找到這些變量的好辦法是將 phpini 設置 error_reporting 設置為 E_ALL同時使用 log_errors 或 display_errors這樣所有 PHP 警告和錯誤都會被分別記錄在文件中或顯示在屏幕上每當使用未初始化的變量(假定具有值)時您將得到一條 E_NOTICE這像 C 和 Java? 語言中那樣仍然與讓 PHP 要求聲明 變量有所不同結果當我們的第一個版本的腳本運行時出現的錯誤消息是
  
  Notice: Undefined variable: authorized in C:\var\www\articles\pressphp
  on line
From:http://tw.wingwit.com/Article/program/PHP/201311/20776.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.