有時候
您的業務可能涉及到 PHP 應用程序的安全性
當您遇到審計任務時
您知道如何執行查找嗎?本系列將帶您進入 PHP
並幫您在一定程序上了解它
讓您在進行安全審計時知道查找什麼
第
部分向您介紹 register_globals 設置
入門知識 我在此假定您對 PHP 的語法有一個大致的了解
至少能夠編寫
Hello World
之類的程序
如果您不具備基礎知識
則請首先學習 PHP 手冊和某些基本的 PHP 教程(參閱 參考資料)
很多出版商都有關於 PHP 的好書
建議初學者一開始先看看入門書籍或食譜形式的書籍
在生產環境的准確副本上執行審計
您不需要復制硬件
但是需要確保軟件版本盡量和實際的完全一樣
PHP 配置必須精確匹配
這一點在 php
ini 文件中
在
htaccess 文件的 Apache 指令中或在 中已經指定
您需要准備一個單獨的環境
因為您將顯示和記錄可能包含敏感的密碼及其他信息的錯誤
此外
您將嘗試中斷站點的安全性
這一點是您在活動應用程序中極力避免的
第一步是將 PHP 的 error_reporting 設置更改為 E_ALL
設置更改後
每當使用未初始化的變量
進行錯誤的文件訪問及發生其他(大多數)無害錯誤時
PHP 都會報告一條警告消息
但也存在這是一個潛在攻擊矢量的可能性
這些錯誤一般情況下只是表明編程草率
所以如果這是您的代碼
您把它們清除掉即可
該設置如下所示 error_reporting = E_ALL
如果您不知道 php
ini 文件在哪裡
則可以通過創建包含以下文本的
php 腳本來查找
<?php
phpinfo();
輸出的上面部分有一行列出了 PHP 查找 php
ini 的位置
圖 PHP 查找 phpini 的位置 [[The No Picture]] 值可能會有些變化
但 /usr/local/lib/php
ini 是大多數 UNIX? 系統上的公共位置
C:\php\php
ini 或 C:\WINDOWS\php
ini 是大多數 Microsoft? Windows? 系統上的公共位置
如果該文件不存在
則創建一個並在文件中鍵入上面的 error_reporting 行即可
修改 php
ini 文件後
需要重啟 Web 服務器
PHP 才能啟用新設置
如果您以前沒有創建 phpinfo() 頁面
則可以現在創建
第二個主要部分的標簽是
配置
它包含許多關於如何設置 PHP 的有用信息
該部分包括三列
設置名稱
本地值 和 xmaster 值
主值是通過 php
ini 指令為您機器上的所有 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 應用程序中的大多數問題與使用用戶提供的數據有關
在使用它和對它執行操作前未曾預先驗證和消毒
您可能聽說過稱為 cross
site scripting (XSS) 的漏洞
XSS 通過提供程序不期望的輸入
然後利用程序對無賴輸入的處理方式發動進攻
編寫良好的程序可以避免這些假定
在機場安全方面
PHP 程序用於檢查旅客的行李
其他問題是一些細微的邏輯錯誤
例如
檢查一系列參數
看看是否批准某個用戶訪問某種資源
是否把括弧放錯位置以至於某些用戶進入了他們原本不該到的地方
我們希望您的應用程序組織良好並具有這種集中式邏輯
識別用戶輸入 最棘手的一件事情是如何從外部源(如某個用戶
別的 Web 站點或某些其他資源)和已經驗證的數據中區分出不受信任的輸入
有人提出了
不相信一切
的觀點
即不管來自何處
對於所有函數都要驗證其數據
這一做法會牽涉到以下幾件事情
第一
驗證在不同的上下文中意味著不同的事情
第二
在應用程序的所有級別上快速執行驗證是一件枯燥乏味和易於出錯的事情
第三
您是在審計應用程序而不是在從頭重新編寫它
您需要通過現有代碼來跟蹤用戶輸入
而不能用驗證函數包裝您看到的每個變量
不期望的用戶輸入 用戶輸入從何而來?第一個源是 GET
POST 和 COOKIE 數據
一般稱為 GPC 數據
此數據的可識別程序依賴於一個有爭議的 php
ini 設置
register_globals
在 PHP V
以後
register_globals 默認情況下被設置為 Off
但是幾年前
在 PHP 中
register_globals 的默認值是打開的
所以存在很多需要它的代碼
register_globals 本身並非安全風險
但是
它為跟蹤用戶輸入和確保應用程序安全增加了難度
為什麼會這樣?因為如果打開 register_globals
在全局名稱空間和 $_GET
$_POST 或 $_COOKIE 數組中
將創建 GET
POST 和 COOKIE 傳遞到 PHP 腳本的所有變量
下面是工作方式及其重要性的示例
清單
COOKIE 的安全性
<?php
// See if the user has the secret cookie
if (!empty($_COOKIE[
secret
])) {
$authorized = true;
}
// Now let
s 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
它就不具備安全性了
下面介紹名為 press
php 的腳本
一般來說
當用戶訪問 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 為打開狀態
則這兩種情形都是由用戶將變量設置為任意值引起的
找到這些變量的好辦法是將 php
ini 設置 error_reporting 設置為 E_ALL
同時使用 log_errors 或 display_errors
這樣
所有 PHP 警告和錯誤都會被分別記錄在文件中或顯示在屏幕上
每當使用未初始化的變量(假定具有值)時
您將得到一條 E_NOTICE
這像 C 和 Java? 語言中那樣
仍然與讓 PHP 要求聲明 變量有所不同
結果
當我們的第一個版本的腳本運行時
出現的錯誤消息是
Notice: Undefined variable: authorized in C:\var\www\articles\press
php
on line
From:http://tw.wingwit.com/Article/program/PHP/201311/20776.html