前言
前段时间有一个好心的白帽子给我们反馈了一个安全问题,就是官网登录之后的重定向 url 存在安全隐患,导致有可能会泄露用户的 oauth token。
具体是这样子操作的, 因为我们的好多产品线,都是同一个地方做单点登录的(其实就是在官网), 然后登录之后,会根据不同的产品,然后在登录校验成功之后,返回对应产品线的 oauth token。 并拼接到 redirect url 后面。
正常情况下, 我们当然会在登录成功之后, 校验 redirect url 的合理性。 但是这个校验是有漏洞的:1
/^http[s]?:\/\/.+\.example.com/ig.test(redirectUrl)
因为只判断域名是否有包含 .example.com
域名。并没有去判断一定是要 .example.com
域名结尾的。 导致最后被 biz.example.com.com
这种冒充的域名给通过了。
所以我如果是黑客的话, 我只要搞一个类似的 biz.example.com.com
的域名, 然后将这个我构建出来的登录页面 url 发送给受害者,让受害者去登录, 那么这个 oauth token 就会带到我的站点上来了。
1 | https://my.example.com/en/signin/?redirect=https%3A%2F%2Fbiz.example.com.com |
优化
所以这个 正则表达式要改一下, 域名必须是 .example.com
结尾的。 后面要么什么都不带,要么后一个字符就只能带 /
或者 :
, 前者是允许跟路径, 后置是允许带端口号。
所以后面就抽成一个公共方法:
1 | isSafeUrl: function(url) { |
这样子就不会被绕过去了。