PHP程序员站--PHP编程开发平台
 当前位置:主页 >> PHP高级编程 >> 高级应用 >> 

PHP安全小建议 下

PHP安全小建议 下

来源:PHP程序员站  作者:admin  发布时间:2011-01-14
近日比较关注PHP的安全问题,国内的许多开发者,特别是PHP初学者,很多时候仅满足功能是否实现,对安全的探讨浅尝辄止甚至漠不关心。这样的后果很严重,比如泛滥的SQL注入,甚至还有直接被下载数据库连接文件的此文译自Cal Evans发表DevZone的系列专题:PHP Security T

近日比较关注PHP的安全问题,国内的许多开发者,特别是PHP初学者,很多时候仅满足功能是否实现,对安全的探讨浅尝辄止甚至漠不关心。这样的后果很严重,比如泛滥的SQL注入,甚至还有直接被下载数据库连接文件的……此文译自Cal Evans发表DevZone的系列专题:PHP Security Tip (安全建议/小窍门) 虽然不是最新文章,但提到的许多原则性的东西和经典的做法仍然是值得重视的,绝对是值得一读的好文章,借此抛砖引玉,希望能给大家一点帮助,建立良好的安全意识,了解必要的防范措施。 文中加入本人的理解和注释的地方已经注明,首次翻译,不当之处欢迎指出。谢谢 ! ——By Falcon

,原书共21个建议,这是翻译的下部。

PHP安全小建议(上)


PHP安全建议#12

我们谈论过过滤,谈论过验证,让我们又再来讨论一下过滤。

过滤用户输入是个很重要的观念,也很多良好安全习惯的前导(pre-cursor),然而,经过了过滤输入和验证处理之后,你还不能坐下来歇一会。在贯穿整个应用程序安全的编码中,你必须保持警惕。

过滤输入给某些开发者一种安全错觉,他们会武断地认为,既然已经过滤了输入 ,那就应该没什么理由再担心了吧。可能在一些简单的实例里确实如此,但在大规模的复杂应用中,你必须不断留心你使用该输入来做什么。尤其是在使用eval()命令下使用用户输入时,由此开始我们今天的建议:

在使用eval()前请谨慎。

在eval()里使用用户输入值时,你有可能给为恶意使用者进入你的服务器打开了大门。即使你的接口只允许他们选择预定义的选项,调用脚本时可能被进行了欺骗(spoofed)。你的脚本可能潜在地被利用来执行他们的请求命令,以此进行一些不良行为的。

谨慎地使用eval() ,当你必须使用它时,务必对用户输入经过过滤和验证处理。如果还有其他方法完成相同的任务,那么应该考虑用它们来代替。


PHP安全建议#13

安全是一种思想,而不只是一些你要做的事情,它会令应用程序的设计和编码增色(colors)不少。然而你还需要不断地监控生产环境,这是选择正确的工具投入工作的地方。我以前提到过PHPSecInfo ,我认为这个工具非常重要以致于我把它作为独立的一节来介绍。

PHPSecInfo 是一个用来监视生产环境的强大工具,它是CERIAS的Ed Finkler编写的,CREIAS是Purdue大学信息安全与保障教育研究中心的简称。(the Center for Education and Research in Information Assurance and Security at Purdue University.),是PHP安全协会的官方项目(PHPSecInfo威武!),这是PHPSecInfo主页对其一些必要的说明:

PHPSecInfo提供一个等价的phpinfo()函数来报告PHP环境的安全信息,并提供改进建议,它目的不是取代安全开发的技术,也不对程序进行任何形式的编码或审核应用。但在使用多层面的安全手段时却是一个很有用的工具。

如果想了解更多信息,下面是一段Ed谈论PHPSecInfo的小采访的链接,还有另外一个链接,是最新发布的0.2版本的通告。

http://devzone.zend.com/node/view/id/1099

http://devzone.zend.com/node/view/id/1735

像所有安全措施一样,(PHPSecInfo) 就其本身,并非银弹(见建议#1的译注 ),但是适当使用,将会成为综合解决方案的一部分。


PHP安全建议#14

差不多所有PHP程序都是运行PHP作为后端,使用web技术作为前端,很多开发者对PHP安全思考了很多,却从来没想过它们前端应用的安全。这里的建议是:当你构造HTML和JavaScript时,你应该思考得更长远和深入些。

任何保持在Cookie里面的信息都有可能被其他人所看到——尽量把这些信息控制到最少

今天的web界有一个很悲哀的事实,有些不怀好意的人出没其间,他们只想让你的应用程序泄露敏感信息,然后破解它,当你评估应用程序的安全时,务必观察全局。非常重要的一点是看看你在前端保留了些什么。


PHP安全建议#15

作为开发者,我们大部分的人都是非常肮脏的,我为无数项目工作过。每次都能发现或者留下一堆额外的诊断文件,随地乱放。像(info.php, test.php ,doMe.php等),这些文件,如果被某个怀有不良企图的人发现,将很有可能泄露系统的有用信息。

今天的安全建议是

不要忘记清除临时的系统诊断文件

在清理危害你的应用的这些文件时你可能会感到惭愧,看到那些留下来的info.php或者更糟的,在test.php“一段快速代码片断",它们都会潜在地泄露关于系统的危险信息,不要再助那些发广告的家伙(ad guys)一臂之力了。

p.s. 你也有安全方面的小建议,把它发布出来吧,能和他人分享是一件再好不过的事了,只要登录并点击右上角的贡献按钮。


PHP 安全建议 #16

保持框架的更新

我已经在之前的评论中发表过了,但鉴于我相信它是非常重要的话题,它有可能值得独立作为一个“安全建议”

务必经常更新任何你使用的框架。

如果你工作在"一次性"的客户项目上,这点尤其重要。很关键的是要考虑到,如果(或者当)第三方软件补丁发布的时候,由谁去维护这个站点。

通常这些网站是放在共享主机的站点上面的,这意味着供应商有责任为PHP,数据库系统和Web服务器保持更新。但他们不太可能维护你安装的框架。

一般来说使用框架是一件好事,不仅因为它可以为减少大量的工作,而且任何潜在的安全问题将(通常)会得到快速处理。

另一方面,这也意味着这些框架的安全问题很好地被文档化了,同时也方便了不怀好意的黑客搜索系统使用框架

的旧版本并通过这些安全问题进行爆破。

我看过很多很多的网站仍然在使用一些非常老的、过期的文件,仅仅是因为没有人去更新它,还在使用旧版 的PEAR 库(其中广为人知的Mail组件安全问题) 的网站会更糟!


PHP安全建议#17

应用程序安全不应该是一个“当其他手段失效后"的(补救)措施,它不是你能把它放在后面的东西,正如我们之前提到的那样,在这里没有银弹解决应用程序的安全问题,安全问题应该始终贯穿整个设计、编码、测试阶段甚至代码进入生产运作的阶段。

知名PHP安全专家Chris Shiflett,他的网站上有一本值得让所有PHP开发者阅读的PDF书籍。这本由PHP安全协会编译的37页的指南解释了在保障PHP应用程序安全方面的各种术语和概念,他们是这样描述安全的:

安全是一个标量(意为可以测量的),而非定性的。

不幸的是很多软件项目只是简单地把安全作为一个必须满足的要求罗列出来。它是不是安全的?这种问法就像问某种东西是不是热的一样。

安全需要与费用来保持平衡

可以很容易和相对廉价地为大部分应用提供充足的安全级别。然而,如果因为要保护的信息价值很高,对安全的要求相当苛刻,那么就必须增加成本来达到更高级别的安全水平,这种支出必须被包含在项目的预算里。

安全需要与易用性保持平衡

很常见的事实是增加Web应用程序的安全的同时减少了易用性。设置密码,Session过期时间和访问控制所有这些措施也为合法用户设置了障碍。有时候为了提供充足的安全这些措施是必要的,但并非适用于所有应用程序,在布署安全措施时也要关心合法用户的易用性。

安全应该是设计的一部分

如果你在设计应用程序时对安全漠不关心,你就注定要不断地对付新的安全风险。精心的编码也不能弥补糟糕的设计。

如果安全对你很重要但你不知道从哪里开始,这会是个好地方。 下载这个PDF文档并花上一个小时左右来通读一遍,如果你已经是安全方面的老手了,也建议下载下来浏览一遍,你可能会发现一些新的东西。

下载地址:http://shiflett.org/php-security.pdf


PHP安全建议#18

当你允许用户上传文件时,你的系统可能存在风险,总是严格限制允许上传的文件类型,不要依靠黑名单的办法。例如一个合理的黑名单机制可以看上去不允许上传 .php文件。

这是个很好的机制直到某一天有人上传了一个名为.htaccess的文件之后,它不是一个PHP文件所以黑名单不会进行拦截,把下面一行代码放进一个.htacess文件并把它上传到一个只使用黑名单机制来过滤的系统将会为那些坏家伙打开大门。

AddType application/x-httpd-php .php .htm

他们现在能上传任何包含PHP代码的.htm文件,可以在你的系统来来回回随意逛悠了。

例如

 

echo system("locate config");

?>

上面的代码很可能会让攻击者获得服务器上每个配置文件的名称。攻击的可能性无穷无尽,而全部只是由于服务器上一个保护不当的上传表单。

留心上传文件并且务必使用白名单机制来保护它们而非黑名单机制,确保上传的文件是你允许的文件类型,有好几种方法来做这事,最简单的是(同时也是最容易被破解的)是检查上传文件的扩展名。你很容易排除掉那些非法的扩展名的上传文件。然而这不是最安全的做法。

为了加强安全检测,找一下PECL扩展,FileInfo(地址:http://pecl.php.net/package/Fileinfo),在这里可以找到相关文档(http://us3.php.net/manual/en/ref.fileinfo.php)。FileInfo检查文件内容,并通过判断特定的字节顺序(specific magic byte sequences 特征码?) 来猜解文件的内容类型。在允许用户上传文件时,使用FileInfo作为白名单机制的一部分是一个更安全的做法。


PHP安全建议 #19

有时候,你能布署的最佳应用程序安全就是只要把网络光缆从服务器上断开。当然这在现实环境里是很不现实的事情 。然而这样想会让你找到一种更好 的保护应用程序安全的做法。

当安全问题上时,必须同时考虑软件和硬件,今天的安全建议来自Chris Hartjes。

最安全的应用程序是没有连接到外部世界的程序。

正如我们上面提到的那样,如果你在构建Web应用程序,不可能真的切断网络连接。不过你可以认真思考哪些服务器需要连接到外部哪些可以放在防火墙里面,除此之外,你还能评估那些需要保留在防火墙外面的服务器怎样和防火墙里面的服务器通信。

会话劫持,XSS 和XSRF是都是开发者需要面对的严重问题,在此我的目的不是讲如何降低它们。很多情况下,它们不过只是达到最终目标的手段而已。对大部分黑客来说,你的数据库相当于彩虹末端的黄金之壶。作为开发者我们今天面对最头疼的问题是我们的应用程序被破解。我们的数据库因此被牵连,那些信任我们的用户的信息在网上被公诸于众。

一个简单的(为了说明)方法是只需要做一点点努力,把数据库服务器放在防火墙后面并限制其访问,一旦踏出这一步,你会找到更多办法来保障整个系统的安全。

这只是一个引发你思考的小建议,不是网络安全入门,问题的解决方法还得留给你,找一个安静的地方,呆上一会半会,重新思考你系统的物理网络结构。想想它们是怎么连接的,你可以做些哪些事情来改进整体的安全。

你有想要分享的安全建议吗?点击右上角的贡献按钮参与吧。


PHP安全建议#20

正如某位美国爱国主义者所言,"安全的代价是无尽的警惕",除了时刻留心监控系统外,你还应该不断学习。今天的安全小建议将介绍一系列资源,它们将帮助你了解最新的安全知识。如果你在寻找PHP安全方面的信息,我已经为你收集了好几个值得考虑的资源。

你应该毫不意外地发现,你正在阅读我的首席推荐——DevZone的PHP安全建议系列!我们每周发表一个值得你深思的新的安全建议。它们通常很简短以便你能快速阅读完毕,然后你可以在这天的其余时间里认真思考这些问题。

你应该阅读的一些书箱:(都可以在www.amazon.com搜索到)

Essential PHP Security (PHP安全本质)

Pro PHP Security (专业PHP安全)

Professional PHP5 Security (专业PHP5安全)

php|architect's Guide to PHP Security (php| 架构师的PHP安全指南)

最后,php|架构师杂志是值得考虑订阅的好刊物,除了他们颇具深度的专题文章,他们每个月还开设一个叫“安全角”的专栏。

所有这些都是很出色的资源,值得你考虑和收集,在面对PHP安全问题时有助于你保持警觉。

php|架构师杂志:http://phparch.com/


PHP安全建议#21

今天的PHP安全建议简短、美妙、易行。非常适合作为主题的最后一个建议。保持警惕,下面是另一个你需要考虑的资源:

如果还没有,你应该去订阅一下《安全焦点简讯》(Security Focus newsletter.)

如果没有订阅话,请点击这里进入(地址见译文最后)他们的邮件列表,然后订阅。当你进入之后会发现有38个邮件列表,问题来了,我应该加入哪 个列表呢?最受欢迎最繁忙的是BugTraq列表,这个列表包含全部内容。以下是他们的描述:

BugTraq是完全公开的制度化的邮件列表,旨在详细探讨和通告计算机方面的安全风险和威胁:这些风险是什么,怎么爆破、如何修复。

今天就加入BugTraq ,开始获得关于PHP的或者更广泛的,运行在你服务器上的应用程序的安全资讯吧。

在构建安全应用程序时,信息是你最大的财富!

《安全焦点简讯》(Security Focus newsletter.)邮件列表地址:http://www.securityfocus.com/archive


安全建议:使用数据库抽象层防范SQL注入

SQL注入是使用数据库的基于Web的应用程序常见的攻击手段,比如说一个潜在的SQL注入的例子,一个询问用户名的登录表单,它的后台代码可能是这样的:

mysql_query('SELECT * FROM user WHERE username = "' . $_GET['username'] . '");

怀有不良企图的黑客可能尝试输入 ""; DELETE FROM user WHERE 1", 这将删除表里所有的用户。(当然,对于PHP的mysql扩展不会发生这种情况,因为默认情况下它不会执行多重查询,用在这里只是作一个举例)

有几种方法来防范这类攻击

在执行查询前,使用数据库扩展的引号机制加入引号

MySQL: mysql_real_escape_string()

PostgreSQL: pg_escape_string()

SQLite: sqlite_escape_string()

使用PDO准备语句支持。PDO为数据库提供原生准备语句,或许你的数据库不支持准备语句,那也能选择可用的引号机制模拟这个过程,下面任意一种方法都能防范SQL注入,例如:

//使用容器(placeholders)

$stmt = $db->prepare("insert into user(name,email,url) values (?,?,?)");

$stmt->bindParam(1,$name);

$stmt->bindParam(2,$email);

$stmt->bindParam(3,$url);

$stmt->execute();

//使用命名参数

$stmt = $db->prepare("insert into (name,email,url) values(:name,:email,:url)");

$stmt->execute(array('url'=>$url,'name'=>$name,'email'=>$email); //(原文array('url' = $url, '处有误 。译者注)

使用数据库抽象层(DAL),比如AdoDB,PEAR::MDB2,或者Zend_Db。大部分的DAL支持准备语句和引号机制,并通常委托PDO处理。

要保护你的数据库,从今天开始,选择并实践上面做法的某一种吧。

 


延伸阅读:
编写安全 PHP 应用程序的七个习惯
PHP SQL注入的安全规范
如何书写安全的PHP代码
PHP安全概述
PHP安全之Register Globals
PHP安全之错误报告
PHP安全之数据过滤
php函数intval()使用不当的安全漏洞分析
开发人员需要牢记的HTML 5安全问题
PHP安全小建议
Tags: php   安全  
最新文章
推荐阅读
月点击排行榜
PHP程序员站 Copyright © 2007-2010,PHPERZ.COM All Rights Reserved 粤ICP备07503606号