If you discover a security vulnerability in Yuvomi, please report it responsibly. Do not open a public issue.
Instead, use GitHub Private Vulnerability Reporting to submit your report. This creates a private advisory visible only to you and the maintainers.
Include:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if you have one)
You should receive an acknowledgment within 48 hours. Fixes for confirmed vulnerabilities will be released as soon as possible.
Yuvomi is designed for self-hosted deployment on a private network behind a reverse proxy with SSL. The security model assumes:
- The server is not directly exposed to the public internet without Nginx + TLS
- The admin controls all user accounts (no public registration)
- The host machine itself is reasonably secured
Vulnerabilities that require physical access to the host or root on the server are generally out of scope.
- Session-based auth with
httpOnly,SameSite=Lax,Securecookies (Lax instead of Strict because Safari Intelligent Tracking Prevention blocks Strict cookies on reverse-proxy navigations and direct URL entry, which would cause 401 errors on login. CSRF risk is mitigated by the Double Submit Cookie pattern listed below and theSecureflag.) - CSRF protection via Double Submit Cookie on all state-changing requests
- Passwords hashed with bcrypt v6 (cost factor 12). Passwords are Unicode-normalized to NFC before hashing and verification, so non-ASCII characters (umlauts, accents) authenticate identically regardless of how the browser normalizes the input. Hashes created before this normalization are still accepted and are silently re-hashed to NFC on the next successful login
- Login rate limiting (5 attempts/min per IP)
- API rate limiting (300 requests/min per IP)
- Content Security Policy via Helmet (
self-only) - Optional SQLCipher AES-256 database encryption, enabled by setting
DB_ENCRYPTION_KEY. The cipher ships inside thebetter-sqlite3-multiple-ciphersbinding, so Docker and bare-metal installs are covered alike and no system SQLCipher is required. If the key is set but encryption is unavailable, or the file on disk is still plaintext, the app refuses to start instead of silently storing data unencrypted. An existing unencrypted database is migrated once on startup, leaving a*.plaintext-backupcopy behind that you should delete after verifying the migration - Existing WebDAV documents protect their connection configuration: changing the URL, username, password, or base path requires explicit admin confirmation and a successful read test against an existing object; required connection data cannot be removed while WebDAV documents exist
- UI-managed WebDAV document-storage URLs are protected against SSRF: private, loopback, link-local, internal-DNS, and DNS-rebinding targets are rejected before persistence and during socket lookup. Trusted private-network targets require the deployment-controlled
DOCUMENT_STORAGE_WEBDAV_URLoverride - Google Drive document storage requests only
drive.file, creates no public permissions, and uses a Drive-specific redirect URI, session OAuth state anddocument_storage_google_drive_*token namespace. Calendar token and state records are never reused or broadened - Drive OAuth tokens, codes, folder IDs and raw Google responses are never returned by the API or intentionally logged. Disconnect deletes local Drive state without calling Google's revocation endpoint, so shared Calendar credentials are not revoked
- Reconnection validates the candidate account and access to an existing Drive-backed file before atomically replacing working tokens. Disconnect is blocked while Drive is selected or referenced by documents; connecting Drive never activates it for uploads
- Subscription logo discovery is SSRF-protected: only public HTTPS targets are fetched, every redirect is re-validated, and remote image responses are size/type constrained
- No API endpoint accessible without session auth (except login)
SESSION_SECRETis mandatory - server refuses to start if unset
Yuvomi uses a flat family authorization model:
- Admin can create, edit, and delete all user accounts and all shared data.
- Member can read and write all shared data (tasks, shopping lists, meals, calendar events, notes, contacts, budget entries) but cannot manage user accounts.
There is no per-user data isolation - all family members see and can edit all data. This is intentional: Yuvomi is a shared family planner, not a multi-tenant application.
Only the latest version on main receives security updates. There are no LTS branches.