Web应用双向认证的失败案例
在过去的两个月里,我测试了两个使用双向认证流程的互联网银行应用,这些应用会向用户显示他们预先设置的秘密短语或图像:
![认证流程示意图]
在这两种情况下,我都通过演示这种向用户验证网站身份的方法几乎无法提供任何安全增强效果,从而让开发人员感到困扰。因此我认为应该写这篇博客,看看其他人是否同意我的发现,并期待有人能提出改进方案。
代理攻击的致命缺陷
我认为这种方法的问题在于它很容易被代理:攻击者创建网站的克隆版本,引诱受害者访问。受害者输入用户名后,会跳转到显示"秘密"信息的页面。此时,虚假网站将用户名传递给真实网站并启动登录流程。当获取到短语或图像时,攻击者网站会收集这些信息,填充到模板中并呈现给用户。下面的流程图展示了从初始钓鱼到窃取凭证的完整过程:
![攻击流程图]
此时,用户看到自己的秘密信息,因此认为可以信任该网站,于是输入密码完成登录过程。攻击者现在获得了用户名和密码,可以选择将用户重定向回真实网站(让用户以为输入了错误密码并重新尝试登录),或者将用户留在自己的网站上继续攻击。
替代方案的局限性
在与他人讨论时,有人建议不显示短语/图像,而是采用带外验证方式,比如发送短信或拨打电话。这初听起来是个不错的替代方案,但稍加思考就会发现它存在完全相同的问题:虚假网站可以启动登录流程,直到真实网站发送短信或拨打电话完成双向认证。用户仍然会收到来自真实网站的预期信息,从而认为他们访问的是可信站点。
另一个建议是在显示秘密详情之前要求完成完整登录,但这会让攻击者无需代理就能获得完整凭证。攻击者可以显示任意图像,或者将用户重定向回真实网站,让用户以为自己操作失误而重新尝试。
安全宣传的反效果
更糟糕的是,网站越是强调这种双向认证,漏洞的严重性就越大。如果他们极力强调只有自己知道秘密信息,因此如果你看到这些信息就一定是访问了真实网站,那么此类代理攻击就会更加有效。网站克隆不需要非常精确,使用的URL也不需要非常接近真实网址,因为一旦显示了秘密信息,受害者就会立即信任该网站并忽略任何问题。
无解的安全困境
我想不出有什么既如此易用又真正有效的系统,因为任何来自服务器的内容都可以以某种方式被代理。如果真实网站严格检查源IP并阻止来自同一源的多个请求,攻击者可以使用开放代理发起请求;如果服务器检查HTTP头,攻击者只需转发受害者发出的确切请求。
我很希望能向客户提供替代解决方案,如果您有任何建议,请联系我。
感谢Michah和Anne的校对和图表协助。