一个URL后面带个?跳转token=xxx,点进去就直接进了后台。页面这事我上周刚碰到。链接录漏
朋友的可直公司做了一套内部工单系统,前端用React写的接登,后端接口用JWT鉴权。跳转他给我看了一个链接,页面格式大概是链接录漏这样:
https://internal.xxx.com/dashboard?auth=eyJhbGciOiJIUzI1NiIs... 我点了一下。页面加载完,可直直接进了管理员面板。接登没有登录页,跳转没有验证码,页面没有二次确认。链接录漏浏览器的可直地址栏里那个auth参数就是完整的JWT token,前端拿到之后存进localStorage,接登后续所有请求带着它走。整个流程“顺畅”得让人害怕。
问题出在哪
这套逻辑本身不算罕见。很多SPA应用为了做“免登跳转”或者“单点登录回调”,会把token放在URL参数里传给前端。前端解析后写入本地存储,然后跳转到目标页面。开发阶段这么干省事,测试也方便,但上了生产环境就是在裸奔。
URL参数会出现在哪些地方?浏览器历史记录、服务器access log、Referer请求头、代理服务器日志、甚至用户复制粘贴分享出去的聊天记录。任何一个环节泄露,token就到手了。而且很多系统的JWT有效期设得特别长——7天、30天,有的干脆不过期。拿到token等于拿到账号,连密码都不用猜。
更麻烦的是,这种链接往往还带角色信息。我朋友那个系统,管理员和普通员工的token结构一样,只是payload里的role字段不同。也就是说,如果普通员工把自己的跳转链接里的token截下来,稍微改一下payload再重新签名——当然这需要密钥——但如果密钥管理也有问题,那就直接提权了。
我见过的几种变体
不只是JWT。有些系统用sessionId拼在URL里,形式像/login?sid=abc123,后端收到后直接根据sid恢复会话。还有的用Base64编码的用户名密码——对,明文Base64,不是加密——拼在链接里做“自动登录”。
最离谱的一个案例:某外包团队给客户做的OA系统,登录接口是GET /api/login?user=admin&pass=admin123。浏览器打开这个URL,返回一个302重定向到首页,同时Set-Cookie。也就是说,任何人只要知道这个URL格式,就能用任意账号密码登录。他们管这叫“接口调试方便”。
这些问题的共同点是:把身份凭证当成了普通参数在URL里传来传去。HTTP协议本身不保证URL的私密性,浏览器也不认为地址栏里的东西需要保护。
怎么防
短期方案:token放URL可以,但必须一次性。后端生成一个短时效的临时code,前端拿code换token,code用完即废。OAuth2的authorization code模式就是这么干的。
中期方案:别用URL传凭证。用POST body,或者走服务端渲染直接写Cookie(HttpOnly + Secure + SameSite)。前端拿不到token,XSS也偷不走。
长期方案:把登录态管理当安全工程做,不是当功能做。JWT有效期压到15分钟以内,配refresh token轮换。角色权限在后端每次请求都校验,别信前端传来的任何身份声明。
我朋友那个系统后来改了。改成后端生成一次性ticket,前端拿ticket换session,ticket60秒过期且只能用一次。改完之后他跟我说:“以前觉得方便,现在觉得以前就是没锁门。”
这话挺准确的。跳转登录本身不是漏洞,把凭证暴露在URL里才是。很多团队不是不知道,是觉得“内部系统没人看”。但内部系统的URL照样会出现在聊天工具、邮件、甚至截图里。安全这事,赌概率迟早输。


相关文章




精彩导读
热门资讯
关注我们