题目
设计安全的OAuth 2.0授权码流程并防御CSRF与授权码注入攻击
信息
- 类型:问答
- 难度:⭐⭐⭐
考点
OAuth 2.0协议, CSRF防护, 授权码注入攻击防护, 安全最佳实践
快速回答
安全实现OAuth 2.0授权码流程的核心要点:
- 强制使用state参数并绑定会话防止CSRF攻击
- 采用PKCE(Proof Key for Code Exchange)防御授权码注入攻击
- 使用HTTPS加密所有通信
- 严格验证重定向URI和客户端身份
- 设置短有效期的授权码(≤10分钟)和访问令牌
- 令牌存储使用HttpOnly Cookie或安全内存
1. 原理说明
OAuth 2.0授权码流程包含6个关键步骤:
1) 客户端初始化授权请求
2) 用户认证与同意授权
3) 授权服务器返回授权码
4) 客户端用授权码交换令牌
5) 授权服务器颁发访问令牌
6) 客户端使用令牌访问资源
主要安全威胁:
- CSRF攻击:攻击者诱导用户点击恶意链接,劫持授权流程
- 授权码注入:攻击者截获授权码并注入到自己的客户端
- 令牌泄露:通过XSS或中间人攻击窃取令牌
2. 防御方案与代码示例
CSRF防护(State参数)
// 客户端生成state(示例:Node.js)
const crypto = require('crypto');
const state = crypto.randomBytes(16).toString('hex');
// 存储state到会话
req.session.oauthState = state;
// 重定向到授权端点
res.redirect(`https://auth-server.com/authorize?
response_type=code
&client_id=CLIENT_ID
&redirect_uri=https://client.com/callback
&state=${state} // 关键防御点
&scope=openid%20profile`);PKCE防御授权码注入
// 生成code_verifier和code_challenge
const codeVerifier = crypto.randomBytes(32).toString('base64url');
const codeChallenge = crypto
.createHash('sha256')
.update(codeVerifier)
.digest('base64url');
// 授权请求添加PKCE参数
res.redirect(`https://auth-server.com/authorize?
...
&code_challenge=${codeChallenge}
&code_challenge_method=S256`);
// 用授权码交换令牌时提交verifier
const tokenResponse = await fetch('https://auth-server.com/token', {
method: 'POST',
body: new URLSearchParams({
grant_type: 'authorization_code',
code: authCode,
redirect_uri: 'https://client.com/callback',
client_id: 'CLIENT_ID',
code_verifier: codeVerifier // 关键验证点
})
});3. 最佳实践
- 重定向URI验证:授权服务器必须严格校验预注册的redirect_uri(包括路径和参数)
- 令牌安全:
- 访问令牌有效期≤1小时,刷新令牌≤90天
- SPA应用使用内存存储令牌,服务端应用使用HttpOnly Cookie
- 客户端认证:机密客户端必须使用client_secret,公共客户端使用PKCE
- 范围最小化:仅请求必要权限(如scope=profile而非scope=all)
4. 常见错误
- ❌ 未验证state参数导致CSRF攻击
- ❌ 允许开放重定向(如redirect_uri=http://attacker.com)
- ❌ 在URL片段中传递令牌(易被浏览器历史记录泄露)
- ❌ 使用长生命期的授权码(>10分钟)
- ❌ 客户端未校验令牌受众(audience claim)
5. 扩展知识
- OpenID Connect:在OAuth 2.0基础上添加ID Token(JWT格式),提供用户身份认证
- 令牌内省端点:资源服务器通过/oauth/introspect验证令牌有效性
- 动态客户端注册:RFC 7591允许程序化注册客户端,需配合软件声明(Software Statement)
- 进阶威胁:
- 令牌绑定(Token Binding)防御MITM攻击
- PAR(Pushed Authorization Requests)防止参数篡改