CVE-2026-66064 Overview
CVE-2026-66064 affects goshs, a single-binary file server used by red teamers and developers. Versions prior to 2.1.5 contain an authorization bypass in the httpserver/handler.gosendFile handler. The handler opens files using a cleaned path but derives the authorization filename from the raw req.URL.Path. A trailing slash in the request URL causes the ACL filename check to see an empty final segment while filepath.Clean still resolves and serves the real file. This bypasses .goshs ACL-file protection and block-list checks, allowing unauthenticated attackers to retrieve files that should be restricted. The issue is fixed in version 2.1.5.
Critical Impact
Remote unauthenticated attackers can bypass .goshs ACL enforcement by appending a trailing slash to file requests, exposing protected files served by goshs.
Affected Products
- goshs versions prior to 2.1.5
- goshs file server component httpserver/handler.go (sendFile handler)
- goshs upload handler httpserver/updown.go (related path traversal in the same fix)
Discovery Timeline
- 2026-07-28 - CVE-2026-66064 published to NVD
- 2026-07-29 - Last updated in NVD database
Technical Details for CVE-2026-66064
Vulnerability Analysis
The flaw is an inconsistency between the path used to open a file and the path used to enforce access control. In vulnerable versions, sendFile calls sanitizePath, which applies filepath.Clean and successfully opens the target file even when the request URL ends in /. However, the code that enforces the .goshs ACL check splits req.URL.Path on / and takes the final segment as the filename. A trailing slash makes that final segment empty, so the string comparison against .goshs fails and the block-list check is skipped, while the underlying file is still returned to the client.
This maps to [CWE-41] (Improper Resolution of Path Equivalence). The upload handler updown.go had a related weakness where filenames of "", ".", or ".." slipped past filepath.Base and could be joined with the target directory to write outside the served tree.
Root Cause
Authorization decisions were derived from unnormalized request input (req.URL.Path) while file I/O used a normalized path. The two representations disagreed for URLs containing trailing slashes, producing a classic path-equivalence bypass.
Attack Vector
An unauthenticated remote attacker sends an HTTP GET request to the goshs server targeting a protected file with a trailing slash, for example GET /path/.goshs/. The ACL check parses the URL, finds an empty final segment, and does not match .goshs. The sendFile routine then opens the cleaned path and returns the file contents.
// Patch: httpserver/handler.go
stat, err := file.Stat()
if err != nil {
fs.handleError(w, req, err, http.StatusInternalServerError)
return
}
// Derive the served filename from the actually opened file, not from the raw
// request path. A trailing slash (e.g. /dir/.goshs/) leaves req.URL.Path with
// an empty final segment, while sanitizePath's filepath.Clean strips it and
// opens the real file — so basing the checks below on req.URL.Path defeats
// both guards. stat.Name() cannot disagree with the file that gets served.
filename := stat.Name()
// Never serve .goshs file and return same error message if it was not there
if filename == ".goshs" {
fs.handleError(w, req, fmt.Errorf("open %s: no such file or directory", file.Name()), 404)
return
}
Source: GitHub Commit f3ef599
The fix derives the enforcement filename from stat.Name() on the opened file handle, guaranteeing the ACL check operates on the same file that will be served.
Detection Methods for CVE-2026-66064
Indicators of Compromise
- HTTP requests to goshs endpoints containing .goshs in the path with a trailing slash, for example /.goshs/ or /subdir/.goshs/.
- Successful 200 responses from goshs for URLs whose final path segment is empty when it should be filtered.
- Access logs showing retrieval of ACL files or block-listed filenames without prior authorization events.
Detection Strategies
- Inspect goshs access logs for URLs ending in / that resolve to sensitive files, correlating with response codes other than 404.
- Deploy a web application firewall or reverse proxy rule that normalizes trailing slashes before requests reach goshs.
- Compare the running goshs binary version against 2.1.5 across hosts to identify unpatched instances.
Monitoring Recommendations
- Alert on any HTTP request containing the literal string .goshs in the URL path targeting a goshs server.
- Track goshs process launches and network exposure on unexpected hosts, since goshs is commonly used ad-hoc by operators.
- Monitor for outbound file transfers from red-team or developer workstations that host goshs on non-standard ports.
How to Mitigate CVE-2026-66064
Immediate Actions Required
- Upgrade goshs to version 2.1.5 or later on all systems where the binary is deployed.
- Audit hosts for stale or forgotten goshs instances left running after engagements or transfers.
- Restrict network exposure of goshs listeners to trusted management networks only.
Patch Information
The fix is committed in GitHub Commit f3ef599 and merged via GitHub Pull Request #222. Vendor guidance is published in GitHub Security Advisory GHSA-964w-f6gj-5236. The patch derives the ACL filename from stat.Name() on the opened file and rejects uploaded filenames that are empty, ., or .. after cleaning.
Workarounds
- Place goshs behind a reverse proxy configured to strip or reject trailing slashes on file paths.
- Avoid serving directories that contain a .goshs ACL file until the upgrade is applied.
- Terminate goshs instances immediately after their intended use to reduce exposure window.
# Verify installed goshs version and upgrade
goshs -v
go install github.com/goshs-labs/goshs@v2.1.5
# Example nginx reverse proxy rule to normalize trailing slashes
# location ~ ^(.*)/$ {
# return 301 $1;
# }
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

