起因
公司目前维护的老项目较多,普遍使用Nacos 2.3.2作为配置中心和注册中心,JDK版本仍停留在8。
近期安全部扫描发现Nacos存在未授权访问漏洞:无需任何鉴权即可访问 /nacos/v1/console/namespaces 接口,直接获取命名空间列表信息。
官方建议升级到最新版本,但存在两个现实障碍:
Nacos 3.x 要求 JDK 17,与现有环境不兼容; 老系统维护人手不足,全量升级风险过高。
因此,本次方案确定为:不改环境、不升级主版本,直接从源码层面修复漏洞,重新打补丁包部署。
漏洞复现
无需携带任何Token,直接通过浏览器访问以下接口:
http://{IP}:8848/nacos/v1/console/namespaces服务器正常返回200,并吐出命名空间数据:
{"code": 200,"message": null,"data": [ {"namespace": "","namespaceShowName": "public","namespaceDesc": null,"quota": 200,"configCount": 0,"type": 0 } ]}可见 public 命名空间的基本信息已被完全暴露。未授权访问漏洞复现成功。
为什么没鉴权?
Nacos的鉴权依赖 AuthFilter 认证过滤器实现。该过滤器的核心逻辑是:只有标注了 @Secured 注解的方法才会被拦截校验,未标注的方法默认允许匿名访问。
关键代码如下:
Method method = methodsCache.getMethod(req);if (method == null) { chain.doFilter(request, response);return;}if (method.isAnnotationPresent(Secured.class) && authConfigs.isAuthEnabled()) {// 此处才真正执行鉴权逻辑}查看 NamespaceController 后发现:
增、删、改等写操作均正确标注了 @Secured;但查询类接口( getNamespaces、getNamespace、checkNamespaceIdExist)均未标注任何注解。
V2版本的 NamespaceControllerV2 中的 /list 接口存在同样问题。
根因:读接口遗漏了 @Secured 注解,导致鉴权过滤器直接放行,无论鉴权开关是否开启都无法拦截。
修复方案
修复思路很清晰:为所有遗漏的读接口统一补上 @Secured 注解,指定资源前缀和操作类型为 READ。
v1 接口修复(NamespaceController)
涉及三个接口:getNamespaces、getNamespace、checkNamespaceIdExist
修复后示例(以 getNamespaces 为例):
@GetMapping@Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.READ)public RestResult<List<Namespace>> getNamespaces() {return RestResultUtils.success(namespaceOperationService.getNamespaceList());}其余两个接口按相同方式补充注解即可。
v2 接口修复(NamespaceControllerV2)
涉及接口:getNamespaceList
@GetMapping("/list")@Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.READ, signType = SignType.CONSOLE)public Result<List<Namespace>> getNamespaceList() {return Result.success(namespaceOperationService.getNamespaceList());}注:v2接口统一使用了
signType = SignType.CONSOLE,与同文件内其他接口保持一致。
修改范围汇总:
涉及文件:2个 涉及接口:4个(v1三个 + v2一个) 无需额外导入包,相关类已存在
验证修复效果
1. 开启鉴权开关
仅修改源码还不够,需在 conf/application.properties 中开启鉴权开关:
nacos.core.auth.enabled=truenacos.core.auth.enable.userAgentAuthWhite=falsenacos.core.auth.server.identity.key=自定义keynacos.core.auth.server.identity.value=自定义valuenacos.core.auth.plugin.nacos.token.secret.key=自定义Base64密钥(至少32字节)安全提醒:
identity.key/value和token.secret.key请使用自定义值,切勿沿用官方示例默认值,以免造成新的安全隐患。集群部署时各节点需保持一致。
2. 验证未授权访问
配置完成后重启Nacos,再次访问漏洞接口:
http://{IP}:8848/nacos/v1/console/namespaces浏览器返回 403 Forbidden,提示 user not found!。
未授权访问已被成功拦截。
3. 验证正常登录访问
使用管理员账号登录Nacos控制台 http://{IP}:8848/nacos,携带合法Token访问命名空间管理页面,列表正常展示,功能不受影响。
修复完成,功能无损。
后续需关注
本次修复仅覆盖了 namespace 相关接口。Nacos 2.x 中其他console读接口(如配置查询、服务列表等)是否存在同类问题,后续建议按 AuthFilter 的拦截逻辑系统排查一遍。
对于不便升级的老系统,这种源码级精准打补丁的方式,算是一种务实可行的“续命”方案。
夜雨聆风