PHP安全配置规范

PHP安全配置规范

一、 说明

本文件中所有的配置选项无特殊说明,均为系统的php.ini文件。由于可能各个系统使用的PHP版本不一样,PHP的默认选项也可能不一样,为方便操作,要求所有检查的配置项必须在配置文件中明确写出。

二、 检查的配置项

1. 启用PHP安全模式

safe_mode = On

或者修改httpd.conf,定义目录:

php_admin_value safe_mode 1

启用safe_mode,会对许多PHP函数进行限制,特别是和系统相关的文件打开、命令执行等函数。所有操作文件的函数将只能操作与脚本UID相同的文件。能在很大程度上提高PHP应用的安全性。


2. 用户组安全

safe_mode打开时,safe_mode_gid被关闭,那么php脚本能够对文件进行访问,而且相同组的用户也能够对文件进行访问。

建议设置为:

safe_mode_gid = off

如果不进行设置,可能我们无法对我们服务器网站目录下的文件进行操作了,比如我们需要对文件进行操作的时候。

参考:http://php.net/manual/zh/ini.sect.safe-mode.php


3. 关闭注册全局变量

register_globals = Off

PHP默认register_globals = On,对于GET, POST, Cookie, Environment, Session的变量可以直接注册成全局变量。它们的注册顺序是variables_order = "EGPCS"(可以通过php.ini修改),同名变量variables_order右边的覆盖左边,所以变量的滥用极易造成程序的混乱。

攻击者能通过提交数据来给PHP应用中的未初始化变量赋值,改变代码逻辑,产生安全问题。


4. 关闭远程文件操作(allow_url_fopen = On allow_url_include = Off 业务需求)

allow_url_fopen = Off

allow_url_include=Off

PHP的远程文件包含和远程文件操作功能在通常的应用中都不会用到,如果PHP代码在文件操作或是文件包含的时候对其变量不作严格的检查,攻击者就可以通过改变这些变量的值来包含远程机器上的恶意文件,并在WEB服务器上运行任意代码。


5. 打开引号转义

magic_quotes_gpc = On

如果PHP代码中没有对用户输入数据中的特殊字符作过滤就直接用于构造SQL查询串,将产生SQL注入漏洞。

该选项使得从GET, POST, COOKIE来的变量自动加了addslashes()操作,对输入字符串中的单引号,双引号,括号会进行转义操作,虽不能通过打开这个选项来完全解决 SQL注入问题,但能在一定程度上加大注入的难度。


三、 建议的配置项

1. 禁止显示警告和错误信息

修改php.ini中关于Error handling and logging部分内容:

error_reporting = E_ALL

display_errors = Off

log_errors = On

error_log = /usr/local/apache/logs/php_error.log

关掉PHP的错误信息显示,并把PHP的所有警告及错误信息记录到一个日志文件是非常明智的,即不给攻击者泄漏物理路径,又能知道程序错误所在。


2. 限制PHP能操作的文件目录(不满足,由于未启用安全模式)


open_basedir =/var/www/


限制PHP代码中文件操作函数能操作的目录,防止代码中的错误或是受到攻击时能破坏的文件范围。建议根据具体使用要求,进一步细化配置值。


3. 禁止动态加载模块

enable_dl=off

动态加载模块功能可能会被用于加载一些外部模块来突破PHP本身的一些安全限制。

如果没有动态动态加载模块的需求,建议关闭这个选项。


4. 禁止部分函数和类

设置php.ini里的disable_functions(这个选项不能在httpd.conf里设置)

禁用方法如下:

打开php.ini文件,

查找到 disable_functions ,添加需禁用的函数名,如下:

phpinfo,eval,passthru,exec,system,chroot,scandir,chgrp,chown,shell_exec,proc_open,proc_get_status,ini_alter,ini_alter,ini_restore,dl,pfsockopen,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server,fsocket,fsockopen

phpinfo()

功能描述:输出 PHP 环境信息以及相关的模块、WEB 环境等信息。

危险等级:中

passthru()

功能描述:允许执行一个外部程序并回显输出,类似于 exec()

危险等级:高

exec()

功能描述:允许执行一个外部程序(如 UNIX Shell CMD 命令等)。

危险等级:高

system()

功能描述:允许执行一个外部程序并回显输出,类似于 passthru()

危险等级:高

chroot()

功能描述:可改变当前 PHP 进程的工作根目录,仅当系统支持 CLI 模式

PHP 时才能工作,且该函数不适用于 Windows 系统。

危险等级:高

scandir()

功能描述:列出指定路径中的文件和目录。

危险等级:中

chgrp()

功能描述:改变文件或目录所属的用户组。

危险等级:高

chown()

功能描述:改变文件或目录的所有者。

危险等级:高

shell_exec()

功能描述:通过 Shell 执行命令,并将执行结果作为字符串返回。

危险等级:高

proc_open()

功能描述:执行一个命令并打开文件指针用于读取以及写入。

危险等级:高

proc_get_status()

功能描述:获取使用 proc_open() 所打开进程的信息。

危险等级:高

error_log()

功能描述:将错误信息发送到指定位置(文件)。

安全备注:在某些版本的 PHP 中,可使用 error_log() 绕过 PHP safe mode

执行任意命令。

危险等级:低

ini_alter()

功能描述:是 ini_set() 函数的一个别名函数,功能与 ini_set() 相同。

具体参见 ini_set()

危险等级:高

ini_set()

功能描述:可用于修改、设置 PHP 环境配置参数。

危险等级:高

ini_restore()

功能描述:可用于恢复 PHP 环境配置参数到其初始值。

危险等级:高

dl()

功能描述:在 PHP 进行运行过程当中(而非启动时)加载一个 PHP 外部模块。

危险等级:高

pfsockopen()

功能描述:建立一个 Internet UNIX 域的 socket 持久连接。

危险等级:高

syslog()

功能描述:可调用 UNIX 系统的系统层 syslog() 函数。

危险等级:中

readlink()

功能描述:返回符号连接指向的目标文件内容。

危险等级:中

symlink()

功能描述:在 UNIX 系统中建立一个符号链接。

危险等级:高

popen()

功能描述:可通过 popen() 的参数传递一条命令,并对 popen() 所打开的文件进行执行。

危险等级:高

stream_socket_server()

功能描述:建立一个 Internet UNIX 服务器连接。

危险等级:中

putenv()

功能描述:用于在 PHP 运行时改变系统字符集环境。在低于 5.2.6 版本的 PHP 中,可利用该函数

修改系统字符集环境后,利用 sendmail 指令发送特殊参数执行系统 SHELL 命令。

危险等级:高

 

四、 安全模式限制函数


函数名 限制

dbmopen() 检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。

dbase_open() 检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。

filepro() 检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。

filepro_rowcount() 检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。

filepro_retrieve() 检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。

ifx_* sql_safe_mode 限制, (!= safe mode)

ingres_* sql_safe_mode 限制, (!= safe mode)

mysql_* sql_safe_mode 限制, (!= safe mode)

pg_loimport() 检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。

posix_mkfifo() 检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。

putenv() 遵循 ini 设置的 safe_mode_protected_env_vars safe_mode_allowed_env_vars 选项。请参考 putenv() 函数的有关文档。

move_uploaded_file() 检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。

chdir() 检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。

dl() 本函数在安全模式下被禁用。

backtick operator 本函数在安全模式下被禁用。

shell_exec()(在功能上和 backticks 函数相同) 本函数在安全模式下被禁用。

exec() 只能在 safe_mode_exec_dir 设置的目录下进行执行操作。基于某些原因,目前不能在可执行对象的路径中使用 ..escapeshellcmd() 将被作用于此函数的参数上。

system() 只能在 safe_mode_exec_dir 设置的目录下进行执行操作。基于某些原因,目前不能在可执行对象的路径中使用 ..escapeshellcmd() 将被作用于此函数的参数上。

passthru() 只能在 safe_mode_exec_dir 设置的目录下进行执行操作。基于某些原因,目前不能在可执行对象的路径中使用 ..escapeshellcmd() 将被作用于此函数的参数上。

popen() 只能在 safe_mode_exec_dir 设置的目录下进行执行操作。基于某些原因,目前不能在可执行对象的路径中使用 ..escapeshellcmd() 将被作用于此函数的参数上。

fopen() 检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。

mkdir() 检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。

rmdir() 检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。

rename() 检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。

unlink() 检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。

copy() 检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。 (on source and target)

chgrp() 检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。

chown() 检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。

chmod() 检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。 另外,不能设置 SUIDSGID sticky bits

touch() 检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。

symlink() 检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。 (注意:仅测试 target

link() 检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。 (注意:仅测试 target

apache_request_headers() 在安全模式下,以“authorization”(区分大小写)开头的标头将不会被返回。

header() 在安全模式下,如果设置了 WWW-Authenticate,当前脚本的 uid 将被添加到该标头的 realm 部分。

PHP_AUTH 变量 在安全模式下,变量 PHP_AUTH_USERPHP_AUTH_PW PHP_AUTH_TYPE $_SERVER 中不可用。但无论如何,您仍然可以使用 REMOTE_USER 来获取用户名称(USER)。(注意:仅 PHP 4.3.0 以后有效)

highlight_file(), show_source() 检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。 (注意,仅在 4.2.1 版本后有效)

parse_ini_file() 检查被操作的文件或目录是否与正在执行的脚本有相同的 UID(所有者)。 检查被操作的目录是否与正在执行的脚本有相同的 UID(所有者)。 (注意,仅在 4.2.1 版本后有效)

set_time_limit() 在安全模式下不起作用。

max_execution_time 在安全模式下不起作用。

mail() 在安全模式下,第五个参数被屏蔽。(注意,仅自 PHP 4.2.3 起受影响)

 

你可能感兴趣的:(php)