Description
When DATABASE_URL does not start with mysql: or postgresql:, vaultwarden silently treats it as a SQLite file path due to the catch-all else branch in DbConnType::from_url. This means any misconfiguration that does not contain a / (or whose path happens to resolve to an existing directory) results in an empty SQLite database being quietly created rather than an error.
In containerised or ephemeral environments, this causes data loss on restart. The user believes they are connected to their intended database whilst secrets are actually written to a throwaway SQLite file that is destroyed when the container restarts.
Steps to reproduce
- Set
DATABASE_URL to any value that is not a valid database URI, e.g. DATABASE_URL=foobar
- Start vaultwarden in a container
- Observe no error. Vaultwarden starts and creates a local SQLite database named
foobar
- Store some secrets
- Restart the container
- Secrets are gone
Prior art
This has been reported before in #2835 and #1910. The partial fix in #2873 (checking the parent directory exists) helps when the misconfigured URL would create a new directory, but does not cover cases where the resolved path sits within an existing directory (such as the working directory itself).
The suggestions from contributors in #2873 (checking for colons, checking for quote characters) were never implemented.
Proposed fix
See #7061. Require an explicit sqlite:// prefix for new SQLite deployments. Bare paths without a recognised scheme are still accepted for backwards compatibility, but only when the database file already exists. Otherwise the process panics with a clear error message.
Description
When
DATABASE_URLdoes not start withmysql:orpostgresql:, vaultwarden silently treats it as a SQLite file path due to the catch-allelsebranch inDbConnType::from_url. This means any misconfiguration that does not contain a/(or whose path happens to resolve to an existing directory) results in an empty SQLite database being quietly created rather than an error.In containerised or ephemeral environments, this causes data loss on restart. The user believes they are connected to their intended database whilst secrets are actually written to a throwaway SQLite file that is destroyed when the container restarts.
Steps to reproduce
DATABASE_URLto any value that is not a valid database URI, e.g.DATABASE_URL=foobarfoobarPrior art
This has been reported before in #2835 and #1910. The partial fix in #2873 (checking the parent directory exists) helps when the misconfigured URL would create a new directory, but does not cover cases where the resolved path sits within an existing directory (such as the working directory itself).
The suggestions from contributors in #2873 (checking for colons, checking for quote characters) were never implemented.
Proposed fix
See #7061. Require an explicit
sqlite://prefix for new SQLite deployments. Bare paths without a recognised scheme are still accepted for backwards compatibility, but only when the database file already exists. Otherwise the process panics with a clear error message.