CVE-2026-50138 — goshs
HIGHCVE-2026-50138 is a high-severity (CVSS 8.1) CWE-284 vulnerability in goshs.de/goshs/v2. A fix is available for goshs.de/goshs/v2 — see the affected versions and patch details below.
goshs: WebDAV listener ignores --read-only, --upload-only, and --no-delete mode flags
Exploitation Status
Proof-of-concept exploit code exists
- CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
- A successful exploit gives an attacker total control of the affected component, not partial access.
Exploitation and automatability from CISA’s SSVC triage for CVE-2026-50138.
EPSS Exploitation Probability
Probability of exploitation in the next 30 days, from FIRST.org EPSS.
How urgent is this, really
CVE-2026-50138 by exploitation likelihood (EPSS) against impact (CVSS). Outside the shaded patch-first corner.
Where this sits among everything scored
Of 396,966 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Counts from FIRST.org, log-scaled.
Real-World Exposure
goshs.de/goshs/v2Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Go packages — download data is not available via public APIs for these ecosystems.
Description
WebDAV listener ignores --read-only, --upload-only, and --no-delete mode flags
Ecosystem: Go
Package: goshs.de/goshs/v2 (github.com/patrickhener/goshs)
Affected: <= v2.0.9 (every release that ships the WebDAV handler)
Summary
When goshs is launched with WebDAV enabled (-w), the mode-restriction flags --read-only, --upload-only, and --no-delete are enforced only on the primary HTTP port. The WebDAV port is wired straight to golang.org/x/net/webdav.Handler with no equivalent guard, so an authenticated WebDAV client can PUT, DELETE, MKCOL, MOVE, and COPY despite the operator's stated intent.
Details
httpserver/server.go:207-238 — the WebDAV mux registers only IPWhitelistMiddleware, ServerHeaderMiddleware, and optionally BasicAuthMiddleware. There is no fs.ReadOnly || fs.UploadOnly || fs.NoDelete check on the WebDAV path. The HTTP mux in the same file (lines 134-204) does check these flags on every state-changing route.
Proof of concept
mkdir -p /tmp/r && echo secret > /tmp/r/x.txt
goshs -p 18000 -wp 18001 -w -ro -d /tmp/r -b admin:pw &
curl -u admin:pw -X PUT http://localhost:18000/y.txt --data x # 403 (HTTP enforces -ro)
curl -u admin:pw -X PUT http://localhost:18001/y.txt --data x # 201 (WebDAV writes anyway)
curl -u admin:pw -X DELETE http://localhost:18001/x.txt # 204 (WebDAV deletes anyway)
curl -u admin:pw -X MKCOL http://localhost:18001/pwned/ # 201 (WebDAV creates dir)
Impact
- Integrity —
--read-onlyand--no-deleteare silently downgraded to "no protection" on the WebDAV port. Any WebDAV client (curl, cadaver, Windows Explorer, Finder) can overwrite/delete files. - Confidentiality —
--upload-onlyis also bypassed: WebDAV GET/PROPFIND still return file contents. - Trust — operators using
goshs -w -ro -d /srv/case-files -b reviewer:pwto deliver engagement artifacts believe the directory is immutable. It isn't.
Suggested fix
Add a small http.HandlerFunc in front of wdHandler that maps WebDAV verbs to the existing mode flags:
wdGuard := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodPut, "MKCOL", "MOVE", "COPY":
if fs.ReadOnly || fs.UploadOnly { http.Error(w, "read-only", 403); return }
case http.MethodDelete:
if fs.ReadOnly || fs.UploadOnly || fs.NoDelete { http.Error(w, "delete disabled", 403); return }
case http.MethodGet, "PROPFIND", "HEAD":
if fs.UploadOnly { http.Error(w, "upload-only", 403); return }
}
wdHandler.ServeHTTP(w, r)
})
Add regression tests in integration/functions.go covering each mode flag × each WebDAV verb.
Reporter: Nishant Verma. Reproduced live against goshs v2.0.9 (commit 8fc1e91) on 2026-05-27.
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐹Go | goshs.de/goshs/v2 | all versions | 2.1.0go get goshs.de/goshs/v2@v2.1.0 |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for goshs.de/goshs/v2, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update goshs.de/goshs/v2 to 2.1.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-50138 is resolved across your whole dependency graph.
Workarounds
Put an independent control in front of the weakness: restrict the affected endpoint or interface to trusted networks, require an additional authentication factor or proxy-level check, and invalidate existing sessions and credentials in case the flaw has already been used.
Frequently Asked Questions
Is CVE-2026-50138 in your dependencies?
Find it across Go, including transitive dependencies.