如何防范被盗Access Token被非法刷新?
这确实是个容易被忽略的安全漏洞——本来短有效期的Access Token是为了缩小风险范围,结果因为Refresh Token的存在反而让黑客能持续获取权限。下面是几个针对性的解决思路:
绑定Access Token与客户端上下文信息
让客户端在每次请求(包括刷新Token的请求)中,除了携带Access Token,还要附上设备指纹(比如设备ID、MAC地址哈希值)、请求IP、User Agent等上下文数据。认证服务器在发放Refresh Token时,同时记录这些上下文信息;当收到刷新请求时,先验证当前请求的上下文是否与记录的一致。如果不一致,直接拒绝刷新请求,甚至吊销对应的Refresh Token。这样黑客即使拿到了过期的Access Token,由于其使用的设备、IP等与原用户不符,也无法通过刷新获取新的权限。给Refresh Token设置有效期并强制轮换
不要使用永久有效的Refresh Token,给它设置一个合理的有效期(比如7天或30天)。同时,每次成功刷新Access Token时,认证服务器要返回一个新的Refresh Token,并立即作废旧的Refresh Token。这样一来,黑客手中的过期Access Token对应的Refresh Token要么已经过期,要么已经被替换成新的,根本无法用来发起刷新请求。引入客户端身份认证机制
对于机密客户端(比如后端服务、桌面应用),要求其在调用刷新Token接口时,携带合法的Client ID和Client Secret进行身份验证;对于公共客户端(比如SPA、移动端),采用证书绑定或设备认证的方式,确保只有授权的客户端才能发起刷新请求。黑客即使窃取了Access Token,没有合法的客户端身份凭证,也无法触发Token刷新流程。实现实时Token吊销机制
维护一个Token黑名单(可以用Redis等缓存系统实现),当用户发现账号异常(比如异地登录、密码泄露)时,允许其主动触发Refresh Token的吊销操作。认证服务器在处理刷新请求前,先检查对应的Refresh Token是否在黑名单中,如果是则直接拒绝。同时配合短有效期的Refresh Token,能进一步缩小黑客可能利用的风险窗口。使用PKCE(Proof Key for Code Exchange)机制
针对SPA、移动端这类无法安全存储Client Secret的公共客户端,强制启用PKCE流程。客户端在发起授权请求前,生成一个随机的code_verifier,并将其哈希后的code_challenge发送给认证服务器;在刷新Token时,必须携带原始的code_verifier,认证服务器验证通过后才允许刷新。由于code_verifier只有合法客户端自己知道,黑客即使拿到了Access Token,也无法提供正确的code_verifier来完成刷新。
内容的提问来源于stack exchange,提问作者Arthur




