🔐 OAuth 回调劫持:为什么一个“差不多匹配”的 redirect_uri 会变成账号接管
很多人以为 OAuth 登录的风险主要在密码,其实大量事故根本不碰密码,而是出在回调地址
为什么这种事会发生?因为很多系统把“能跳回自己网站”理解成了“域名看起来像自己就行”。比如把
现实防护也别搞玄学,直接把边界钉死。
🧪 场景题:某公司把 OAuth 回调地址配置成
💡 核心记忆:OAuth 最怕的不是密码泄露,而是把授权码送错地方,所以
#Security
很多人以为 OAuth 登录的风险主要在密码,其实大量事故根本不碰密码,而是出在回调地址
redirect_uri 的校验太松。OAuth 的核心流程是:用户在身份提供方登录后,授权码 code 会被浏览器带回业务方预先登记的回调地址。如果服务端只做“包含关系”“前缀匹配”或者允许任意子路径、任意子域,攻击者就能把本该回到你应用的授权码,骗去自己的页面,再拿这个 code 去换取 access token,结果就是用户刚正常登录,账号却被别人接管了。为什么这种事会发生?因为很多系统把“能跳回自己网站”理解成了“域名看起来像自己就行”。比如把
https://app.example.com/callback 放宽成 https://app.example.com/*,甚至更糟,允许 https://*.example.com/*。一旦某个子域可被上传内容、可被接管,或者存在开放重定向,攻击者就能把 OAuth 服务器返回的 code 转走。麻烦在于,这不是用户输错密码,也不是浏览器中毒,而是协议落地时把“精确绑定”做成了“模糊容忍”。现实防护也别搞玄学,直接把边界钉死。
redirect_uri 必须做精确匹配,最好精确到完整 URL;不要支持通配符子域;不要依赖“先跳到本站再 302 到别处”的补救设计;客户端在发起授权时要带高强度 state 防 CSRF,移动端和 SPA 还应该用 PKCE,避免授权码被截获后直接复用。还有一个常被忽略的点:如果业务里存在 open redirect,它本身就可能成为 OAuth 回调劫持的跳板,所以开放重定向不是“小漏洞”,放到认证链路里就会升级。🧪 场景题:某公司把 OAuth 回调地址配置成
https://login.example.com/*,而 https://login.example.com/redirect?next= 存在开放重定向。攻击者发起授权请求,把回调写成 https://login.example.com/redirect?next=https://evil.com/catch。用户完成登录后,授权码最终会到谁手里?为什么?答案:login.example.comevil.com/catch💡 核心记忆:OAuth 最怕的不是密码泄露,而是把授权码送错地方,所以
redirect_uri 必须精确绑定,不能“差不多就行”。#Security