Nezha Monitoring RoleMember SSRF with Full Response Body Reflection
Nezha Monitoring is vulnerable to a server-side request forgery (SSRF) vulnerability, where a low-privilege RoleMember user can call notification routes and send HTTP requests to a user-controlled URL, with the entire response body reflected back to the caller, potentially exposing intranet resources and causing denial of service.
Nezha Monitoring is affected by a server-side request forgery (SSRF) vulnerability that allows a low-privileged RoleMember user (Role==1) to perform actions normally restricted to RoleAdmin. The vulnerability resides in the notification routes POST /api/v1/notification and PATCH /api/v1/notification/:id, which are accessible to RoleMember users due to being wired through commonHandler instead of adminHandler. By crafting malicious HTTP requests to user-controlled URLs via these routes, attackers can force the Nezha dashboard’s hub to send requests to internal resources. The entire response body, without any size limitation, is then reflected back to the attacker, enabling the exposure of sensitive intranet data and potential denial-of-service (DoS) attacks by targeting large internal files. The vulnerability exists in versions up to commit 50dc8e660326b9f22990898142c58b7a5312b42a on the master branch.
Attack Chain
- Attacker obtains a valid
RoleMemberaccount, likely through legitimate registration or compromise. - Attacker crafts a malicious HTTP POST request to
/api/v1/notificationorPATCH /api/v1/notification/:id. - The request includes a JSON payload containing a user-controlled
URLparameter pointing to an internal resource (e.g.,http://192.168.1.1/admin/index.htmlorhttp://169.254.169.254/latest/meta-data/iam/security-credentials/). - The
NotificationServerBundle.Send()function is called, which uses eitherutils.HttpClientorutils.HttpClientSkipTlsVerify(depending on theVerifyTLSsetting) to send the request. Critically, the request is sent synchronously, andVerifyTLScan be set to false to bypass TLS certificate validation. - The target internal resource responds to the request. If the response status code is not in the 200-299 range, the entire response body is read via
io.ReadAlland included in an error message. - The error message, containing the full response body of the internal resource, is returned to the attacker via
newErrorResponsein a JSON response. - The attacker parses the JSON response to extract the reflected content of the internal resource.
- If the attacker targets a large internal file, the dashboard may experience a denial-of-service due to excessive memory consumption by
io.ReadAll.
Impact
Successful exploitation of this SSRF vulnerability allows a RoleMember to read the contents of internal web pages, potentially exposing sensitive information like API keys, configuration details, or internal application data. The ability to disable TLS verification expands the scope of attack to internal HTTPS endpoints. Furthermore, an attacker can trigger a denial-of-service (DoS) by targeting large internal files, causing the dashboard server to consume excessive memory. The vulnerability is rated as medium severity with a CVSS score of 6.4, considering the low privileges required and potential for limited data exposure and service disruption.
Recommendation
- Immediately apply the suggested fix by switching the
/notificationroutes to useadminHandlerto restrict access to administrators only. This mitigation directly addresses the root cause by preventingRoleMemberusers from accessing the vulnerable endpoints (cmd/dashboard/controller/controller.go:121-122). - Implement SSRF hardening measures in the
NotificationServerBundle.Send()function as suggested in the advisory. This should include validating the target URL, resolving the host IP address, and enforcing HTTP(S) schemes to prevent requests to arbitrary protocols. - Cap the response body size using
io.LimitReader(resp.Body, 4096)within theNotificationServerBundle.Send()function to mitigate the DoS risk associated with reading large internal files (model/notification.go:113-159). - Deploy the provided Sigma rule
Detect Nezha Monitoring SSRF Attempt via Notification APIto identify attempts to exploit this vulnerability by monitoring requests to the/api/v1/notificationendpoint with suspicious URLs.
Detection coverage 2
Detect Nezha Monitoring SSRF Attempt via Notification API
mediumDetects potential SSRF attempts in Nezha Monitoring by monitoring POST requests to the /api/v1/notification endpoint with URLs containing IP addresses, potentially indicating an attempt to access internal resources.
Detect Nezha Monitoring Large Response Body SSRF
lowDetects potential denial-of-service attacks by monitoring for error responses with exceptionally large bodies returned from the `/api/v1/notification` endpoint, indicative of an SSRF attempt targeting a large file.
Detection queries are available on the platform. Get full rules →