PHP安全编程:从URL的语义进行攻击

以一个Webmail系统为例
服务器君一共花费了213.229 ms进行了5次数据库查询,努力地为您提供了这个页面。
试试阅读模式?希望听取您的建议

好奇心是很多攻击者的主要动机,语义URL攻击就是一个很好的例子。此类攻击主要包括对URL进行编辑以期发现一些有趣的事情。例如,如果用户chris点击了你的软件中的一个链接并到达了页面http://example.org/private.php?user=chris, 很自然地他可能会试图改变user的值,看看会发生什么。例如,他可能访问http://example.org/private.php?user=rasmus来看一下他是否能看到其他人的信息。虽然对GET数据的操纵只是比对POST数据稍为方便,但它的暴露性决定了它更为频繁的受攻击,特别是对于攻击的新手而言。

大多数的漏洞是由于疏漏而产生的,而不是特别复杂的原因引起的。虽然很多有经验的程序员能轻易地意识到上面所述的对URL的信任所带来的危险,但是常常要到别人指出才恍然大悟。

为了更好地演示语义URL攻击及漏洞是如何被疏忽的,以一个Webmail系统为例,该系统主要功能是用户登录察看他们自己的邮件。任何基于用户登录的系统都需要一个密码找回机制。通常的方法是询问一个攻击者不可能知道的问题(如你的计算机的品牌等,但如果能让用户自己指定问题和答案更佳),如果问题回答正确,则把新的密码发送到注册时指定的邮件地址。

对于一个Webmail系统,可能不会在注册时指定邮件地址,因此正确回答问题的用户会被提示提供一个邮件地址(在向该邮件地址发送新密码的同时,也可以收集备用邮件地址信息)。下面的表单即用于询问一个新的邮件地址,同时他的帐户名称存在表单的一个隐藏字段中:

<form action="reset.php" method="GET">
  <input type="hidden" name="user" value="chris" />
  <p>Please specify the email address where you want your new password sent:</p>
  <input type="text" name="email" /><br />
  <input type="submit" value="Send Password" />
</form>

可以看出,接收脚本reset.php会得到所有信息,包括重置哪个帐号的密码、并给出将新密码发送到哪一个邮件地址。

如果一个用户能看到上面的表单(在回答正确问题后),你有理由认为他是chris帐号的合法拥有者。如果他提供了chris@example.org作为备用邮件地址,在提交后他将进入下面的URL:

http://example.org/reset.php?user=chris&email=chris%40example.org

该URL出现在浏览器栏中,所以任何一位进行到这一步的用户都能够方便地看出其中的user和mail变量的作用。当意思到这一点后,这位用户就想到php@example.org是一个非常酷的地址,于是他就会访问下面链接进行尝试:

http://example.org/reset.php?user=php&email=chris%40example.org

如果reset.php信任了用户提供的这些信息,这就是一个语义URL攻击漏洞。在此情况下,系统将会为php帐号产生一个新密码并发送至chris@example.org,这样chris成功地窃取了php帐号。

如果使用session跟踪,可以很方便地避免上述情况的发生:

<?php
 
  session_start();
 
  $clean = array();
  $email_pattern = '/^[^@\s<&>]+@([-a-z0-9]+\.)+[a-z]{2,}$/i';
 
  if (preg_match($email_pattern, $_POST['email']))
  {
    $clean['email'] = $_POST['email'];
    $user = $_SESSION['user'];
    $new_password = md5(uniqid(rand(), TRUE));
 
    if ($_SESSION['verified'])
    {
      /* Update Password */
 
      mail($clean['email'], 'Your New Password', $new_password);
    }
  }
 
?>

尽管上例省略了一些细节(如更详细的email信息或一个合理的密码),但它示范了对用户提供的帐户不加以信任,同时更重要的是使用session变量为保存用户是否正确回答了问题($_SESSION['verified']),以及正确回答问题的用户($_SESSION['user'])。正是这种不信任的做法是防止你的应用产生漏洞的关键。

这个实例并不是完全虚构的。它是从2003年5月发现的Microsoft Passport的漏洞中得到的灵感。

延伸阅读

此文章所在专题列表如下:

  1. PHP安全编程:register_globals的安全性
  2. PHP安全编程:不要让不相关的人看到报错信息
  3. PHP安全编程:网站安全设计的一些原则
  4. PHP安全编程:可用性与数据跟踪
  5. PHP安全编程:过滤用户输入
  6. PHP安全编程:对输出要进行转义
  7. PHP安全编程:表单与数据安全
  8. PHP安全编程:从URL的语义进行攻击
  9. PHP安全编程:文件上传攻击的防御
  10. PHP安全编程:跨站脚本攻击的防御
  11. PHP安全编程:跨站请求伪造CSRF的防御
  12. PHP安全编程:关于表单欺骗提交
  13. PHP安全编程:HTTP请求欺骗
  14. PHP安全编程:不要暴露数据库访问权限
  15. PHP安全编程:防止SQL注入
  16. PHP安全编程:cookie暴露导致session被劫持
  17. PHP安全编程:session固定获取合法会话
  18. PHP安全编程:session劫持的防御
  19. PHP安全编程:防止源代码的暴露
  20. PHP安全编程:留心后门URL
  21. PHP安全编程:阻止文件名被操纵
  22. PHP安全编程:文件包含的代码注入攻击
  23. PHP安全编程:文件目录猜测漏洞
  24. PHP安全编程:打开远程文件的风险
  25. PHP安全编程:shell命令注入
  26. PHP安全编程:暴力破解攻击
  27. PHP安全编程:密码嗅探与重播攻击
  28. PHP安全编程:记住登录状态的安全做法
  29. PHP安全编程:共享主机的源码安全
  30. PHP安全编程:更优的会话数据安全
  31. PHP安全编程:会话数据注入
  32. PHP安全编程:主机文件目录浏览
  33. PHP安全编程:PHP的安全模式

本文地址:http://www.nowamagic.net/librarys/veda/detail/1992,欢迎访问原出处。

不打个分吗?

转载随意,但请带上本文地址:

http://www.nowamagic.net/librarys/veda/detail/1992

如果你认为这篇文章值得更多人阅读,欢迎使用下面的分享功能。
小提示:您可以按快捷键 Ctrl + D,或点此 加入收藏

大家都在看

阅读一百本计算机著作吧,少年

很多人觉得自己技术进步很慢,学习效率低,我觉得一个重要原因是看的书少了。多少是多呢?起码得看3、4、5、6米吧。给个具体的数量,那就100本书吧。很多人知识结构不好而且不系统,因为在特定领域有一个足够量的知识量+足够良好的知识结构,系统化以后就足以应对大量未曾遇到过的问题。

奉劝自学者:构建特定领域的知识结构体系的路径中再也没有比学习该专业的专业课程更好的了。如果我的知识结构体系足以囊括面试官的大部分甚至吞并他的知识结构体系的话,读到他言语中的一个词我们就已经知道他要表达什么,我们可以让他坐“上位”毕竟他是面试官,但是在知识结构体系以及心理上我们就居高临下。

所以,阅读一百本计算机著作吧,少年!

《高性能网站建设指南》 桑德斯 (Steve Sounders) (作者), 刘彦博 (译者)

《高性能网站建设指南》结合Web2.0以来Web开发领域的最新形势和特点,介绍了网站性能问题的现状、产生的原因,以及改善或解决性能问题的原则、技术技巧和最佳实践。重点关注网页的行为特征,阐释优化Ajax、CSS、JavaScript、Flash和图片处理等要素的技术,全面涵盖浏览器端性能问题的方方面面。在《高性能网站建设指南》中,作者给出了14条具体的优化原则,每一条原则都配以范例佐证,并提供了在线支持。全书内容丰富,主要包括减少HTTP请求、ExpiresHeader技术、Gzip组件、CSS和JavaScript最佳实践、关闭ETags的技巧、Ajax缓存技术和最小化技术等。

更多计算机宝库...