PHP是一种开源服务器端脚本语言,应用很广泛。Apache web服务器提供了这种便利:通过HTTP或HTTPS协议,访问文件和内容。配置不当的服务器端脚本语言会带来各种各样的问题。所以,使用PHP时要小心。以下是25个PHP安全方面的最佳实践,可供系统管理员们安全地配置PHP。 为PHP安全提示而提供的示例环境 文件根目录(DocumentRoot):/var/www/html 默认的Web服务器:Apache(可以使用Lighttpd或Nginx来取代Apache) 默认的PHP配置文件:/etc/php.ini 默认的PHP加载模块配置目录:/etc/php.d/ 我们的示例php安全配置文件:/etc/php.d/security.ini(需要使用文本编辑器来创建该文件) 操作系统:RHEL/CentOS/Fedora Linux(相关指令应该与Debian/Ubuntu等其他任何Linux发行版或者OpenBSD/FreeBSD/HP-UX等其他类似Unix的操作系统兼容)。 默认的php服务器TCP/UDP端口:无 为本文所列的大多数操作编写代码时,假定它们将由运行bash外壳程序或其他任何现代外壳程序的根用户来执行: $ php -v 示例输出: PHP 5.3.3 (cli) (built: Oct 24 2011 08:35:41) Copyright (c) 1997-2010 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies 出于演示的用途,我会使用以下操作系统: $ cat /etc/redhat-release 示例输出: Red Hat Enterprise Linux Server release 6.1 (Santiago) 第1个最佳实践:了解你的对手 基于PHP的应用程序面临不同类型的攻击。我注意到了几种不同类型的攻击: 1. XSS:跨站脚本是Web PHP应用程序中的一种安全漏洞,攻击者可以利用该漏洞来窃取用户的信息。你可以配置Apache,编写更安全的PHP脚本(验证所有的用户输入),以避免XSS攻击。 2. SQL注入攻击:这是PHP应用程序的数据库层中的安全漏洞。用户输入不正确地过滤时,应用程序就能执行任何SQL语句。你可以配置Apache,编写安全代码(验证和转换所有的用户输入),以避免SQL注入攻击。PHP中的一个常见做法是,在发送SQL查询之前,使用名为mysql_real_escape_string()的函数,转换参数。 3. 文件上传:它让访客可以将文件放在(将文件上传到)你的服务器上。这会带来众多安全问题,比如删除你的文件、删除数据库、获取用户详细资料,不一而足。你可以使用php来禁用文件上传,或编写安全代码(比如验证用户输入,只允许PNG或GIF等图像文件类型)。 4. 添加本地和远程文件:攻击者可以从远程服务器打开文件,执行任何PHP代码。这让他们得以上传文件、删除文件和安装后门。可以配置php以禁用远程文件执行功能。 5. eval() :将字符串作为PHP代码来进行评估。攻击者常常利用该函数来隐藏其在服务器本身上面的代码和工具。你可以配置PHP,禁用eval()。 6. sea-surf攻击(跨站请求伪造,CSRF):这种攻击迫使最终用户针对目前已验证其身份的Web应用程序执行有害的操作。如果是平常的用户,得逞的CSRF攻击会危及最终用户的数据和操作。但如果被盯上的最终用户使用管理员帐户,这会危及整个Web应用程序。 第2个最佳实践:查找内置的PHP模块 想查看一组编译进去的PHP模块,请输入以下命令: # php -m 示例输出: [PHP模块] apc bcmath bz2 calendar Core ctype curl date dom ereg exif fileinfo filter ftp gd gettext gmp hash iconv imap json libxml mbstring memcache mysql mysqli openssl pcntl pcre PDO pdo_mysql pdo_sqlite Phar readline Reflection session shmop SimpleXML sockets SPL sqlite3 standard suhosin tokenizer wddx xml xmlreader xmlrpc xmlwriter xsl zip zlib [Zend模块] Suhosin 我建议你使用模块数量减少的PHP,以增强性能和安全。比如说,你可以通过删除(移除)配置文件或者更名(或移动)一个名为/etc/php.d/sqlite3.ini的文件来禁用sqlite3模块,操作如下: # rm /etc/php.d/sqlite3.ini 或者 # mv /etc/php.d/sqlite3.ini /etc/php.d/sqlite3.disable 其他编译进去的模块只能通过重新安装精简配置的PHP来移除。可以从php.net下载php源代码,然后按以下方法编译它,支持GD、fastcgi和MySQL: ./configure --with-libdir=lib64 --with-gd --with-mysql --prefix=/usr --exec-prefix=/usr 第3个最佳实践:限制PHP信息泄露 要限制PHP信息泄露,就要禁用expose_php。编辑/etc/php.d/secutity.ini,执行以下指令: expose_php=Off 启用后,expose_php向外界报告PHP安装在服务器上,这包括HTTP头里面的PHP版本(如X-Powered-By: PHP/5.3.3)。PHP标识的全局唯一标识符(GUID,见示例9568F34-D428-11d2-A769-00AA001ACF42)也显示出来,因而将它们添加到支持PHP的网站的URL后面,就会显示相应标识。expose_php启用后,你可以使用以下命令,查看PHP版本: $ curl -I 示例输出: HTTP/1.1 200 OK X-Powered-By: PHP/5.3.3 Content-type: text/html; charset=UTF-8 Vary: Accept-Encoding, Cookie X-Vary-Options: Accept-Encoding;list-contains=gzip,Cookie;string-contains=wikiToken;string-contains=wikiLoggedOut;string-contains=wiki_session Last-Modified: Thu, 03 Nov 2011 22:32:55 GMT ... 我还建议,你应在httpd.conf中执行ServerTokens和ServerSignature命令,隐藏Apache版本及其他信息()。 第4个最佳实践:尽量减少可装入的PHP模块(动态加载模块) PHP支持“动态加载模块”(Dynamic Extensions)。默认情况下,RHEL装入/etc/php.d/目录里面的所有加载模块。要启用或禁用某一个模块,只要在/etc/php.d/目录中找到配置文件、为模块名称添加注释。你还可以更名或删除模块配置文件。想获得最佳的PHP性能和安全,你应该只启用Web应用程序需要的加载模块。比如说,要禁用gd加载模块,输入以下命令: # cd /etc/php.d/ # mv gd.{ini,disable} # /sbin/service httpd restart 要启用名为gd的php模块,请输入: # mv gd.{disable,ini} # /sbin/service httpd restart 第5个最佳实践:将所有PHP错误记入日志 别让PHP错误信息暴露在网站的所有访客面前。编辑/etc/php.d/security.ini,执行以下指令: display_errors=Off 确保你将所有PHP错误记入到日志文件中(): log_errors=On error_log=/var/log/httpd/php_scripts_error.log 第6个最佳实践:不允许上传文件 出于安全原因,编辑/etc/php.d/security.ini,执行以下命令: file_uploads=Off 如果使用你应用程序的用户需要上传文件,只要设置upload_max_filesize(),即可启用该功能,该设置限制了PHP允许通过上传的文件的最大值: file_uploads=On # 用户通过PHP上传的文件最大1MB upload_max_filesize=1M 第7个最佳实践:关闭远程代码执行 如果启用,allow_url_fopen允许PHP的文件函数——如file_get_contents()、include语句和require语句——可以从远程地方(如FTP或网站)获取数据。 allow_url_fopen选项允许PHP的文件函数——如file_get_contents()、include语句和require语句——可以使用FTP或HTTP协议,从远程地方获取数据。编程员们常常忘了这一点,将用户提供的数据传送给这些函数时,没有进行适当的输入过滤,因而给代码注入安全漏洞留下了隐患。基于PHP的Web应用程序中存在的众多代码注入安全漏洞是由启用allow_url_fopen和糟糕的输入过滤共同引起的。编辑/etc/php.d/security.ini,执行以下指令:
信息发布:广州名易软件有限公司 http://www.myidp.net
|