Advisories for Golang/Github.com/Nezhahq/Nezha package

2026

Nezha's authenticated agents can forge service-monitor results for other users' services

Nezha accepts service-monitor TaskResult messages from an authenticated agent based only on whether the reported service ID exists. The dashboard authenticates the agent and derives the reporter server ID from the gRPC stream, but the service-monitor result worker does not verify that the reporter server was selected for that service, belongs to the service owner, or was actually assigned that monitoring task. A low-privilege user with a valid agent secret …

Nezha's authenticated DDNS webhook configuration allows blind SSRF from the dashboard host

An authenticated Nezha dashboard user can create or update a DDNS profile with provider webhook and configure an arbitrary webhook_url, HTTP method, request body, and headers. When DDNS is triggered for a server that uses that profile, the dashboard process sends the configured request with utils.HttpClient without the SSRF protections used by notification webhooks. This allows a low-privileged authenticated user who controls an owned server/DDNS profile to make the dashboard …

Nezha Monitoring: RoleMember-reachable SSRF with full response-body reflection via POST /api/v1/notification

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 …

Nezha Monitoring: RoleMember can run shell on every server (cross-tenant RCE) via POST /api/v1/cron

nezha's dashboard supports two user roles: RoleAdmin (Role==0) and RoleMember (Role==1). The cron routes POST /api/v1/cron and PATCH /api/v1/cron/:id are wired through commonHandler (any authenticated user) rather than adminHandler, and the per-server permission check on cron creation has a vacuous-true bypass. A RoleMember user can create a scheduled cron task with Cover=CronCoverAll, Servers=[] and an arbitrary Command. At every tick of the scheduler, the dashboard pushes that command to every …

Nezha Monitoring: RoleMember can fire other users' cron tasks via AlertRule.FailTriggerTasks (no ownership check)

createAlertRule and createService (and their update* siblings) accept FailTriggerTasks []uint64 and RecoverTriggerTasks []uint64 — IDs of cron tasks to fire when the alert/service trips. The validation function only validates the alert's Rules.Ignore server map; it never checks that the cron task IDs in FailTriggerTasks / RecoverTriggerTasks belong to the caller. When the alert fires, singleton.CronShared.SendTriggerTasks(taskIDs, triggerServer) (service/singleton/crontask.go:113-127) looks up those task IDs in the global cron registry and executes them …

Nezha Monitoring: Nezha WebSocket server stream discloses cross-tenant server telemetry to authenticated members

Any authenticated non-admin member can connect to the server-status WebSocket and receive telemetry for all servers, including servers owned by other users. The normal server list API filters objects by HasPermission, but the WebSocket stream treats the presence of any authenticated user as authorization for the full unfiltered server list.