GHSA-RMXW-PQ4X-3FVH
Vulnerability from github – Published: 2026-07-28 21:59 – Updated: 2026-07-28 21:59GHSA-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.
Proof 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): GET /protected/secret.txt -> 401 (ACL enforced on normal path) GET /protected/secret.txt -u admin:admin -> 200 GET /?bulk&file=/protected/secret.txt -> 200, zip contains the protected file contents (BYPASS) GET /?bulk&file=/protected/blocked.txt -> 200, zip contains the block-listed file (block bypass) GET /protected/secret.txt?share -> 403 'Sharing disabled when auth is disabled' (correctly gated, NOT a bypass)
Impact: 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).
Remediation: 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.
Credit: anir0y (independent security research).
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/patrickhener/goshs"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "1.1.4"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 2.1.0"
},
"package": {
"ecosystem": "Go",
"name": "github.com/patrickhener/goshs/v2"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.1.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "goshs.de/goshs"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "1.1.4"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 2.1.0"
},
"package": {
"ecosystem": "Go",
"name": "goshs.de/goshs/v2"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.1.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-54719"
],
"database_specific": {
"cwe_ids": [
"CWE-862",
"CWE-863"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-28T21:59:48Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"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 -\u003e 401 (ACL enforced on normal path)\n GET /protected/secret.txt -u admin:admin -\u003e 200\n GET /?bulk\u0026file=/protected/secret.txt -\u003e 200, zip contains the protected file contents (BYPASS)\n GET /?bulk\u0026file=/protected/blocked.txt -\u003e 200, zip contains the block-listed file (block bypass)\n GET /protected/secret.txt?share -\u003e 403 \u0027Sharing disabled when auth is disabled\u0027 (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).",
"id": "GHSA-rmxw-pq4x-3fvh",
"modified": "2026-07-28T21:59:48Z",
"published": "2026-07-28T21:59:48Z",
"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"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "goshs: File-based .goshs ACL authorization bypass via the ?bulk zip-download route (unauthenticated read; residual of GHSA-wvhv-qcqf-f3cx)"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.