PHP安全漏洞防范研究

时间:2022-10-05 06:04:58

PHP安全漏洞防范研究

【 摘 要 】 文章分别从网站开发和网站管理的角度,研究了PHP安全漏洞的防范。这样一来,只要网站开发人员和网站管理人员不同时出现工作失误,就不会发生重大网站安全事故。

【 关键词 】 PHP安全漏洞;PHP开发安全;PHP安全配置

1 引言

PHP因其功能强大、入门简单、代码执行效率高等优点,成为了Web应用开发的流行语言。由于使用广泛,所以利用PHP安全漏洞对Web网站进行的攻击也越来越多,这给Web应用的安全带来了严重威胁。

对网站的安全负有直接责任的主要有两类人员:一类是网站开发人员;一类是网站管理人员。本文分别从网站开发和网站管理的角度,对PHP安全漏洞的防范进行了较为全面的总结、研究。

2 PHP网站开发过程中产生的安全漏洞及其防范

从网站开发的角度出发,研究在程序的开发过程中,如何避免PHP安全漏洞的产生,从而开发出较为安全的PHP网站。

对以往大量攻击案例的研究表明,PHP安全漏洞的产生原因主要是没有对用户的输入进行严格的验证和对系统的输出没有进行适当的转义。用户的输入永远是不可以盲目相信的,在没有进行验证前,都可以认为是被污染数据。系统的输出在没有适当转义前,也有可能带来较大的安全风险。

2.1 未对用户输入进行严格验证产生安全漏洞及其防范

考虑一个系统的登录验证,此系统要求用注册时所填的邮箱和密码登录。一般情况下,只要输入正确即可登录,如果输入错误则不允许登录,这是通常的处理流程。其程序实现一般是,通过一个登录表单获取用户输入的邮箱和密码,然后传递给程序以构造一个SQL查询语句,例如:select count(*) from users where email='' and password='mypass',再将此SQL语句提交给后台数据库执行,若返回的记录数为0,则说明输入的邮箱信息或密码有误或用户根本没有注册,系统拒绝其登录,反之则为合法用户,允许其登录。这套验证流程对于一般的客户是十分奏效的,其若没有注册亦或没有输入正确的邮箱和密码都是不能登录系统的。但对于黑客来说,情况就不一样了。其完全可以精心设计一个字符串来代替合法邮箱地址从而绕过系统的验证,例如:若黑客输入的邮箱地址是“myemail' or 1=1--”、密码是“myppass”,此时,SQL语句变为:select count(*) from users where email='myemail' or 1=1--' and password='mypass',此语句执行后所返回的记录数是users表的所有记录总数,并不为0,所以通过了系统的登录验证,系统允许其登录。这就是著名的SQL注入攻击。导致这个后果的原因是黑客精心构造了一个字符串用于代替合法邮箱地址且系统并未对用户输入的数据本身进行合法性检查。

为了对上述PHP安全漏洞进行防范,我们可以对用户的输入进行合法性验证。

此处要求输入的是邮箱地址,为了对用户输入的数据本身进行合法性检查,我们可以用正则表达式对用户输入的邮箱地址进行验证,看是否符合正确的邮箱格式,这样就可以大大增加黑客设计特殊字符串的难度,在一定程度上防止SQL注入漏洞的产生。

在任何情况下,如果对用户的输入均进行严格的验证(当然,验证方法根据不同情况而有所不同,并不局限于正则表达式),这就可以在很大程度上对PHP安全漏洞进行防范。

2.2 未对系统的输出进行适当转义产生安全漏洞及其防范

未对系统的输出进行适当转义也会产生安全漏洞,跨站脚本漏洞就是一个很著名的例子。假设有一个可以发表评论的系统,其采用表单的形式进行数据提交。对于一般用户,这不会有什么太大问题,但是对于黑客,问题就来了。因为黑客并不是真的想发表什么评论,其有可能是想盗取其他登录用户的cookies。为了盗取其他登录用户的cookies,黑客可以将如下Javascript代码作为评论内容进行提交:

document.location = 'http:///hook.php?cookies='+document.cookie

如果在输出前对黑客所提交的内容不做任何转义的话,那么此段Javascript代码将被其他用户的浏览器所执行,从而将浏览评论的其他登录用户的cookies发送到http:///hook.php,黑客只要利用$_GET['cookies']就可以获取到盗窃的cookies了。

这就是跨站脚本漏洞的一个经典攻击实例。

为了防范上述跨站脚本漏洞攻击,我们所要采取的措施很简单:在将评论内容输出到客户端浏览器之前,利用htmlentities()函数对输出内容进行转义。此函数可以将输出内容中可能包含的html标签转换成html实体,从而使得黑客输入的Javascript代码不被执行。

任何情况下,对于系统的输出都应该进行适当的转义(转义方法根据不同情况而有所不同,并不局限于htmlentities()函数),这样才不会让黑客有机可乘。

3 合理进行PHP安全配置防范PHP安全漏洞

上面从网站开发的角度,研究了怎样开发出安全的PHP网站。但是,如果开发人员缺乏安全意识或者经验不足,开发出的网站不够安全,如何弥补呢?这就是本节要解决的问题。本节站在网站管理的角度,讨论了如何对PHP网站进行安全配置,以此防范PHP安全漏洞。

3.1 打开安全模式

如同微软的操作系统有一个“安全模式”一样,PHP也可以运行在“安全模式”下。PHP的安全模式是一个PHP内嵌的安全机制,当PHP运行在安全模式下时,有许多可能导致安全问题的函数将会被忽略或功能受到限制,以此提高系统的安全性。

打开方法如下:将php.ini文件中的safe_mode选项设定为On,即safe_mode=On。

打开安全模式后注意事项。

(1)默认情况下,在安全模式下打开文件,PHP会做UID比较检查,这是一种比GID更为严格的检查方式,但有可能会带来一些麻烦和不便。所以,若要执行宽松一些的检查,可以打开safe_mode_gid选项,即safe_mode_gid = On。

(2)在安全模式下,若要执行某些特定程序(一般情况下是不需要的,也不推荐执行),需要将safe_mode_exec_dir选项的值设定为该程序所在目录路径,否则无法执行,为了安全起见,建议创建一个特定目录用来存放这些要执行的程序而不要将其存放在系统程序所在目录,例如:safe_mode_exec_dir = d:/usr/exec。

(3)为使代码正常运行,有时需要在安全模式下包含文件,这时可以将safe_mode_include_dir选项的值设定为被包含文件所在目录,例如:safe_mode_include_dir = d:/usr/include/。

3.2 其他安全配置

为进一步防范PHP安全漏洞,光使PHP网站运行在安全模式下是不够的,还需进行一些辅助配置。

(1)限制PHP Shell能够访问的目录

PHP Shell是一个用PHP脚本封装的Web工具,用于远程执行服务器上的命令和浏览服务器上的文件,从而远程管理Web服务器。为了减少使用PHP Shell带来的安全风险,可以利用php.ini中的open_basedir选项来设定PHP脚本所能访问的目录,拒绝其访问不该访问的目录,例如:open_basedir = d:/www。

(2)关闭可能带来安全风险的函数

一般情况下,如果开启了安全模式,大部分可能带来安全风险的函数已经被禁用或功能受到限制,但为了更加保险起见,还可以在php.ini文件的disable_functions选项中将这些函数包含进来,例如:disable_functions = system, exec等。此选项可以和其他选项配合以达到更好的安全效果。

(3)防止PHP版本信息的泄露

为了防止攻击者通过了解PHP版本信息寻找安全漏洞,可以利用php.ini中的expose_php选项关闭PHP版本信息在http头中的显示,例如:expose_php = Off,这样设定以后,当攻击者telnet某网站时就看不到该网站所采用的PHP的版本信息了。

(4)关闭全局变量注册

在PHP中提交的变量,包括使用POST或者GET方法提交的变量,默认都被注册为全局变量,能够直接进行访问,这对网站是非常不安全的,可以利用php.ini中的register_globals选项关闭全局变量注册,例如:register_globals = Off。

在关闭全局变量注册以后,获取变量时必须采用特定的方式,比如:获取由POST方法提交的变量E-mail,就必须用$_GET['Email']的方式来获取。

(5)打开magic_quotes_gpc选项,防止SQL注入

SQL注入是非常危险的攻击,攻击者通过精心设计特定的输入字符串来构造特定的SQL查询并使数据库执行,从而达到攻击目的,轻则导致信息泄露,重则导致网站瘫痪。SQL注入的产生主要是对用户的输入没有进行严格验证和对系统的输出没有进行适当转义导致的。

为了降低SQL注入攻击的可能性,可以将php.ini中的magic_quotes_gpc选项打开,例如:magic_quotes_gpc = On,此选项打开以后,系统将对向数据库提交的SQL查询进行转义,从而在相当程度上减少SQL注入攻击的发生。

(6)关闭错误信息的显示

系统在运行过程中如果发生错误,则会在浏览器上显示错误信息,在调试阶段,这可以帮助系统开发人员查找错误产生的原因。但是,一旦系统正式投入使用,则不应该将出错信息显示在客户的浏览器上,因为错误信息中含有大量敏感的系统信息,为黑客攻击系统提供了便利,为此,可以利用php.ini中的display_errors选项关闭错误信息的显示,比如:display_errors = Off。

(7)打开错误日志记录功能

在关闭错误信息的显示后,为了了解系统的运行情况,可以查看系统的错误日志。为了实现错误日志记录功能,可以利用php.ini中的log_errors选项打开错误日志记录功能,比如:log_errors = On,同时利用error_log选项指定日志存放路径和文件名,例如:error_log = d:/logs/php/php_errors.log。

4 结束语

PHP安全漏洞的产生原因主要是未对用户的输入进行严格验证以及未对系统的输出进行适当转义(内置函数使用不当产生的安全漏洞其本质原因也在于此)。正所谓“魔高一尺、道高一丈”,只要网站开发人员和网站管理人员提高安全意识,在开发和管理网站的过程中采取适当措施,大部分PHP安全漏洞还是不难防范的。

参考文献

[1] 滕萍.云计算技术发展分析及其应用研究[J].信息网络安全,2012,(11):89-91.

[2] 傅慧.动态包过滤防火墙规则优化研究[J].信息网络安全,2012,(12):12-14.

[3] 孙志丹,邹哲峰,刘鹏.基于云计算技术的信息安全试验系统设计与实现[J].信息网络安全,2012,(12):50-52.

作者简介:

程茂华(1977-),男,安徽黄山人,硕士研究生;研究方向:网络与信息安全。

上一篇:基于网站信息流程的监控设计与实现 下一篇:数字电子技术在网络中的应用研究