github Skyfay/SkySend v2.5.0

latest releases: v2.11.2, v2.11.1, v2.11.0...
one month ago

Security Audit Fixes, Test Coverage Improvements, and Docker Metadata Labels

✨ Features

  • server: Added per-IP per-resource password attempt lockout - after 10 failed attempts the IP is locked out for 15 minutes with a Retry-After header; IPs stored as ephemeral HMAC-SHA256 hashes; configurable via PASSWORD_MAX_ATTEMPTS and PASSWORD_LOCKOUT_MS

🔒 Security

  • server: Updated hono from 4.12.12 to 4.12.14 to fix HTML injection via improperly handled JSX attribute names in SSR (GHSA-458j-xx4x-4375)
  • infra: Added pnpm.overrides for esbuild (>=0.25.0), vite (>=6.4.2), and fast-xml-parser (>=5.7.0) to patch transitive vulnerabilities in dev/docs dependencies (GHSA-67mh-4wv8-2f99, GHSA-4w7w-66w2-5vf9, GHSA-gh4j-gqv2-49f6)
  • crypto: Tightened Argon2id-to-PBKDF2 fallback logic - the fallback now only triggers on WASM availability errors (CompileError, LinkError, or matching message) and propagates all other crypto errors instead of silently swallowing them
  • crypto: Increased Argon2id parameters from 19 MiB / 2 iterations to 64 MiB / 3 iterations, matching OWASP's strong recommendation and significantly raising GPU brute-force cost for new password-protected uploads
  • crypto: Increased HKDF salt length from 16 to 32 bytes for new uploads, matching the RFC 5869 recommendation to use a salt equal to the hash output length - legacy 16-byte salts from existing uploads are still accepted
  • crypto: Added stream truncation detection to createDecryptStream - callers can pass expectedPlaintextSize (from authenticated metadata) to detect a malicious server delivering fewer records than were encrypted
  • server: Added Referrer-Policy: no-referrer HTTP header to prevent URL fragments from leaking via Referer header in misconfigured or future environments
  • web: Added <meta name="referrer" content="no-referrer"> to index.html as defense-in-depth for the referrer policy
  • web: URL fragment (encryption key) is now removed from the browser address bar via history.replaceState once decryption begins, preventing key leakage through browser history
  • web: Note uploads now use Argon2id for password key derivation - previously PBKDF2 was always used for notes due to a missing argument
  • crypto: Removed Argon2id-to-PBKDF2 upload fallback entirely - if Argon2id WASM fails during an upload, an error is thrown instead of silently downgrading to PBKDF2 ("fail secure"); PBKDF2 decryption for existing uploads is unaffected
  • web: Added DOMPurify sanitization of highlight.js output before dangerouslySetInnerHTML in code notes - defense-in-depth against any future upstream hljs vulnerability
  • web: Added rehype-sanitize plugin to ReactMarkdown rendering in notes - prevents XSS from future react-markdown upstream changes that could enable raw HTML
  • web: URL fragment (encryption key) is now removed from the browser address bar via history.replaceState in NoteView immediately at page mount - previously only the Download page had this protection
  • server: Fixed IP extraction when TRUST_PROXY=true - previously the leftmost (client-controlled) value from X-Forwarded-For was used, allowing clients to spoof their IP and bypass rate limiting and upload quotas; now uses the rightmost (proxy-appended) value
  • server: Fixed S3 download with S3_PUBLIC_URL configured - previously a permanent public URL was returned, remaining valid indefinitely after DB record deletion and bypassing expiry/download-limit enforcement; now always uses presigned URLs with a TTL
  • web: Replaced deprecated apple-mobile-web-app-capable meta tag with the standard mobile-web-app-capable equivalent - eliminates browser console warning; the PWA manifest display: standalone already handles standalone mode on modern browsers

🎨 Improvements

  • web: Password prompt now shows a translated "too many attempts" error when the server returns 429 instead of switching away from the password screen

🔧 CI/CD

  • infra: Added OCI standard labels to Docker images via docker/metadata-action@v5 - sets title, description, url, source, version, revision, created, vendor, and licenses for better registry compatibility and Renovate/Dependabot integration

🧪 Tests

  • crypto: Expanded to 129 tests with 100% coverage - added security-property tests for HKDF domain separation, ECE reorder/truncation attacks, Argon2id error propagation, PBKDF2 known-answer verification, and legacy salt backward compatibility.
  • server: Added 24 integration tests for the chunked upload flow (/init, /chunk, /finalize), password-attempt lockout (429 + Retry-After), and invalid input handling across meta.ts, password.ts, and note.ts routes.
  • server: Added 5 tests for startCleanupJob (interval, stop function, logging, error recovery) - bringing cleanup.ts to 100%.
  • server: Brought upload-validation.ts and quota.ts to 100% - covers all check(), getStatus(), 413 middleware, DB key restoration, and interval behavior (rotation, expiry cleanup).
  • infra: Added vitest.config.ts for server and client; updated vite.config.ts for web - all with scoped coverage.include and explicit excludes for untestable files (browser workers, WASM, S3 backend, app entrypoints).

🐳 Docker

  • Image: skyfay/skysend:v2.5.0
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

Don't miss a new SkySend release

NewReleases is sending notifications on new releases.