github jhaals/yopass 16.0.0

2 hours ago

Yopass 16.0.0

This release addresses 27 security findings: 15 medium and 12 low severity thanks to Claude Mythos OSS Security Reviews. Upgrade both the server and clients to receive all fixes.

Breaking changes — why 16.0.0?

Version 16.0.0 follows 15.1.0 because its fixes change existing API behavior and accepted inputs:

  • Secret request API clients: fulfilling a request after key replacement now requires the key_version returned by its lookup. Missing or stale versions return 412 instead of accepting an answer the requester cannot decrypt.
  • Receipt API clients: missing or invalid receipt tokens now return 404 instead of the documented 401. Update clients that distinguish these responses. Receipt-storage failures now return 503 before consuming a secret.
  • Browser integrations: directly navigating to a protected API URL no longer authenticates with a session cookie and returns 401 when authentication is required. Use frontend share links or supported API requests instead; foreign-origin requests also lose cookie authority.
  • Accepted inputs: oversized HTTP headers and OpenPGP messages exceeding the new Argon2, decompression, or CLI packet-prefix limits are rejected. Integrations that previously relied on these inputs must adapt.

Review the configuration migrations below before upgrading. Existing webhook sha256= signature verification remains compatible; this release does not require v2 signatures.

Upgrade notes

  • Secret request API: after a key replacement, clients must echo key_version from the request lookup when submitting an answer. Missing or stale versions return 412; the web UI asks the responder to use the new verified link. Requests whose keys have never been replaced retain compatibility with older clients.
  • Receipt API: missing or invalid receipt tokens now return 404 instead of 401, matching absent receipts. Receipt-write failures return 503 before consuming the secret, allowing retrieval to be retried after recovery.
  • Cookie-authenticated API calls: foreign-origin requests and browser GET navigations no longer receive cookie authority. Open protected secrets through frontend share links. Non-browser clients without Origin/Fetch Metadata remain supported. Keep --prefetch-secret=true for reveal confirmation; disabling it intentionally auto-retrieves frontend links.
  • OIDC configuration: replace the obsolete OIDC_ALLOWED_DOMAIN setting with OIDC_ALLOWED_DOMAINS. The server now refuses to start when the old setting is present rather than silently ignoring it.
  • Decryption limits: the browser and CLI reject Argon2 memory requirements above 128 MiB and compressed OpenPGP packets that expand beyond 1 MiB. The CLI also limits session-key packet prefixes to 64 KiB. Yopass-generated messages remain compatible; the decompression limit does not cap ordinary uncompressed file sizes.
  • HTTP headers: application and metrics listeners now configure a 16 KiB header limit. Check deployments with large authentication cookies; protocol-specific allowances apply.
  • Webhooks: signatures retain the existing sha256= HMAC over the raw JSON body. The payload adds delivery_id, so strict JSON schemas must allow this field. Receivers must use the verified body's event and delivery_id, enforce timestamp freshness, and deduplicate IDs to gain replay protection. Do not fall back to unsigned headers for older payloads without delivery_id.
  • File storage: configured disk/S3 stores must remain valid even with --disable-upload, so expiry cleanup can continue. Keep the disk store directory present and private to the server account; operations that escape it through symlinks are rejected.
  • After upgrading: review retained logs and rotate Redis or webhook credentials if they were exposed there. Unsampled audit logging can increase log volume.

Bug fixes

  • Retain downloaded file ciphertext across incorrect decryption keys, so retrying with the correct key or correcting the URL key works for one-time files without a second fetch. The browser buffers the encrypted file until decryption succeeds or the page closes.

  • Return 503 for secret-request and read-receipt lookup failures caused by a database outage. Reserve 404 for missing, malformed or expired records so revocation/purge keeps retryable requests and their keys, and receipt polling can recover.

  • Honor the stored response kind when revealing secret-request answers. Text answers remain text even with an embedded filename, and file answers retain binary presentation even without a filename.

  • Reject secret-request responses prepared before a key replacement with 412, leaving the request pending instead of accepting an answer encrypted to a discarded key.

  • Limit each S3 cleanup request, including retries and response-body reads, to 30 seconds so a silent storage endpoint cannot permanently stall expiry cleanup.

  • Return 204 once a file link has been revoked, even if blob deletion fails. Log and audit the cleanup failure separately; leftover ciphertext is removed by the expiry sweeper or bucket lifecycle policy. Download metadata is never restored.

  • Keep issued secret requests usable after restarting with a verified expired license, including their response links and request list. Existing requests can drain within their TTLs while new request creation stays disabled.

  • Close stalled HTTP/2 connections after 30 seconds without write progress, so a peer that stops reading cannot keep handlers blocked past their stream deadlines. This limit remains active when configurable request timeouts are disabled.

  • Queue collected request answers instead of overwriting an open answer. Keep pending results and reveal dialogs across in-app navigation, and track each busy request independently. Collected content remains in memory until explicitly closed; reloading or closing the tab still discards it.

  • Reset the response draft, selected file, and verified public key when opening a different request link in the same tab. The form remains unavailable until the new request is loaded and verified.

  • Prevent client disconnects from abandoning committed file-store uploads or cancelling cleanup. Failed uploads also attempt bounded cleanup when the store may have committed despite a lost response.

  • Preserve one-time file links when opening the file store fails transiently: return 503 without consuming metadata or deleting the blob, allowing a successful retry after storage recovers. Access is checked before opening and again when claiming the file.

  • Recover Memcached and Redis one-time claims when the backend applied a write but its reply was lost, including collected request answers. Claims retain small, secret-free ownership markers for 60 seconds and still fail closed when ownership cannot be established.

  • Return 404 for static assets and the built-in logo when no asset directory is configured, rather than serving files from the process working directory in embedded/Lambda deployments.

  • Bound DynamoDB calls, including SDK retry backoff, and raise the CDK Lambda timeout to 29 seconds so stalled post-download cleanup does not outlast the default three-second invocation limit.

  • Recover DynamoDB one-time claims and conditional updates when the SDK retries a write whose response was lost. Claims use a short-lived marker containing no ciphertext; a competing caller cannot retrieve the secret.

  • Sweep expired disk files when the configured storage directory is a symlink, while preserving live files and confinement to the storage root.

  • Keep Argon2 browser decryption working when --argon2 is disabled or differs between instances. The CSP now always permits WebAssembly compilation without enabling JavaScript eval. Reload older cached pages and check custom proxy CSP headers.

  • Reject malformed boolean settings instead of silently treating values such as READ_ONLY=yes or YOPASS_ONE_TIME=yes as false. Use true or false in environment variables and CLI configuration.

  • Record rejected authentication on secret/file/request creation and OIDC callbacks in the audit log, including failures before the userinfo callback.

  • Fix audit-log secret fingerprints so they match webhook and access-log identifiers, and encode timestamps in the documented RFC 3339 format.

Security fixes

Authentication and sessions

  • Ignore session cookies on foreign-origin API requests and browser GET navigations, preventing forged requests from consuming protected one-time secrets/files or creating secrets under a signed-in user. Trusted split-origin frontends and API-token identities remain supported.

  • Reject logout requests carrying foreign-origin browser Fetch Metadata, retaining configured split-origin frontend validation.

  • Preserve the authorized user's identity throughout a request, including when logout occurs concurrently, so audit records retain attribution.

  • Ignore request bodies on the OIDC GET callback to prevent multipart temporary-file accumulation.

  • Correct the allowed-domain setting in read-only deployment documentation and reject the obsolete setting at startup.

Secret and file storage

  • Record file access in audit logs, read receipts, and webhook notifications before streaming, including when the recipient disconnects. These records indicate access, not completed delivery or decryption.
  • Confine disk file operations and cleanup to the configured storage root.
  • Share decoded database-backed file buffers across active downloads of the same content, reducing memory retained by stalled downloads.
  • Prevent Redis creation-write retries from recreating a consumed one-time secret after an ambiguous response. Ambiguous creation failures now surface as errors.
  • Keep disk and S3 expiry cleanup active when uploads are disabled, unless cleanup is explicitly disabled.
  • Remove expired temporary disk-upload files left by interrupted uploads and prevent swept uploads from publishing untracked blobs.

Audit logs and credentials

  • Redact raw file IDs from disk/S3 error messages and cleanup logs, extending existing HTTP access-log redaction while retaining diagnostic causes and fingerprints.

  • Disable sampling for the dedicated audit logger so bursts of activity cannot suppress audit events.

  • Remove Redis connection URLs from debug logs and credentials from URL-validation errors.

  • Remove webhook URL credentials from startup and failed-delivery logs while retaining receiver-host and transport diagnostics.

Browser and resource protections

  • Bound decoded request headers on application and metrics listeners, including HTTP/2 compressed headers.
  • Reject URL syntax in client-side secret identifiers before issuing API or file-download requests.
  • Use bounded structural validation for submitted OpenPGP public keys, avoiding expensive signature verification on the server. Encryption clients validate keys before use.
  • Send Cache-Control: no-store for secret and file retrieval, status, receipt, request, and current-user responses.
  • Give decrypted file blobs an explicit binary MIME type to prevent browser HTML sniffing when re-download links open in a tab.
  • Bound sender-selected Argon2 memory costs in both clients before key derivation.
  • Bound OpenPGP decompression during browser parsing and decryption and in the CLI.

Read receipts

  • Return indistinguishable responses for missing receipts and invalid receipt tokens, preventing disclosure of whether tracking was enabled.
  • Replace claims that expired receipts prove a secret was never opened with neutral wording in both receipt views and all translations.
  • Start receipt expiry after secret/file storage and round deadlines to cover retrievals near expiration. Roll back new payloads if their requested receipt cannot be stored.
  • Refuse retrieval when recording the receipt fails, keeping one-time secrets intact for retry. A receipt can record an authorized retrieval even if the subsequent claim or transfer fails.

Webhooks

  • Add a unique delivery ID to the signed JSON body and reuse it across retries. Existing body-only signature verifiers remain compatible. Updated receiver guidance covers authenticated routing, deduplication, and replay windows; receivers that continue trusting unsigned headers remain vulnerable.

Security advisories and CVEs

Yopass 16.0.0 fixes the 27 security issues listed below. Each finding links to its GitHub security advisory. CVE assignment has been requested for all 27; see the linked advisories for CVE IDs as GitHub assigns them.

Finding GitHub advisory
Public-key validation permits attacker-controlled expensive OpenPGP arithmetic (medium) GHSA-xgh2-mqxc-gr72
Disk file store symlinks can expose files outside the store to link holders (medium) GHSA-243g-72v2-g9cq
Webhook receiver credentials exposed through application logs (low) GHSA-4fgj-gp6x-j658
HTTP/2 compressed headers can amplify server memory usage with built-in TLS (medium) GHSA-8xxw-g2p6-x5h6
Expired read receipts falsely indicate secrets were never opened (low) GHSA-65wg-22g4-gw53
Browser cache can expose consumed or authentication-protected secrets to sibling origins (medium) GHSA-4x6j-r8q8-6mpc
Untyped decrypted file blobs can render sender HTML under the Yopass origin (low) GHSA-hgfr-gcvc-5p7v
Concurrent logout can remove user attribution from authorized creation audit events (medium) GHSA-rp5f-p3w5-8g76
Sender-selected Argon2 costs can exhaust decryption client memory (low) GHSA-9jg6-967j-2f79
Compressed OpenPGP messages can exhaust recipient browser or CLI memory (low) GHSA-ffww-82j2-gm4g
Failed receipt writes allow successful retrievals to remain unrecorded (low) GHSA-h525-pfjg-6wxr
Redis connection credentials exposed in startup logs and parse errors (low) GHSA-724h-m642-8g9m
Read receipts expire before their secrets or slow file uploads (low) GHSA-wfwp-rv9h-wrf5
Read-only OIDC example silently omits intended email-domain restrictions (medium) GHSA-6qx2-rj54-97gv
Interrupted disk uploads leave expired temporary ciphertext indefinitely (low) GHSA-q8j3-39w4-v9jj
Disabling uploads silently disables expired file cleanup (low) GHSA-c4rw-cr8m-fpmm
Retried Redis creation writes can restore consumed one-time records (medium) GHSA-p283-rmr6-72qp
Audit log sampling allows suppression of security events (medium) GHSA-wwgv-c8hw-fxwx
Repeated stalled database-backed file downloads retain duplicate payload buffers (medium) GHSA-4p9m-w8m2-r497
Interrupted file downloads bypass audit events, read receipts, and viewed webhooks (medium) GHSA-q743-qjq4-mvgj
Webhook signatures do not authenticate routing and deduplication headers (low) GHSA-2mg3-54g4-g87p
OIDC callback can parse unbounded multipart bodies and leave temporary files (medium) GHSA-gcgc-828x-8gpx
Crafted client identifiers redirect status prefetch into consuming API requests (medium) GHSA-j7q8-7xqh-jw4m
Disk and S3 storage failures expose raw file retrieval IDs in application logs (medium) GHSA-xmqv-88g6-r8w5
Foreign browser requests can consume authentication-protected one-time secrets using a victim session (medium) GHSA-gp6q-chjf-5g3v
OIDC logout accepts cross-origin requests and can sign users out without consent (medium) GHSA-prmp-p6hv-m586
Receipt responses reveal whether a sender enabled read tracking (low) GHSA-hmgj-m9jv-pxwx

Acknowledgements

These vulnerabilities were discovered by Anthropic's OSS Scanner.

Don't miss a new yopass release

NewReleases is sending notifications on new releases.