1.2.3 防止证书获取
小结:证书获取将用户暴露在各种攻击之下
威胁:暴力攻击、社会工程、垃圾邮件
几年前,我接到一个电话。电话另一端的一位先生称呼我的名字,并且说他来自于我所开账户的银行,现在需要确认在记录上的账户信息。我立刻怀疑起来,但在我有机会回答他之前,他开始读出我的全名和街道地址。但是,他读出的是错误的地址,碰巧这个错误的地址是列在电话本中的地址。通过这个情况,我判断他只是使用可从白页(white page)上获取的公开信息来欺骗我提供其他个人信息。他从电话本上获取名字,使用这些名字作为诈骗的目标。请看下列证书获取实例中的风险。
情形一:Alice的支票账户
1.Alice在银行站点上注册了一个账户,她首先使用该账户登录,然后注意到如下的URL地址:
![]()
2.为了了解该银行应用程序确切的安全性,Alice将userid参数改为:
![]()
3.现在,她发现自己正在查看其他人的支票账户账目。按照这种思路,她进一步尝试如下URL:
![]()
4.她发现这是一个测试账户,因此她尝试使用userid=2,结果发现这是银行董事会成员的账户。
在这一情形中,Alice发现了应用程序中的一个缺陷:使用可预测的连续用户ID可跳转到其他账户上。
情形二:垃圾邮件之王
Bob,著名的垃圾邮件发送者,编写了一段脚本,每天在所有流行拍卖站点上扫描数千个Web页面。在每个页面上,该脚本提取找到的每个拍卖用户的用户名。在收集了几百万个账户名后,Bob处理所产生的账户名列表,将每个用户名和最常用的电子邮件与因特网服务提供商组合起来,如hotmail.com, msn.com, juno.com, aol.com, earthlink.net, yahoo.com等。
接下来,Bob给每个组合而成的地址发送一封电子邮件,并且跟踪哪些账户有效。当所有这些工作都完成后,他就拥有了超过一百万个有效电子邮件地址。当然,Bob发送的第一封垃圾电子邮件是提供100万个有效电子邮件地址,价格只需要99美元。
情形三:电脑黑客Chuck
Chuck是一个电脑黑客,他从信任的电子商务客户处窃取身份和财务信息。他知道一个大型零售商的Web站点允许客户保存他们的信用卡信息,从而可以在将来更方便地进行购物。Chuck企图侵入客户账户,并且窃取该客户存储的信用卡信息。
在第一次尝试中,Chuck创建一个常用用户名和密码的小型列表,并且尝试通过脚本暴力攻击该Web站点。他很快就了解到,一旦用户在一行中输入5个错误的密码,则该站点将封锁账户。但是,有另一种方法可暴力攻击密码:不是针对一个账户尝试很多密码,而是针对多个不同的用户账户尝试一到两个常用的密码。根据统计,他知道,如果针对足够的用户尝试一些常用的密码,将获得一个匹配。
现在惟一的问题是如何收集账户名。为了做到这一点,他编写了一段脚本,使用随机的常见用户名注册账户。该脚本填写并提交注册表单,并且监视如下消息:“Sorry, that username is already in use”(抱歉,该用户名已经被使用)。如果收到该消息,脚本将保存这个用户名。如果没有收到该消息,则该脚本取消当前会话,并且使用下一个用户名重新开始。
几小时后,该脚本从这个繁忙的Web站点上收集了几千个用户名。Chuck整理出用户名列表,并且将其用于暴力攻击脚本中,该脚本最终找到3个使用密码asdf的账户。3个账户可能并不算辉煌的战绩,但Chuck充分利用这个脚本,让它每天运行,每次对脚本进行细微的改动,就可窃取更多的密码。
限制证书暴露
通过获取用户名,攻击者能够收集用于垃圾邮件攻击的电子邮件地址,使用社会工程技术来欺骗其他的用户提供密码,尝试对多个账户使用暴力攻击,或者利用应用程序中的其他弱点来实施。阻止证书获取实际上就是不显示用户名,并且不使用可预测的证书。然而,一些Web站点完全基于用户证书,因此必须使用各种方法来限制证书的暴露。
设计系统时,避免使用户名成为数据库的主键。这种解决方案允许用户改变他们的用户名,而不会丢失重要的账户信息和历史记录。保护用户名的一种技术是允许用户创建一个或多个别名,这些别名不能用于登录到账户。避免使用连续的用户名或遵循可预测性模式的用户名。如果将用户连接到外部账户,例如支票账户,则不能使用支票账户号作为用户ID,因为这些支票账户号通常是连续的,攻击者很容易发现这一信息。
在某些场合中,允许用户改变用户名或使用别名将很容易导致滥用。应该仔细考虑允许用户名改变或使用别名的含意,以确定这样做是否适合应用程序。例如,某论坛的Web站点允许用户改变用户名,但一个月只能改变一次,以防止账户的滥用。但是,该站点没有采取任何措施来防止滥用者创建新的账户。
防止用户名获取的最佳方法是绝对不要在站点上显示用户名。然而,如果对于Web应用程序并不可行,则可以通过改变用于编写用户名的编码,来尝试欺骗一些自动用户名获取脚本。
另一条重要的原则是,避免传递用户名作为查询字符串参数,以防止该用户名出现在浏览器历史记录、代理日志或其他站点的HTTP引用[sic]头中。考虑如下的URL,它们可能出现在另一个Web站点的Web日志中。
下面是一个较差的示例:
![]()
下面是一个较好的示例:
![]()
在这两个示例中,后一个示例更为安全,因为该URL没有包含辨识信息。
安全策略
n 绝对不要使用电子邮件地址作为用户名,并且避免在其他地方显示用户的电子邮件地址。
n 避免使用公有的用户目录和白页。
n 允许用户在需要时改变他们的用户名。
n 允许用户将一个或多个公有别名赋给他们的账户。
n 允许探测暴力攻击或获取攻击。







