2.6 KiB
2.6 KiB
Security
Bill Tracker is a self-hosted app that stores financial records, bank connections, and encryption keys. Security is a first-class concern.
Reporting a vulnerability
Please report suspected vulnerabilities privately to the maintainer (do not open a public issue). Include steps to reproduce and impact. We aim to acknowledge within a few days.
Controls in place
- Authentication: bcrypt passwords, hashed + rotating session tokens, optional TOTP 2FA and WebAuthn/FIDO2, OIDC. Failed-login tracking + login history.
- Authorization:
requireAuth/requireUser/requireAdminon every non-public route; all user data is scoped byuser_id(isolation is covered by tests). - CSRF: double-submit token (
csrfMiddleware) on all authenticated mutating routes. - Rate limiting: on auth, admin, import/export, backup, and password-change surfaces.
- Encryption at rest: AES-256-GCM with HKDF key derivation for stored secrets
(SimpleFIN token, SMTP/OIDC secrets, login metadata); a non-reversible key fingerprint
lets operators verify the active key. Set
TOKEN_ENCRYPTION_KEYin production so the key lives outside the database. - Transport/headers: security headers + CSP (
securityHeaders), Secure/HttpOnly/SameSite cookies, opt-in CORS allowlist. - Audit: security-sensitive actions recorded to
audit_log. - Automated in CI: secret scanning (gitleaks), dependency audit (
npm audit), lint + typecheck + tests on every push.
Known dependency-audit exceptions (assessed)
npm audit reports two HIGH advisories that are not currently actionable via npm and are
assessed as follows:
- nodemailer —
rawmessage option file-read/SSRF. Not exploitable here: the app builds messages via the normal API and never passes a user-controlledrawoption. The npm fix requires nodemailer 9 (breaking); deferred until a maintenance window with SMTP re-test. - xlsx (SheetJS) — prototype pollution. Confined to
services/spreadsheetImportService.cts(import only), which parses withraw: falsebehind a 10 MB size cap and content-type allowlist. SheetJS publishes fixes only via its own CDN (not npm); migrating to the CDN build (or a maintained alternative) is tracked as follow-up.
The CI dependency gate fails on critical; highs are reviewed here.
Operational hardening
- Set
TOKEN_ENCRYPTION_KEY(outside the DB) in production. - Run behind HTTPS with
TRUST_PROXYset appropriately. - Turn off verbose/debug logging (e.g.
simplefin_debug_logging) in production. - Back up
data/dbencrypted; never commit databases or keys (gitignored + gitleaks).