将明文密码经过哈希后(MD5 或者 SHA-1) 再保存到数据库中, 是目前比较普遍的做法. 登录时验证密码的过程仅仅是验证用户提交的"密码"的哈希值,与保存在数据库中“密码”的哈希值是否一致。但是,目前黑客们广泛使用一种破解 MD5 后密码的方法:彩虹表.(即收集尽可能多的明文密码和明文对应的MD5值)
Session 与 认证
当用户登录完成后, 服务器端会创建一个新的会话(session), 会话中保存用户的状态和相关信息,服务器端维护所有在线用户的session, 常见的方法是把SessionID加密后保存在客户端的Cookie中,因为Cookie会随着HTTP请求头发送,且受到浏览器同源策略的保护.
SessionID 一旦在生命周期内被窃取,就等同于账户失窃。Session 劫持就是一种窃取用户 SessionID后,使用该SessionID 登录目标账户。
在 Cookie 中泄露SessionID 的方法很多, 常见有 XSS, 网络Sniff, 木马等, 通过给 Cookie标记httponly, 可以有效缓解XSS, 但是还有很多方法,需要从客户端入手防御.
Session Fixation 攻击
举例, A 有一辆汽车, A 把汽车卖给了B, 但是 A 并没有把所有的车钥匙交给B, 自己藏了一把,这时,如果B 没有给车换锁的话,A 仍然可以用藏下的钥匙使用汽车.
在用户登录网站的过程中, 如果登录前后用户的SessionID没有发生变化,则会存在Session Fixation问题。具体攻击过程是:
用户 X (攻击者)先获取到一个未经认证的SessionID, 然后将这个SessionID交给用户Y去认证,Y完成认证后,服务器并未更新此SessionID的值, 所以X可以直接通过这个SessionID登录Y账户. X 如何才能让 Y 使用这个SessonID呢, 如果sessionID保存在cookie中,比较难做到这一点,但是,如果sessionID保存在URL中,则X只需要诱使Y打开这个URL即可(所以安全策略:sessionID必须保存cookie中)
session 保持攻击
一般来说, session 是有生命周期的, 当用户长时间未活动,或者用户点击退出时,服务器将销毁 Session. Session 如果一直未能失效, 会导致什么问题?
比如前面讲的攻击者获得了一个用户的SessionID, 他可以用这个用户的身份进行登录, 如果攻击者一直持有一个有效的Session(比如间隔地刷新网页,以告诉服务器这个用户仍然活着),而服务器对活动的Session一直不销毁的话,攻击者就能通过这个办法一直使用该用户账户,成为一个永久的“后门”。
一般应用都会给session设置一个失效时间, 当到达失效时间后,session将被销毁.
Cookie 是有有效期的, 但是不能相信, 用户可以通过设置Cookie 的 Expire 时间来让 Cookie 永不过期.
所以, 防御这种攻击, 还是要在服务器端设置一个session的有效期,比如2天, 也就是2天后,session就会被销毁.
单点登录(SSO)
登录过程: 用户实际想登录中间的网站(命名为B), (通过最右边的 OpenID Provider单点认证提供方) 命名为C
- 用户访问想要登录的网站B.
- B 返回 login 界面. (此时提示用户可以使用OpenID 的方式登录)
- 用户选择使用 OpenID 方式登录
- Normalization
- Discovery
- B 请求跟C建立连接
- C 返回建立连接成功
- B 请求 authentication
- C 返回页面给用户
- 用户在C给的页面中输入必要信息(OpenID 和 password), 这个可以通过
- C 将认证结果告诉 B
- B 确定了用户身份后, B 开始查询用户的权限
- 根据用户的权限, 返回页面给用户