Skip to content

Commit 877fa1e

Browse files
1 parent ee26c95 commit 877fa1e

1 file changed

Lines changed: 54 additions & 0 deletions

File tree

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-68f8-9mhj-h2mp",
4+
"modified": "2026-03-30T18:41:15Z",
5+
"published": "2026-03-30T18:41:15Z",
6+
"aliases": [],
7+
"summary": "OpenClaw has a Gateway HTTP /v1/models Route Bypasses Operator Read Scope",
8+
"details": "> Fixed in OpenClaw 2026.3.24, the current shipping release.\n\n## Summary\n\nThe OpenAI-compatible HTTP endpoint `/v1/models` accepts bearer auth but does not enforce operator method scopes.\n\nIn contrast, the WebSocket RPC path enforces `operator.read` for `models.list`.\n\nA caller connected with `operator.approvals` (no read scope) is rejected for `models.list` (`missing scope: operator.read`) but can still enumerate model metadata through HTTP `/v1/models`.\n\nConfirmed on current `main` at commit `06de515b6c42816b62ec752e1c221cab67b38501`.\n\n## Details\n\nThe WS control-plane path enforces role/scope checks centrally before dispatching methods. For non-admin operators, this includes required method scopes such as `operator.read` for `models.list`.\n\nThe HTTP compatibility path for `/v1/models` performs bearer authorization and then returns model metadata; it does not apply an equivalent scope check.\n\nAs reproduced, a caller with only `operator.approvals` can:\n\n1. connect successfully,\n2. fail `models.list` over WS with `missing scope: operator.read`,\n3. fetch `/v1/models` over HTTP with status 200 and model data.\n\nThis is a cross-surface authorization inconsistency where the stricter WS policy can be bypassed via HTTP.\n\n## Impact\n\n- Callers lacking `operator.read` can still enumerate gateway model metadata through HTTP compatibility routes.\n- Breaks scope model consistency between WS RPC and HTTP surfaces.\n- Weakens least-privilege expectations for operators granted non-read scopes.\n\n## Patch Suggestion\n\n### 1) Enforce read scope on `/v1/models` routes\n\nApply a scope gate equivalent to `models.list` before serving `/v1/models` or `/v1/models/:id`.\n\n### 2) Reuse centralized scope-authorization helper for HTTP compatibility endpoints\n\nUse the same operator scope logic used by WS dispatch (`authorizeOperatorScopesForMethod(...)`) to prevent policy drift.\n\n### 3) Add regression tests\n\nKeep this PoC and add explicit negative/positive controls:\n\n- `operator.approvals` without read is rejected on HTTP `/v1/models`.\n- `operator.read` is accepted on both WS `models.list` and HTTP `/v1/models`.\n\n## Credit\n\nReported by @zpbrent.",
9+
"severity": [],
10+
"affected": [
11+
{
12+
"package": {
13+
"ecosystem": "npm",
14+
"name": "openclaw"
15+
},
16+
"ranges": [
17+
{
18+
"type": "ECOSYSTEM",
19+
"events": [
20+
{
21+
"introduced": "0"
22+
},
23+
{
24+
"fixed": "2026.3.24"
25+
}
26+
]
27+
}
28+
],
29+
"database_specific": {
30+
"last_known_affected_version_range": "<= 2026.3.23"
31+
}
32+
}
33+
],
34+
"references": [
35+
{
36+
"type": "WEB",
37+
"url": "https://github.com/openclaw/openclaw/security/advisories/GHSA-68f8-9mhj-h2mp"
38+
},
39+
{
40+
"type": "PACKAGE",
41+
"url": "https://github.com/openclaw/openclaw"
42+
}
43+
],
44+
"database_specific": {
45+
"cwe_ids": [
46+
"CWE-284",
47+
"CWE-863"
48+
],
49+
"severity": "MODERATE",
50+
"github_reviewed": true,
51+
"github_reviewed_at": "2026-03-30T18:41:15Z",
52+
"nvd_published_at": null
53+
}
54+
}

0 commit comments

Comments
 (0)