Yopass

jhaals/yopass last check 69 releases today
Notes
Release notes
v14.7.0 · today
view on github

Security

  • [GHSA-rpg6-935f-pp7v] Remote memory exhaustion via unbounded JSON body on POST /create/secret (High, CVSS 7.5) The handler decoded the request body without a size cap, so an unauthenticated client could force the server to allocate an arbitrarily large payload in memory before the --max-length check ran. A single large request could OOM-kill the process. The body is now bounded with http.MaxBytesReader and oversized requests get a 413 without being buffered. (#3772) Reported by @EQSTLab.

  • Session cookies stayed valid after logout, and for far longer than intended. (#3775) securecookie.New defaults to a 30-day maxAge, so the 24h MaxAge on the cookie was a client-side hint only — a captured cookie authenticated for 30 days. The codec maxAge now matches. Sessions also carry a random ID; logout records it as revoked with a 24h TTL and getSession rejects any cookie whose ID is listed, so a replayed cookie no longer authenticates. Revocation lookups fail open, so a storage outage does not sign everyone out. Affects deployments running OIDC with --require-auth.

  • Unbounded Prometheus label cardinality from client-supplied HTTP methods. (#3773) Arbitrary methods reaching the file-server catch-all route each created a new metric label, letting an unauthenticated client grow server memory indefinitely. Unknown methods now collapse to the existing <other> sentinel.

  • HTTP servers had no connection timeouts. (#3776) A client could open a connection and hold it open indefinitely without completing a request. ReadHeaderTimeout and IdleTimeout are now set on the yopass server, and the full set including ReadTimeout/WriteTimeout on the metrics server. Whole-request deadlines are intentionally left off the yopass server because file upload and download stream bodies of arbitrary size.

Bug fixes

  • A transient storage error no longer destroys a multi-view file secret. (#3774) FileStore.Load returned an undifferentiated error for both "object is gone" and "store is unreachable", and the download handler deleted the database metadata in either case — so a single S3 network blip or disk hiccup permanently destroyed the secret. Load now wraps the ErrKeyNotFound sentinel on definite not-found only (os.IsNotExist, S3 NoSuchKey/NotFound, database cache miss). The handler cleans up stale metadata for that case alone; anything else returns 503 and keeps the record so the secret survives the outage.

Hardening

  • Stricter PGP armor validation on submission. (#3772) isPGPEncrypted only parsed the armor BEGIN line, so any string shaped like an armor header was accepted — wrong block types, truncated messages, plaintext wrapped in headers. The block type, body, and END marker are now all verified. Thanks to @xhydraxOffSec for reporting this.

    This is input hygiene, not a security boundary: a client can always encrypt with a key it controls, so the server can never prove a payload is encrypted. The value is rejecting malformed ciphertext before a sender shares a link to a secret nobody can decrypt. SECURITY.md is reworded accordingly — "No Plain Text Storage" is guaranteed by the client, not enforced by the server.

Behavior changes

  • Malformed or truncated armored payloads that earlier versions accepted are now rejected with 400. Requests exceeding the body cap return 413 instead of 400. Clients producing well-formed OpenPGP messages are unaffected.
  • Logging out now invalidates the session server-side. Existing sessions are unaffected by the upgrade, but cookies issued before it are subject to the corrected 24h codec lifetime.