CRITICAL: SMTP password stored in plaintext in SQLite #69

Closed
opened 2026-05-31 12:02:35 -05:00 by null · 1 comment
Owner

Bug Description

The SMTP password (notify_smtp_password) is stored directly in the user_settings table as plaintext. While it is masked (dots) in API GET responses (routes/notifications.js:20), anyone with direct access to the SQLite database file (e.g., via backup extraction or filesystem access) can read the SMTP credentials in cleartext.

This contrasts with the data_sources table, which properly encrypts secrets using AES-256-GCM via encryptionService.

Affected Files

  • routes/notifications.js:37 - plaintext password saved via setSetting()
  • services/notificationService.js:16 - plaintext password read via getSetting()
  • db/database.js:2813 - default empty string for notify_smtp_password setting

Impact

If the SQLite database is accessed (backup download, filesystem breach), SMTP credentials are immediately exposed. The data_sources.encrypted_secret column demonstrates the correct pattern already exists.

  • Use encryptionService.encryptSecret() / decryptSecret() for the SMTP password, same as SimpleFIN access tokens
  • Store the encrypted version in settings with a prefix (e.g., enc:) to distinguish from legacy plaintext values
  • Add migration to encrypt existing plaintext passwords
## Bug Description The SMTP password (notify_smtp_password) is stored directly in the user_settings table as plaintext. While it is masked (dots) in API GET responses (routes/notifications.js:20), anyone with direct access to the SQLite database file (e.g., via backup extraction or filesystem access) can read the SMTP credentials in cleartext. This contrasts with the data_sources table, which properly encrypts secrets using AES-256-GCM via encryptionService. ## Affected Files - routes/notifications.js:37 - plaintext password saved via setSetting() - services/notificationService.js:16 - plaintext password read via getSetting() - db/database.js:2813 - default empty string for notify_smtp_password setting ## Impact If the SQLite database is accessed (backup download, filesystem breach), SMTP credentials are immediately exposed. The data_sources.encrypted_secret column demonstrates the correct pattern already exists. ## Recommended Fix - Use encryptionService.encryptSecret() / decryptSecret() for the SMTP password, same as SimpleFIN access tokens - Store the encrypted version in settings with a prefix (e.g., enc:) to distinguish from legacy plaintext values - Add migration to encrypt existing plaintext passwords
null added the
backend
bug
priority:critical
labels 2026-05-31 12:02:35 -05:00
Author
Owner

0.34.2.1 corrected

0.34.2.1 corrected
null closed this issue 2026-05-31 12:56:35 -05:00
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: null/BillTracker#69
No description provided.