Public share-password verification has no rate limiting and no minimum password length, enabling online brute force
low Fully Valid medium confidence
Status
Fully Valid
Absence of rate limiting is confirmed, and the missing minimum-length on share passwords (verified at share.go:177) makes weak passwords genuinely brute-forceable — stronger than the login case. Fully_valid, low.
Repository / Component
Plain-English Description
Password-protected share links can be guessed at without limit: the server never throttles or locks out repeated wrong guesses, and it never enforces a minimum length for share passwords. A weak share password can be brute-forced online by anyone holding the share link.
Description of the Underlying Issue
authenticateShareRequest (http/public.go:129-154) verifies the attacker-supplied X-SHARE-PASSWORD header with bcrypt.CompareHashAndPassword (http/public.go:138-146) with no attempt counter, lockout, or delay. getSharePasswordHash (http/share.go:172-183) bcrypt-hashes the chosen password but enforces no minimum length (http/share.go:177). The only router middleware is the CSP header setter, and handle() injects no limiter (http/http.go:30-40). Together, unauthenticated share-password verification is both unthrottled and permitted to protect a share with an arbitrarily short/weak password.
Potential Attack
An attacker who possesses a share hash/URL repeatedly sends requests to /api/public/... with guessed X-SHARE-PASSWORD header values. No counter or lockout intervenes, so guessing continues at a rate bounded only by bcrypt's per-attempt CPU cost. Because share passwords have no minimum length, many real shares are protected by short/weak passwords that fall to online guessing.
Outcomes of Potential Attack
The attacker can recover a weak share password and gain the access the share grants (viewing/downloading the shared file or directory), plus impose auth-path CPU load through repeated bcrypt verifications.
Affected Scope
authenticateShareRequest (http/public.go:129-154), X-SHARE-PASSWORD verification on public share access
Suggested Fix (plain english)
Enforce a minimum length for share passwords and add rate limiting or lockout to the public share-password check.
Suggested Fix (detailed)
Enforce a minimum share-password length in getSharePasswordHash (http/share.go:172-183) and add rate limiting / lockout keyed on share hash plus client IP in front of authenticateShareRequest (http/public.go:129-154). Verify by attempting rapid repeated X-SHARE-PASSWORD guesses against a known share hash and confirming throttling/lockout, and by attempting to set a too-short share password and confirming rejection. Related: DOK-100042 (same missing rate-limiting control on /api/login). Enforce a minimum share-password length and add rate limiting/lockout keyed on share hash + client IP.
Validation
Absence of rate limiting is confirmed, and the missing minimum-length on share passwords (verified at share.go:177) makes weak passwords genuinely brute-forceable — stronger than the login case. Fully_valid, low.
Full Evidence
http/public.go:138-146 bcrypt.CompareHashAndPassword on attacker-supplied X-SHARE-PASSWORD with no attempt counter/lockout/delay
http/share.go:172-183 getSharePasswordHash hashes body.Password with bcrypt but enforces NO minimum length
http/http.go:30-40 only middleware is the CSP header; handle() injects no limiter
Proven fact: Unauthenticated share-password verification has no rate limiting AND share passwords have no minimum-length requirement, so weak share passwords are online-brute-forceable (bcrypt only CPU-throttles each attempt)
Unvalidated fact: The attacker must already possess the share hash (distributed in the share URL); actual password strength is user-chosen and deployment-dependent
http/public.go:138-146 — bcrypt.CompareHashAndPassword on the attacker-supplied X-SHARE-PASSWORD with no attempt counter/lockout/delay
http/share.go:172-183 — getSharePasswordHash hashes body.Password with bcrypt but enforces NO minimum length (share.go:177)
http/http.go:30-40 — the only middleware is the CSP header; handle() injects no limiter
Proven fact: Unauthenticated share-password verification has no rate limiting, and share passwords have no minimum-length requirement, so weak share passwords are online-brute-forceable (bcrypt only CPU-throttles each attempt).
Unvalidated fact: The attacker must already possess the share hash (distributed in the share URL); actual share-password strength is user-chosen and deployment-dependent.
http/public.go:138-151 — bcrypt.CompareHashAndPassword on attacker-supplied X-SHARE-PASSWORD with no attempt counter or delay
http/http.go:30-40 and http/data.go:50-85 — the only middleware is a CSP header; handle() injects no rate limiter or lockout
repo-wide search for ratelimit|throttl|limiter|lockout|backoff|failed_attempt yields no security control (only an unrelated comment in runner/commands.go)
Distinct from prior dismissal 'Non-constant-time token comparison and 48-bit share-hash entropy' (SP-A4/SP-A6), which reasoned from HIGH entropy of the 768-bit token and 48-bit hash; that infeasibility argument does not apply to a low-entropy user-chosen password