close

安全模式 safe_mode

PHP 的安全模式是為了試圖解決共享伺服器(shared-server)安全問題而設立的。在結構上,試圖在 PHP 層上解決這個問題是不合理的,但修改 WEB 伺服器層和操作系統層顯得非常不現實。因此許多人,特別是 ISP,目前使用安全模式。


保安措施和安全模式


表格 22-1. 保安措施和安全模式配置指令

名稱預設值作用範圍
safe_mode"0"PHP_INI_SYSTEM
safe_mode_gid"0"PHP_INI_SYSTEM
safe_mode_include_dirNULLPHP_INI_SYSTEM
safe_mode_exec_dir""PHP_INI_SYSTEM
safe_mode_allowed_env_varsPHP_PHP_INI_SYSTEM
safe_mode_protected_env_varsLD_LIBRARY_PATHPHP_INI_SYSTEM
open_basedirNULLPHP_INI_SYSTEM
disable_functions""PHP_INI_SYSTEM
PHP_INI_* 常數的進一步詳細說明與定義見 ini_set()


這裡是配置指令的一些簡短解釋。

safe_mode boolean

是否啟用 PHP 的安全模式。更多訊息請閱讀安全一章。

safe_mode_gid boolean

預定情況下,安全模式在打開文件時會做 UID 比較檢查。如果你想將其放寬到 GID 比較,則打開 safe_mode_gid。是否在文件連接時使用 UIDFALSE)或者 GIDTRUE)來做檢查。

safe_mode_include_dir string

當從此目錄及其子目錄(目錄必須在 include_path 中或者用完整路徑來包含)包含文件時越過 UID/GID 檢查。

從 PHP 4.2.0 開始,本指令可以接受和 include_path 指令類似的風格用分號隔開的路徑,而不只是一個目錄。

safe_mode_exec_dir string

如果 PHP 使用了安全模式,system() 和其它執行系統程序的函式將拒絕啟動不在此目錄中的程序。

safe_mode_allowed_env_vars string

設置某些環境變數可能是潛在的安全缺口。本指令包含有一個逗號分隔的前綴列表。在安全模式下,用戶只能改變那些名字具有在這裡提供的前綴的環境變數。預定情況下,用戶只能設置以 PHP_ 開頭的環境變數(例如 PHP_FOO = BAR)。

註: 如果本指令為空,PHP 將使用戶可以修改任何環境變數!

safe_mode_protected_env_vars string

本指令包含有一個逗號分隔的環境變數的列表,最終用戶不能用 putenv() 來改變這些環境變數。甚至在 safe_mode_allowed_env_vars 中設置了允許修改時也不能改變這些變數。

open_basedir string

將 PHP 所能打開的文件限制在指定的目錄樹。本指令不受安全模式打開或者關閉的影響。

當一個腳本試圖用例如 fopen 或者 gzopen 打開一個文件時,該文件的位置將被檢查。當文件在指定的目錄樹之外時 PHP 將拒絕打開它。所有的符號連接都會被解析,所以不可能通過符號連接來避開此限制。

特殊值 . 指定了存放該腳本的目錄將被當做基准目錄。

在 Windows 中,用分號分隔目錄。在任何其它系統中用冒號分隔目錄。作為 Apache 模塊時,父目錄中的 open_basedir 路徑自動被繼承。

用 open_basedir 指定的限制實際上是前綴,不是目錄名。也就是說 "open_basedir = /dir/incl" 也會允許連接 "/dir/include" 和 "/dir/incls",如果它們存在的話。如果要將連接限制在僅為指定的目錄,用斜線結束路徑名。例如:"open_basedir = /dir/incl/"。

註: 支援多個目錄是 3.0.7 加入的。

預定是允許打開所有文件。

disable_functions string

本指令允許你基於安全原因禁止某些函式。接受逗號分隔的函式名列表作為參數。 disable_functions 不受安全模式的影響。

本指令只能設置在 php.ini 中。例如你不能將其設置在 httpd.conf

參見 register_globalsdisplay_errorslog_errors

safe_mode 設置為 on,PHP 將檢查當前腳本的擁有者是否和將被文件函式操作的文件的擁有者相匹配。例如:

-rw-rw-r--    1 rasmus   rasmus       33 Jul  1 19:20 script.php 
-rw-r--r-- 1 root root 1116 May 26 18:01 /etc/passwd

執行 script.php
<?php
readfile('/etc/passwd');
?>

如果安全模式被啟動,則將會導致以下錯誤:
Warning: SAFE MODE Restriction in effect. The script whose uid is 500 is not 
allowed to access /etc/passwd owned by uid 0 in /docroot/script.php on line 2


同時,或許會存在這樣的環境,在該環境下,寬松的 GID 檢查已經足夠,但嚴格的 UID 檢查反而是不適合的。您可以用 safe_mode_gid 選項來控制這種檢查。如果設置為 On 則進行寬松的 GID 檢查;設置為 Off(預設值)則進行 UID 檢查。

除了 safe_mode 以外,如果您設置了 open_basedir 選項,則所有的文件操作將被限制在您指定的目錄下。例如:

<Directory /docroot>
php_admin_value open_basedir /docroot
</Directory>

如果您在設置了 open_basedir 選項後執行同樣的 script.php,則其結果會是:
Warning: open_basedir restriction in effect. File is in wrong directory in 
/docroot/script.php on line 2


您也可以單獨地屏蔽某些函式。請注意 disable_functions 選項不能在 php.ini 文件外部使用,也就是說您無法在 httpd.conf 文件的按不同虛擬主機或不同目錄的方式來屏蔽函式。 如果我們將如下內容加入到 php.ini 文件:

disable_functions readfile,system

則我們會得到如下的輸出:
Warning: readfile() has been disabled for security reasons in 
/docroot/script.php on line 2

arrow
arrow
    全站熱搜

    kevin0523 發表在 痞客邦 留言(0) 人氣()