面试题答案
一键面试可能面临的安全风险
- 令牌劫持:攻击者可能通过中间人攻击、XSS(跨站脚本攻击)等手段获取用户的JWT,然后冒用用户身份进行操作。
- 密钥泄露:如果用于签名JWT的密钥泄露,攻击者可以伪造有效的JWT,从而绕过身份验证和授权机制。
- 过期时间设置不当:若JWT的过期时间设置过长,会增加令牌被劫持后造成危害的时间窗口;若设置过短,可能给用户带来频繁重新登录的不便。
- 重放攻击:攻击者捕获合法的JWT,并在后续重复使用它来访问API,即使在用户已经登出或令牌应失效的情况下。
防范措施
- 令牌存储与传输安全
- HTTPS:始终使用HTTPS协议进行API通信,防止中间人攻击窃听和篡改数据,包括JWT。
- 安全的存储位置:建议将JWT存储在HTTP-only的Cookie中,避免通过JavaScript访问,防止XSS攻击窃取令牌。如果必须在前端存储,可使用LocalStorage或SessionStorage,并结合严格的访问控制和加密。
- 密钥管理
- 强密钥生成:使用足够长度和复杂度的密钥,例如256位或更长的随机字符串。
- 密钥保护:将密钥存储在安全的地方,如服务器的环境变量或专门的密钥管理服务(KMS)中,避免在代码中硬编码。
- 定期更换密钥:定期更新签名密钥,降低因密钥泄露带来的风险。当密钥更新时,需要确保系统能够正确处理新旧JWT的验证。
- 合理设置过期时间
- 短期令牌:设置较短的JWT过期时间,例如15 - 30分钟,降低令牌被劫持后的风险。
- 刷新令牌:引入刷新令牌机制,当JWT过期时,用户可以使用刷新令牌获取新的JWT,而无需重新进行完整的登录流程。刷新令牌应长期有效,但同样需要安全存储和传输。
- 防范重放攻击
- 一次性使用令牌:在JWT中添加唯一标识符(如UUID),并在服务器端维护已使用令牌的列表。每次验证JWT时,检查该标识符是否已被使用过。
- 时间戳验证:在JWT中包含签发时间(iat)和过期时间(exp)字段,服务器验证时确保当前时间在有效范围内,且JWT未被提前使用(防止提前捕获并在过期前重放)。
- GraphQL特定防范
- 输入验证:对GraphQL的输入参数进行严格验证,防止恶意用户通过构造恶意查询来利用JWT相关漏洞,例如注入攻击。
- 权限控制:在GraphQL解析器中实现细粒度的权限控制,确保只有经过授权的用户能够访问特定的查询和突变操作。即使JWT被劫持,攻击者也无法执行超出权限的操作。