Nacos 3.1.1 升级 3.2.4 修复权限绕过漏洞记录

Nacos 3.1.1 升级 3.2.4 修复权限绕过漏洞记录

记录时间:2026-08-28 至 2026-08-30
环境:公司测试 / 生产xc / 生产xc-kj 三套 Nacos,nacos-server v3.1.1 升 v3.2.4,K8s StatefulSet 2 副本 + 外置 MySQL,Harbor 内网仓库(信创 ARM64)

一、事情的由头

2026-08-28 长亭发了通告:Nacos 3.0.0 至 3.2.3 管理接口权限绕过。3.x 对不同类型接口做了分层鉴权,部分管理接口的鉴权范围配置不一致,特定默认配置下没进预期的管理权限校验流程,不带凭证就能创建账户、调整角色、授资源权限,能做持久化后门。高危、远程、无需认证、无需交互,修复版 3.2.4 已发布,修复复杂度低。

我先盘家底。三套环境的镜像配置都在仓库里,grep 一把:

环境 镜像 tag 暴露面
公司测试(xc/test) v3.1.1 NodePort 30848 + Ingress 控制台
生产xc(xc/xc-prod) v3.1.1 Ingress 控制台
生产xc-kj(kj/kj-prod) v3.1.1 Ingress 控制台

全部落在受影响区间。结论没有悬念:升级。

二、升级前先搞清楚鉴权开没开,这里我判断错了一回

我盯着三套环境 application.properties 里那行 nacos.core.auth.enabled=false,第一反应是:StatefulSet 里的 NACOS_AUTH_ENABLE=true 这个 env 没被 properties 引用,鉴权实际是关的,紧急度要上调。

把镜像里的启动脚本翻出来一看,当场打脸:

if [[ ! -z "${NACOS_AUTH_ENABLE}" ]]; then
  JAVA_OPT="${JAVA_OPT} -Dnacos.core.auth.enabled=${NACOS_AUTH_ENABLE}"
fi

启动脚本把 env 转成 JVM 系统属性,而 Spring 的属性源里系统属性高于 application.properties,properties 里那行 false 是被覆盖的死配置。三套环境的实际生效状态:

配置项 文件里写的 实际生效 生效方式
nacos.core.auth.enabled false true env NACOS_AUTH_ENABLE 经启动脚本转 -D 覆盖
nacos.core.auth.admin.enabled true true properties 直配
nacos.core.auth.console.enabled true true properties 直配

三个开关全开。那缓解在位,还升不升?升。通告里的绕过本体就是”鉴权开启状态下管理接口没进预期校验流程”,缺陷在代码里,官方也明说临时措施不能替代升级,auth.enabled=true 只是把 Open API 这层收窄,admin 接口的绕过挡不住。

这条给我记死了:查 nacos 容器化的配置生效值,conf 文件和 env 两个来路都要看,-D 覆盖这条最容易漏。

三、升级窗口的一盆冷水:2 副本 Raft

三套都是 2 副本,Raft 多数派是 2。滚动替换任何一台,集群就失去多数派,配置发布中断,等节点起来重新同步(一般 1 到 3 分钟一台)。运行中的业务不怕:客户端有配置本地快照和服务发现缓存兜底,短暂重连自动恢复。所以升级窗口冻结配置发布就行,影响面是”窗口内改不了配置”,不是”窗口内业务挂”。

四、test 环境升级,apply 先吃了个 Forbidden

先查 Harbor 有没有现成的 v3.2.4,curl 一把 tags:v3.1.0、v3.1.1、v3.2.4 都在,镜像这关免了。改 tag,apply,API 直接拒了:

The StatefulSet "nacos" is invalid: spec: Forbidden: updates to statefulset spec
for fields other than 'replicas', 'ordinals', 'template', 'updateStrategy',
'persistentVolumeClaimRetentionPolicy' and 'minReadySeconds' are forbidden

我盯着报错看:镜像在 template 里,template 明明在允许清单里,那就是别的锁死字段跟线上对不上。把线上 sts 拉下来对比,翻到真凶:

kubectl get sts nacos -n tools -o jsonpath='{.spec.volumeClaimTemplates[0].spec.resources.requests.storage}'
# 线上实际 5Gi,仓库文件写的 10Gi

这条漂移怎么来的:历史上有过扩容意图,10Gi 写进了文件,但 volumeClaimTemplates 创建后不可变,那次 apply 压根没生效,10Gi 一直躺在文件里当摆设,这次连带把 tag 升级也拦了。仓库改成 5Gi,一把过。

注意:sts 的 volumeClaimTemplates 创建后不可变。仓库和线上漂移时 apply 是原子拒绝,不会半套生效,失败是安全的;想扩容的正确路径是单独 patch PVC,改 sts 文件没有用。

滚动 2/2 完成,两 Pod Running 零重启。功能模式也验了:

kubectl exec nacos-0 -n tools -- ps aux | grep -o 'nacos.functionMode=[a-z]*'
# 输出:nacos.functionMode=microservice

五、顺手关掉 AI 模块和旧版控制台

AI 模块用不上,升级时顺手关掉,改动如下:

参数 说明
FUNCTION_MODE(StatefulSet env) microservice 运行时不加载 AI 模块,Config+Naming 组合模式
nacos.extension.ai.enabled false AI 模块总开关,console 隐藏 AI 条目、AI console API 禁用
nacos.plugin.ai-pipeline.enabled false AI 发布管线(skill-scanner),docker 版 conf 默认 true,一并关
nacos.console.ui.default legacy 控制台默认用旧版 UI(new/legacy 二选一,默认 new),旧版也可走 /legacy/ 路径

env 和 properties 两个开关互为兜底,谁失效另一个兜着。逐项的官方文档佐证如下。

官方文档佐证

AI 模块总开关的定义插件概览:状态、模块开关和选择配置):

层次:模块或能力总开关。职责:决定核心流程是否进入某类插件能力,也可用于延迟加载整个类型。示例:nacos.extension.ai.enabled、nacos.plugin.visibility.enabled、nacos.plugin.ai-pipeline.enabled

关闭写法与版本支持控制台手册 FAQ 9.2:如何关闭控制台的AI功能相关页面):

在 application.properties 中添加:

### 是否开启AI功能,默认开启
nacos.extension.ai.enabled=false
### 是否开启AI功能中MCP相关页面/功能,默认关闭
nacos.ai.mcp.registry.enabled=false

修改后需要重启 Nacos 实例方可生效。该配置在 3.2.x 版本中支持,3.1.x 及以下版本不支持。
注意:AI功能页面关闭后,不影响配置中心和服务发现模块的功能。

FUNCTION_MODE=microservice 的语义部署概览:按功能模式选择模块):

功能模式只控制运行时加载的模块,仍然使用标准 Nacos 发行包,不会从发行包中移除 AI 相关 JAR。使用 -f microservice 后,无需再设置 nacos.extension.ai.enabled=false。

Nacos 3.2.0、3.2.1,或无法传递 -f 参数的部署方式,可以在 ${nacos.home}/conf/application.properties 中设置 nacos.extension.ai.enabled=false,关闭 AI 模块并保留 Config 和 Naming 模块。

旧版控制台默认入口控制台手册:旧版控制台兼容说明):

旧控制台仍可通过配置 nacos.console.ui.default=legacy 作为默认入口,也可以直接访问 /legacy/。

### 设置控制台默认UI为旧版,可选值: new/legacy,默认 new
nacos.console.ui.default=legacy

ConfigMap 是启动读取,改完要重启 Pod 才生效,别指望热加载。

六、验证清单

kubectl exec nacos-0 -n tools -- ps aux | grep -o 'nacos.functionMode=[a-z]*'
# 期望输出:nacos.functionMode=microservice
  • console 版本号 3.2.4,AI 相关页面消失(extension.ai.enabled 生效的直观标志)
  • 默认落在旧版控制台界面(ui.default=legacy 生效)
  • 发一个测试配置,确认 Raft 写入和推送恢复
  • 挑一个业务应用看日志,无配置拉取和注册报错

七、遇到的问题速查表

现象 根因 解法
apply sts 报 spec Forbidden volumeClaimTemplates 10Gi 与线上 5Gi 漂移 仓库改成跟线上一致
properties 写 false 实际是 true env 经启动脚本转 -D,系统属性优先级更高 查生效值要把 -D 覆盖一起看
AI 关闭 key 在镜像 conf 里找不到 docker 版 conf 与源码 distribution 版是两份文件,前者没跟上 以官方文档为准,ConfigMap 自带覆盖
3.1.1 上配 extension.ai.enabled 无效 该配置 3.2.x 才支持 与升级同批生效
ConfigMap 改了配置没变化 properties 是启动读取,无热加载 rollout restart sts
单加 FUNCTION_MODE 怕静默失败 env 方式失败时 AI 回退默认开启 与 properties 开关两边一起加

八、注意事项

  • 升级窗口冻结配置发布。2 副本 Raft 少一台就失多数派,业务有本地快照兜底不挂,但窗口内发不了配置。
  • sts 模板字段漂移要自查。手动维护 sts 文件的,apply 前先对一遍 volumeClaimTemplates 和线上实际值,历史扩容意图最容易变成这种”躺在文件里的死配置”。
  • properties 里那行 auth.enabled=false 是死配置。实际被 -D 覆盖成 true,建议改成 ${NACOS_AUTH_ENABLE:false} 占位符写法,不然下一个读文件的人还会栽一遍。
  • AI 关闭的验证在 console 不在文档。写上无害,生效与否升级后一眼便知。
  • 升级后复核账户和密钥是通告要求的动作。查 users、roles、permissions 表有无异常账户,轮换管理员密码,漏洞暴露窗口从部署 3.1.1 起算;identity 还是公开默认值(nacos_docker / nacos_docker@123),token 三套环境同一个串,轮换挂账。

九、参考资料

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇