写在前面:合法学习边界
本文讲解 OAuth 2.0 授权码模式的原理与风险。不要针对真实第三方应用做授权码窃取、redirect_uri 绕过或令牌复用测试,必须在自建环境或明确授权的环境中学习。
一、OAuth 2.0 解决什么问题
OAuth 2.0 让用户可以把“某一类权限”授权给第三方应用,而不是把密码直接交给对方。
常见场景:
1
2
3
| 用 GitHub 登录一个第三方网站
第三方应用读取用户的邮箱
应用代替用户调用某个 API
|
它的核心思想是:授权 ≠ 把账号密码交出去。
二、授权码模式有哪些参与者
1
2
3
4
| 资源所有者:用户
客户端:第三方应用
授权服务器:负责认证和发令牌
资源服务器:持有受保护资源
|
理解这四个角色,后面所有风险都能对号入座。
三、授权码模式的流程
最常见的是授权码模式(Authorization Code),流程大致如下:
1
2
3
4
5
| 1. 客户端把用户重定向到授权服务器
2. 用户登录并同意授权
3. 授权服务器重定向回客户端,带上授权码 code
4. 客户端用 code + client_secret 换取 access_token
5. 客户端用 access_token 访问资源服务器
|
这个流程里,access_token 不会经过浏览器,只在客户端和授权服务器之间传递,这是它比隐式模式更安全的关键。
四、常见风险
1. redirect_uri 校验不严
授权服务器把 code 回传给客户端时,靠 redirect_uri 决定把 code 交给谁。如果校验不严,攻击者可能诱导授权服务器把 code 发给自己。
1
2
3
| redirect_uri 必须精确匹配
不能允许任意后缀匹配
不能接受可控的 open redirect
|
2. 缺少 state 导致 CSRF
授权服务器回跳时如果客户端不校验 state,攻击者可以把自己的 code 塞给受害者,造成账号绑定或会话污染。
1
2
| state 要随机且绑定会话
回调时必须校验 state
|
3. code 或 token 泄露
1
2
3
| code 出现在 URL、日志、Referer
token 存在 localStorage 且无隔离
token 没有过期时间
|
4. 权限过大
第三方申请了超出业务需要的 scope,比如只读邮箱却申请了删除权限。
影响与危害
OAuth 配置问题能造成:
1
2
3
4
| 授权码被劫持
账号绑定被篡改(CSRF)
令牌泄露导致越权访问
第三方过度授权
|
风险等级:中到高。
五、防御建议
1
2
3
4
5
6
| redirect_uri 白名单精确匹配
强制校验 state 防回调 CSRF
code 一次性使用、短有效期
access_token 尽量不落浏览器,落浏览器也要短效+独立存储
按最小权限申请 scope
对 code/token 泄露做监控
|
修复
1
2
3
4
5
6
| 回调地址白名单精确匹配
强制校验 state 防回调 CSRF
code 一次性使用、短有效期
access_token 短效并独立存储
最小权限申请 scope
修复后复测:篡改回调/缺失 state 均被拒绝
|
六、报告中的正确写法
示例:
1
2
3
| 发现:授权回调未校验 state,且 redirect_uri 允许非精确匹配,攻击者可替换回调地址。
风险:可能导致授权码被劫持、账号绑定被篡改。
建议:回调精确校验 redirect_uri;生成并校验随机 state;code 设置为一次性短效。
|
报告要写清楚验证步骤和影响,而不是只写“OAuth 配置不规范”。
七、小结
OAuth 2.0 不是“登录就一定安全”。它的安全取决于 redirect_uri、state、code 有效期和令牌存储这几个边界。把这些边界想清楚,就能看懂很多第三方登录相关的漏洞。