T3MP3ST v1 — hardened launch (AGPL, verify-claims 24/24, leak-scrubbed)
This commit is contained in:
1 parent
c7a356bde0
commit
6c57e09023
242 files changed
+1761
-51038
No files matched your search
@@ -1 +1 @@
|
||||
{"id": "GHSA-w4g9-mxgg-j532", "cve": "CVE-2026-46717", "repo": "nezhahq/nezha", "cwes": ["CWE-863", "CWE-918"], "vuln_files": ["model/notification.go", "model/notification_test.go"], "duration_sec": 104, "error": null, "strict": false, "lenient": false, "findings_scored": [{"fileMatch": false, "lineProx": false, "cweMatch": false, "hit": false, "title": "Nil-pointer dereference / division-by-zero in alert cycle-transfer rule evaluation (DoS)", "file": "model/rule.go", "line": 187, "cwe": "CWE-476"}, {"fileMatch": false, "lineProx": false, "cweMatch": false, "hit": false, "title": "Panic on slices.Max over empty slice for gpu_max / temperature_max rules (DoS)", "file": "model/rule.go", "line": 70, "cwe": "CWE-248"}, {"fileMatch": true, "lineProx": false, "cweMatch": false, "hit": false, "title": "Unescaped notification template substitution enables JSON/body injection in outbound notifications", "file": "model/notification.go", "line": 79, "cwe": "CWE-116"}], "n_findings": 3, "findings": [{"title": "Nil-pointer dereference / division-by-zero in alert cycle-transfer rule evaluation (DoS)", "file": "model/rule.go", "line": 187, "cwe": "CWE-476", "vuln_class": "dos", "severity": "high", "description": "Rule.CycleStart is a *time.Time tagged validate:\"optional\" and Rule.CycleInterval is an unvalidated uint64; both are populated directly from the alert-rule API form (AlertRuleForm.Rules -> Rule) and persisted/loaded via AlertRule.RulesRaw JSON (un)marshaling with no validation. In Rule.Snapshot, for any rule whose Type ends in '_cycle' (IsTransferDurationRule()==true), the block at lines 141-163 ALWAYS calls u.GetTransferDurationStart() and u.GetTransferDurationEnd() at lines 161-162 \u2014 independently of the 'if u.CycleInterval != 0' guards used earlier (lines 97/104/111). GetTransferDurationStart() begins with 'startTime := *u.CycleStart' (line 187): if cycle_start was omitted in the rule JSON, this dereferences a nil *time.Time and panics. The same functions also compute 'interval := 3600 * int64(u.CycleInterval)' and divide by it in the default/hour branch (lines 217/257); with cycle_interval==0 this is an integer division by zero panic. Either panic aborts the periodic alert-evaluation goroutine that runs Snapshot for every monitored server, taking down monitoring/alerting (availability) for the whole dashboard.", "poc": "As an authenticated user create/save an alert rule with a rule object: {\"rules\":[{\"type\":\"transfer_in_cycle\",\"max\":1}]} (no cycle_start, cycle_interval=0, cycle_unit unset). On the next alert tick the server evaluates Rule.Snapshot -> GetTransferDurationStart() -> '*u.CycleStart' nil dereference panic (and/or 3600*0 division-by-zero in the default unit branch), crashing the alerting loop.", "confidence": 0.78}, {"title": "Panic on slices.Max over empty slice for gpu_max / temperature_max rules (DoS)", "file": "model/rule.go", "line": 70, "cwe": "CWE-248", "vuln_class": "dos", "severity": "medium", "description": "In Rule.Snapshot, the 'gpu_max' branch calls slices.Max(server.State.GPU) (line 70) and the 'temperature_max' branch calls slices.Max(temp) (line 136). Go's slices.Max panics when given a zero-length slice. server.State.GPU and Temperatures originate from agent-reported HostState (PB2State) and are not guaranteed non-empty; an agent reporting no GPU/temperature data combined with an admin-configured 'gpu_max'/'temperature_max' alert rule causes slices.Max to panic and crash the alert-evaluation goroutine.", "poc": "Configure an alert rule {\"rules\":[{\"type\":\"gpu_max\",\"max\":1}]} for a server whose agent reports no GPU data (empty GPU slice). On evaluation, slices.Max([]) panics.", "confidence": 0.5}, {"title": "Unescaped notification template substitution enables JSON/body injection in outbound notifications", "file": "model/notification.go", "line": 79, "cwe": "CWE-116", "vuln_class": "info-disclosure", "severity": "low", "description": "reqBody()'s Form branch (line 79) calls replaceParamsInString with a nil mod function, so attacker-influenced server fields (e.g. Server.Name, public note, agent-reported metrics) are substituted into form/body parameters without escaping. Combined with attacker-controlled notification URL/headers (setRequestHeader sets arbitrary headers, Send may skip TLS verification), this allows content injection into outbound requests, though it requires notification configuration privileges.", "poc": "Set a server name containing form-breaking characters and a Form-type notification whose body references #SERVER.NAME#; the value is inserted unescaped into the urlencoded body.", "confidence": 0.2}], "transcript": ""}
|
||||
{"id": "GHSA-w4g9-mxgg-j532", "cve": "CVE-2026-46717", "repo": "nezhahq/nezha", "cwes": ["CWE-863", "CWE-918"], "vuln_files": ["model/notification.go", "model/notification_test.go"], "duration_sec": 155.7, "error": null, "strict": false, "lenient": false, "findings_scored": [{"fileMatch": false, "lineProx": false, "cweMatch": false, "hit": false, "title": "Nil pointer dereference in Rule.GetTransferDurationStart via cycle rule without cycle_start (dashboard DoS)", "file": "model/rule.go", "line": 187, "cwe": "CWE-476"}, {"fileMatch": false, "lineProx": false, "cweMatch": false, "hit": false, "title": "Integer divide-by-zero in Rule.GetTransferDurationStart/End for hour-unit cycle rule with cycle_interval=0 (dashboard DoS)", "file": "model/rule.go", "line": 217, "cwe": "CWE-369"}], "n_findings": 2, "findings": [{"title": "Nil pointer dereference in Rule.GetTransferDurationStart via cycle rule without cycle_start (dashboard DoS)", "file": "model/rule.go", "line": 187, "cwe": "CWE-476", "vuln_class": "dos", "severity": "high", "description": "Rule.CycleStart is a *time.Time tagged `validate:\"optional\"`, so it may be nil/omitted when a user creates an AlertRule. In Rule.Snapshot, once a rule's Type ends with '_cycle' (IsTransferDurationRule() == true), the block at rule.go:141 is entered unconditionally (independent of Max/Min/CycleInterval) and calls GetTransferDurationStart() at line 161 and GetTransferDurationEnd() at line 162. GetTransferDurationStart begins with `startTime := *u.CycleStart` (line 187), dereferencing the nil pointer and panicking. The AlertRule rules are attacker-controlled: they are supplied as JSON via the alert-rule create/update API (persisted to RulesRaw, reloaded in AlertRule.AfterFind). Snapshot is invoked by the alert-checking loop whenever a monitored server sends a state report, so the panic crashes the dashboard's alerting goroutine/process. No validation anywhere enforces a non-nil CycleStart for cycle-type rules.", "poc": "As an authenticated user, create an alert rule whose rules contain a cycle-type entry with no cycle_start, e.g. POST /api/v1/alert-rule with body: {\"name\":\"x\",\"rules\":[{\"type\":\"transfer_in_cycle\",\"max\":1,\"cycle_unit\":\"hour\",\"cycle_interval\":1}]} (note: cycle_start omitted -> nil). On the next server state report, Rule.Snapshot -> GetTransferDurationStart dereferences nil *CycleStart and panics, taking down the dashboard.", "confidence": 0.82}, {"title": "Integer divide-by-zero in Rule.GetTransferDurationStart/End for hour-unit cycle rule with cycle_interval=0 (dashboard DoS)", "file": "model/rule.go", "line": 217, "cwe": "CWE-369", "vuln_class": "dos", "severity": "high", "description": "For a cycle-type rule with CycleUnit empty or 'hour' (the default branch), GetTransferDurationStart computes `interval := 3600 * int64(u.CycleInterval)` (line 216) and then divides by `interval` (line 217: `(time.Now().Unix()-u.CycleStart.Unix())/interval*interval`). CycleInterval is tagged `validate:\"optional\"` and defaults to 0, so interval == 0 causes an integer divide-by-zero panic. Reached unconditionally from Rule.Snapshot line 161 for any '_cycle' rule (the CycleInterval!=0 guards at lines 97/104/111 do NOT protect the line-161 call). Same defect in GetTransferDurationEnd line 257. Attacker-controlled rule JSON triggers a dashboard-wide panic on server state report.", "poc": "Create alert rule: {\"name\":\"x\",\"rules\":[{\"type\":\"transfer_out_cycle\",\"max\":1,\"cycle_start\":\"2024-01-01T00:00:00Z\",\"cycle_unit\":\"hour\",\"cycle_interval\":0}]}. Next server report -> GetTransferDurationStart divides by zero -> panic/DoS.", "confidence": 0.6}], "transcript": ""}
|
||||
Reference in new issue
Block a user