{ "schema_version": "1.4.0", "id": "GHSA-rmxw-pq4x-3fvh", "modified": "2026-07-28T21:59:48Z", "published": "2026-07-28T21:59:48Z", "aliases": [ "CVE-2026-54719" ], "summary": "goshs: File-based .goshs ACL authorization bypass via the ?bulk zip-download route (unauthenticated read; residual of GHSA-wvhv-qcqf-f3cx)", "details": "GHSA-wvhv-qcqf-f3cx fixed the per-folder .goshs ACL bypass on the state-changing routes (PUT/POST upload/?mkdir/?delete) and added recursive ACL resolution, and its description states the read/list path correctly enforces .goshs. That premise does not hold for the ?bulk zip-download route. bulkDownload (httpserver/updown.go) takes one or more ?file= parameters, runs each through sanitizePath(fs.Webroot, file), and streams the contents back as a ZIP without ever calling findEffectiveACL/applyCustomAuth. It is dispatched from earlyBreakParameters (?bulk) before the normal doDir/doFile/sendFile flow that performs the ACL check. An unauthenticated attacker can therefore read any file under the webroot protected solely by a .goshs ACL, bypassing both the folder auth (401 on the normal path) and the per-file block list (404 on the normal path). Same authorization-inconsistency root cause as the original advisory, surviving on a read route the fix did not cover.\n\nProof of concept (live, against the fixed v2.1.0 build which includes fix commit f212c4f4, served with no global -b auth, only a per-folder .goshs):\n GET /protected/secret.txt -> 401 (ACL enforced on normal path)\n GET /protected/secret.txt -u admin:admin -> 200\n GET /?bulk&file=/protected/secret.txt -> 200, zip contains the protected file contents (BYPASS)\n GET /?bulk&file=/protected/blocked.txt -> 200, zip contains the block-listed file (block bypass)\n GET /protected/secret.txt?share -> 403 'Sharing disabled when auth is disabled' (correctly gated, NOT a bypass)\n\nImpact: any unauthenticated network attacker can read files an operator protected with the documented per-folder .goshs ACL/basic-auth feature, by requesting them through ?bulk. Confidentiality only (the write/delete equivalents were closed by GHSA-wvhv-qcqf-f3cx). Applies to deployments relying on .goshs as the access boundary (a server-wide -b basic auth, if configured, also gates ?bulk via its middleware).\n\nRemediation: enforce the effective .goshs ACL inside bulkDownload for every requested file exactly as sendFile/processDir do (resolve findEffectiveACL(filepath.Dir(absPath)) + applyCustomAuth + honor acl.Block), or route ?bulk through the same authorization gate as the normal read path. Audit ?cbDown and other alternate read routes for the same gap.\n\nCredit: anir0y (independent security research).", "severity": [ { "type": "CVSS_V3", "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N" } ], "affected": [ { "package": { "ecosystem": "Go", "name": "github.com/patrickhener/goshs" }, "ranges": [ { "type": "ECOSYSTEM", "events": [ { "introduced": "0" }, { "last_affected": "1.1.4" } ] } ] }, { "package": { "ecosystem": "Go", "name": "github.com/patrickhener/goshs/v2" }, "ranges": [ { "type": "ECOSYSTEM", "events": [ { "introduced": "0" }, { "fixed": "2.1.1" } ] } ], "database_specific": { "last_known_affected_version_range": "<= 2.1.0" } }, { "package": { "ecosystem": "Go", "name": "goshs.de/goshs" }, "ranges": [ { "type": "ECOSYSTEM", "events": [ { "introduced": "0" }, { "last_affected": "1.1.4" } ] } ] }, { "package": { "ecosystem": "Go", "name": "goshs.de/goshs/v2" }, "ranges": [ { "type": "ECOSYSTEM", "events": [ { "introduced": "0" }, { "fixed": "2.1.1" } ] } ], "database_specific": { "last_known_affected_version_range": "<= 2.1.0" } } ], "references": [ { "type": "WEB", "url": "https://github.com/goshs-labs/goshs/security/advisories/GHSA-rmxw-pq4x-3fvh" }, { "type": "WEB", "url": "https://github.com/goshs-labs/goshs/commit/7cf911a26ace737e1a55b7dc073e307a25f7fd1d" }, { "type": "PACKAGE", "url": "https://github.com/goshs-labs/goshs" }, { "type": "WEB", "url": "https://github.com/goshs-labs/goshs/releases/tag/v2.1.1" } ], "database_specific": { "cwe_ids": [ "CWE-862", "CWE-863" ], "severity": "HIGH", "github_reviewed": true, "github_reviewed_at": "2026-07-28T21:59:48Z", "nvd_published_at": null } }