一、什么是身份验证功能缺陷
身份验证功能在机制、代码实现、配置等方面会存在缺陷。
黑客利用这个缺陷,盗用身份、访问受限API;以此为跳板做进一步的攻击。
二、身份验证的常见方式
- 账号密码
- Token/Key验证
账号密码
最常见的验证方式,用户输入账号密码,验证通过后,将用户的标识记录到session或者cookie中,后续请求系统会检察session或者cookie从而判断用户是否登陆。
当用户退出时,服务器将session中的用户身份信息删除,或整个销毁。
Token/Key验证
常用于API调用验证
三、常见安全问题&防范
- 弱密码
- 验证功能未做,调用频率限制
- 明文存密码或弱hash
- 敏感信息存在Cookie
- URL暴露Session Id
- 没有明确的设置,身份验证的Session/Token的过期时间
- 修改密码后没有立即失效Session/Token
- 验证失败的提示过于明确
- 验证代码存在逻辑缺陷
1.弱密码
弱密码就是能猜出来的密码,特点:
- 太短
- 在已知列表中可查询(如:字典、已经泄漏的密码库、常用词列表等)
- 跟公开的信息有关
黑客利用已知列表,对密码进行暴力破解;如果使用的是弱密码,增加了黑客破解的成功率。
解决办法:
- 应该限制密码的长度,复杂度,至少8位字符且包含特殊字符、字母跟数字
- 实用开源的弱密码检查库,进行密码校验
2.验证功能未做,调用频率限制
解决办法:
应该限制登陆、注册、找回密码等功能的请求频率,增加黑客破解的难度;可能的话应该实用两步验证,如短信验证、谷歌验证等。
3.明文存密码或弱hash
如果系统存在漏洞,明文存密码,将导致数据库被拖库,直接导致账号密码泄漏;有些系统为了解决这个问题,没有存明文密码,而是存密码的hash值。但如果直接对密码MD5,网上已经有很多可以逆向的库,弱hash并不安全。
解决办法:
- 不应该存储明文密码
- 对hash的密码加盐(salt),每个用户使用不同的盐,salt: 是指密码学安全的是随机字符串(例如使用 SecureRandom 生成的 32 字节或 64 字节字符串)最终可以表示为:hash(salt + password)
4.敏感信息存在cookie
cookie是用户可控内容,如果讲身份验证的敏感信息放在cookie中,用户可以轻易的将它修改成其他人的信息,从而冒用他人身份。
解决办法:
身份严重的信息应该放在session中,如果放在cookie中应该加密或者签名防止篡改。
5.URL暴露Session Id
这种情况在 JavaEE 应用中较为常见。在 JavaEE 中,允许使用 URL Rewriting 的技术,将 Session Id 写在 URL 中,主要是为了让 Session 在用户关掉浏览器的 Cookie 功能时仍然可用。
解决办法:
应将此功能禁止。
6.没有明确的设置,身份验证的session/Token的过期时间
Session Id、身份认证 Token/Key 需要设置合适的过期时间,并且在用户更改密码后,让这些认证信息失效。这是为了降低这些信息泄露后,身份被盗的风险。
7.修改密码后没有立即失效Session/Token
用户修改密码,有可能是意识到自己的密码已经被盗,立刻让旧的 Session Id、身份认证 Token/Key 失效,可以进一步降低风险。
8.验证失败的提示过于明确
在用户登录时,针对用户名不存在和密码不正确两种错误,给出了不同的提示。这对于用户来说是更为友好,但同样给黑客对系统的攻击带来了便利。从安全角度考虑,应在认证失败时给出一致的错误提示,例如登录失败的情况,可以统一使用错误提示“用户名或密码错误”,以增加黑客暴力破解账号的难度。
9.验证代码存在逻辑缺陷
因为一些低级错误或误用语言特性、API,导致认证逻辑被跳过的情况,并不少见。
建议解决办法:
- 完善单元测试用例
- 开发流程中引入 Code Review