50 lines
2.6 KiB
Markdown
50 lines
2.6 KiB
Markdown
# 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` / `requireAdmin` on every non-public
|
|
route; all user data is scoped by `user_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_KEY` in 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 — `raw` message option file-read/SSRF.** Not exploitable here: the app builds
|
|
messages via the normal API and never passes a user-controlled `raw` option. 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 with `raw: false` behind 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_PROXY` set appropriately.
|
|
- Turn off verbose/debug logging (e.g. `simplefin_debug_logging`) in production.
|
|
- Back up `data/db` encrypted; never commit databases or keys (gitignored + gitleaks).
|