在上一篇文章中,我们详细介绍了代码注入的安全威胁。在这篇文章中,我们将挖掘Web应用程序中被破坏的认证漏洞,并看看如何避免它。
保证用户认证的安全是使Web应用更安全的关键部分。为了更好地理解这个漏洞,让我们来看看一个典型的认证过程是怎样的:
- 用户输入他们的登录凭证
- 服务器验证凭证,然后创建一个会话,这个会话被存储在服务器端
- 一个带有会话ID的cookie被存储在用户的浏览器上。
- 在用户提出的每一个后续请求中,会话ID将与存储在服务器上的值进行验证,以处理该请求。如果ID不一样,认证就会失败,请求就不会被成功处理。
- 当用户注销应用程序时,这个会话在客户端和服务器上都会被销毁。
现在,如果这个机制有任何缺陷,或者如果认证过程在实施过程中没有注意到最佳实践,攻击者可以使用手动或自动媒介来试图获得对任何账户的访问,或者在最坏的情况下,控制系统。
虽然这种威胁有多种形式,但这些是一些明显的情况,使应用程序容易受到攻击:
-
将密码存储为纯文本。这绝不是一个好主意。在存储密码之前,一定要用盐对密码进行散列,这样即使数据库被破坏,密码也不会暴露。不要使用弱的哈希值,如
SHA1或MD5。 -
将管理员的登录页面留给网站的所有访问者公开访问。
-
不注意自动攻击,如凭证填充,攻击者有一个有效的用户名和密码列表。
-
没有照顾到暴力攻击或其他自动攻击。
-
没有对照最常见的密码列表检查密码。
-
使用弱的或无效的凭证恢复和忘记密码的过程,如基于知识的回答,这不能使其安全。
-
在URL中暴露会话ID。例如,URL重写。
http://example.com/sale/saleitems;jsessionid=2P0OC2JSNDLPSKHCJUN2JV?dest=Hawaii -
在成功登录后不轮换会话ID。
-
不适当地使会话ID失效。用户会话或认证令牌,特别是单点登录(SSO)令牌,在注销或不活动期间没有正确地失效。
正如在以前的一篇文章中提到的,"企业需要改变文化才能正确解决应用安全问题",我们将一直强调拥有一个安全的软件而不是工作的软件。上面提到的大多数问题对你来说可能是显而易见的,但即使在今天,这些漏洞仍然可以在许多应用程序中找到。
为了使应用程序免受这种特殊漏洞的影响,开发人员必须了解网站安全的最佳做法。代码在部署到生产之前应该进行彻底的测试。
以下是OWASP的一些技术建议,以确保你的应用安全,不受这些破碎的认证漏洞的影响:
-
使用一个服务器端的、安全的、内置的会话管理器,在登录后生成一个新的具有高熵的随机会话ID。
-
会话ID不应出现在URL中。ID也应该被安全地存储,并在注销、闲置和绝对超时后失效。
-
在可能的情况下,实施多因素认证,以防止自动的、伪造的、蛮力的和偷来的凭证重复使用的攻击。
-
不要用任何默认的凭证来运送或部署,特别是对管理员用户。
-
实施弱密码检查,例如根据前10000个最差的密码列表来测试新的或更改的密码。
-
根据NIST 800-63 B第5.1.1节中关于记忆秘密或其他现代基于证据的密码政策,调整密码长度、复杂性和轮换政策。
-
确保注册、凭证恢复和 API 途径通过对所有结果使用相同的消息来防止账户枚举攻击。例如,认证失败响应不应指出认证数据的哪一部分不正确。不要使用 "无效的用户名 "或 "无效的密码",只需对两者使用 "无效的用户名和/或密码"。错误响应在显示和源代码中都必须是真正相同的。
-
限制或日益延迟失败的登录尝试。记录所有的失败,并在检测到凭证填充、蛮力或其他攻击时提醒管理员。使用已知密码的列表是一种常见的攻击。如果一个应用程序没有实施自动威胁或凭证填充保护,该应用程序可以被用作密码神谕,以确定凭证是否有效。