返回首页 PHP 之道

安全

Web应用安全

总有一些人会千方百计的想着破坏你的Web应用,提前想办法加强自己的Web应用的安全性非常重要。幸运的是, The Open Web Application Security Project (OWASP) 已经提供详尽的已知安全问题列表和防范对策。 每个关注Web安全的开发者都应该仔细阅读该列表。

阅读OWASP安全指南

数据过滤

永远不要在PHP代码中信任外部输入,在使用之前一定要先过滤和验证,filter_var和filter_input函数可以帮助过滤文本和 验证文本格式(如邮箱地址)。

外部输入可以是:$_GET和$_POST表单输入数据、$_SERVER超级变量中的某些值和通过fopen('php://input', 'r')获取的 HTTP请求体。要记住外部输入不仅仅是用户提交的表单数据,还包括上传和下载的文件、session变量、cookie数据和第三方Web服务提供的 数据等。

当外部数据被存储合并之后,下次读取时,它们仍然算是外部输入,每次在代码中处理的时候,需要问自己是否已经正确过滤,是否可以 信任它们。

数据需要根据不同用处,进行不同的过滤,如果把未经过滤的数据输出到HTML页面,它可以在你的网站里执行HTML和JavaScript!即通常 说的跨站脚本攻击(XSS)。避免XSS的一个策略就是使用strip_tags函数过滤外部输入的所有HTML标签,或者使用htmlentities/ htmlspecialchars转义其中的HTML实体。

另外一个例子是传给命令行命令的选项,这可能非常危险(通常不是一个好主意),不过你可以用内置的escapeshellarg函数过滤命令行的 参数。

最后一个例子是根据外部输入来从文件系统中加载文件的操作,可以通过修改路径中的文件名实施攻击。你需要过滤输入中的”/”, “../”, null bytes, 或其他特殊字符,以防止加载不能公开的包含敏感数据的文件。

数据清洗

数据清洗就是删除或转义外部输入中的非法或不安全字符。比如把外部数据输出到HTML或插入到SQL语句之前,需要先清洗外部输入。 当你通过PDO绑定数据时,它会替你转义输入数据。

有时候需要允许外部数据包含安全的HTML标签,并输出到HTML页面中。这个比较难处理,可以考虑使用其他更严格的格式,如 或BBCode,实在不能的话,可以使用HTML Purifier库来进行数据清洗。

了解更多数据清洗过滤器

数据验证

数据验证外部输入就是你预期的,如你在处理注册表单时,需要验证email地址、电话号码和年龄等数据

了解更多数据验证过滤器

配置文件

在创建应用的配置文件时,请遵循下面的业界最佳实践:

  • 配置文件保存在Web不能直接访问和上传的目录中。
  • 如果配置文件只能放在文档根目录时,请使用.php作为文件名后缀,这样即使直接访问该配置文件,也不会输出配置信息。
  • 配置文件内容应该加密,或者对文件设置访问权限。

注册全局变量

提示:从PHP 5.4.0开始,register_globals配置已经删除,不再生效。保留这个配置,只是提示依赖该配置的应用进行升级。

启用register_globals配置后,$_POST, $_GET和$_REQUEST中的变量自动注册为全局变量,使得应用很难辨别变量的确切来源,从而产生安全漏洞。

例如:$_GET['foo']将注册变量$foo,这会覆盖程序中未声明的同名变量。如果你使用PHP 5.4.0之前的版本,请确保已经把register_globals设置为off。

Register_globals in the PHP manual

错误提示

错误日志可以帮助追查应用的Bug,但是也会暴露应用的结构信息而产生安全问题,为此,需要在开发环境和线上环境设置不同的配置,防止 敏感信息的泄漏。

开发环境

要在开发环境显示错误提示,需要在php.ini中配置以下配置项:

display_errors = On
display_startup_errors = On
error_reporting = -1
log_errors = On

来自php.net:

-1表示显示各种错误,包括将来增加的新错误类型,和PHP 5.4中的E_ALL行为相同。

E_STRICT错误级别在5.3.0版本引入,不在E_ALL中,不过5.4.0版本开始,E_ALL包含E_STRICT级别的错误。所以在5.3版本中,要显示 所有错误,需要把error_reporting设置为-1或者E_ALL | E_STRICT。

各PHP版本显示所有错误的配置

< 5.3 -1 or E_ALL
  5.3 -1 or E_ALL | E_STRICT
> 5.3 -1 or E_ALL

线上环境

要在线上环境隐藏错误提示,需要在php.ini中配置以下配置项:

display_errors = Off
display_startup_errors = Off
error_reporting = E_ALL
log_errors = On

这样设置后,线上错误会记录到Web服务器的错误日志中,而不是直接显示给用户。如果想了解更多错误提示相关的设置,请参考手册:

上一篇: 数据库 下一篇: 测试