Security
This page documents the security model implemented in current source.
Security Layers
account credential hashing (
services/db.ts)lock PIN verification (
services/db.ts+components/LockScreen.tsx)vault encryption and key wrapping (
services/vault.ts)OS-backed secret encryption (
services/secrets.ts+ Electron safeStorage)Electron process isolation + preload bridge (
electron/main.cjs,electron/preload.cjs)
PBKDF2 Parameters At a Glance
Two different PBKDF2 configurations exist in the codebase for different purposes.
Account/Auth
services/db.ts
password, security answer, and lock PIN hashing/verification
150000
Vault
services/vault.ts
deriving wrapping keys for vault master key protection
300000
This is intentional and not a mismatch: auth hashing and vault key-wrapping are separate security paths.
Account Password and Security Answer Hashing
Location: services/db.ts
Parameters:
algorithm: PBKDF2-SHA256
iterations:
150000salt length:
16byteshash length:
32bytes
Stored format:
Behavior:
existing plain-text passwords are re-hashed on successful login when possible
security answers are normalized (
trim().toLowerCase()) before hashing
Important limitation:
if Web Crypto is unavailable, hashing path falls back to plain text storage
Lock PIN
Lock settings live in User profile fields:
lockEnabledlockPin(hashed when possible)lockTimeoutMinutes
Runtime behavior:
app can lock on startup (if enabled)
app auto-locks after inactivity timer
PIN input is numeric-normalized
verification uses same hash verification mechanism as password
Vault Cryptography
Location: services/vault.ts
Design:
generate random AES-GCM 256 master key
wrap master key with password-derived key
wrap master key with recovery-code-derived key
encrypt vault payload with master key
Parameters:
cipher: AES-GCM (256-bit)
PBKDF2 hash: SHA-256
PBKDF2 iterations:
300000salt length:
16bytesIV length:
12bytes
Recovery model:
recovery code can decrypt vault and reset master password wrapping
if both password and recovery code are lost, data is unrecoverable by design
API Key and Secret Handling
Locations:
services/secrets.tselectron/main.cjs
Flow:
renderer asks preload for encrypt/decrypt
main process uses Electron
safeStorageencrypted values are stored with prefix
enc$
Fallback behavior:
if safeStorage is unavailable, values may remain plaintext or unresolved depending on call path
Backup Confidentiality
Current backup/export manifests are JSON payloads.
retention and atomic writes exist
backups are not encrypted by default
Confidentiality therefore depends on host filesystem protections.
Electron Hardening
Enabled controls in current main window configuration:
context isolation
node integration disabled
sandbox enabled
blocked direct external navigation
packaged CSP header policy
Permissions:
geolocation only for trusted app origins
Known Security Gaps
High-impact gaps to consider if continuing maintenance:
remove plaintext fallback when Web Crypto is unavailable
add encrypted backup option (passphrase-based)
enforce stricter behavior when safeStorage is unavailable
add more automated security regression tests (auth, vault, restore paths)
tighten type-safe notification severity handling (
warning/errorvsinfo/alert/successmismatch in callers)
Last updated
Was this helpful?
