使用OAuth实现统一登录的安全防范

『23年05月21日』

当使用 OAuth2.0 去实现应用的统一登录验证时,会存在一些安全问题,值得开发者们思考与防范。特指 authorization code 模式。

回顾一下authorization code授权登录的整个流程:

  1. OAuth Provider 注册一个应用,获取 app key(client ID) 和 app secret,并填写回调地址;

  2. client 端引导用户打开统一登录页面,并携带app key

  3. 用户登录完成后跳转到指定的redirect_uri,并返回authorization code

    题外话:implicit 模式貌似可在 step3 直接返回 token

  4. 第三方 app 服务端调用OAuth Provider 获取 token 的 API,通常是/oauth/token, 携带authorization codeapp keyapp secret去换取 token.

  5. 拿到 token 后就算登录成功了

流程:

authorization_code_flow

潜在的安全问题:

中间人攻击

攻击者通过劫持、伪造网络基站等方式监听了你的通信信息。如果使用了明文传输,那么很容易获取到你的账号密码。但是中间人攻击的方式对于 OAuth 来说,最多也只是能够获取到 Authorization code,看起来作用不太大。每个 code 被设计为具有时效性+只能使用一次,且只能搭配 app secret 使用, secret 一般只存在服务端。

重新拼接authorization URL,替换回调地址

如果开发者没有在 OAuth Provider Center 去设置精确的回调地址,比如使用*或者http://,那就容易因为被替换回调地址而泄露了 authorization code,攻击者在拿到 authorization code 之后,再获取你的 app key(公开的) 和 app select 就可以去替换 token 了。所以也要避免自己的 app secret 泄露,因此一般 app secret 都存储在服务端,换取 token 的流程也应该在 app 的服务端进行,而不在前端。

防范措施:

  • redirect URL 应该做精确比配校验
  • 不暴露(使用) app secret,比如使用 PKCE

PKCE 是为了防止 authorization code 泄露而设计的
以下是使用 PKCE 增强安全性的步骤

  1. 创建随机的 Code Verifier:客户端生成一个随机的 Code Verifier。Code Verifier 是一个随机的、高熵的字符串,可以使用 Base64 URL 编码。

  2. 计算 Code Challenge:客户端使用 SHA256 哈希算法计算 Code Verifier 的哈希值,并对哈希值进行 Base64 URL 编码,生成 Code Challenge。

  3. 发起授权请求:在授权请求中,客户端将 Code Challenge 和相应的哈希算法(通常为”code_challenge_method=S256”)发送给授权服务器。

  4. 授权服务器验证:授权服务器接收到授权请求后,将 Code Challenge 进行验证。如果验证通过,它将返回授权码给客户端。

  5. 交换授权码:客户端使用授权码和原始的 Code Verifier 来交换访问令牌。授权服务器会验证 Code Verifier 是否与之前发送的 Code Challenge 匹配。只有匹配的情况下,才会返回访问令牌。

reference

流程图来自:https://juejin.cn/post/6844903880896020488