Newly created configuration files are world readable #490

Closed
opened 2025-10-09 16:34:14 +03:00 by OVERLORD · 9 comments
Owner

Originally created by @pimlie on GitHub.

Originally assigned to: @BlackDex on GitHub.

Subject of the issue

After setting up a new (docker) instance of vaultwarden, all configuration files/folders have 644/755 permissions

Deployment environment

Your environment (Generated via diagnostics page)

  • Vaultwarden version: v1.30.5
  • Web-vault version: v2024.1.2b
  • OS/Arch: linux/x86_64
  • Running within a container: true (Base: Debian)
  • Environment settings overridden: true
  • Uses a reverse proxy: true
  • IP Header check: true (X-Real-IP)
  • Internet access: true
  • Internet access via a proxy: false
  • DNS Check: true
  • Browser/Server Time Check: true
  • Server/NTP Time Check: true
  • Domain Configuration Check: true
  • HTTPS Check: true
  • Database type: SQLite
  • Database version: 3.44.0
  • Clients used:
  • Reverse proxy and version:
  • Other relevant information:

Steps to reproduce

Start a new vaultwarden docker instance and mount the /data volume to a new folder

Expected behaviour

Vaultwarden configuration files should not be world readable, maybe even don't let groups have (write) access by default. So all files under /data should have at least 660/770 permissions and maybe 640/750 or 600/700

Actual behaviour

Vaultwarden configuration files are world readable

Troubleshooting data

/data$ ls -laF
total 308
drwxr-xr-x 6 root root   4096 May 18 13:48 ./
drwxr-xr-x 1 root root   4096 May 18 13:48 ../
drwxr-xr-x 2 root root   4096 May 18 13:48 attachments/
-rw-r--r-- 1 root root 249856 May 18 13:48 db.sqlite3
-rw-r--r-- 1 root root  32768 May 18 13:48 db.sqlite3-shm
-rw-r--r-- 1 root root      0 May 18 13:48 db.sqlite3-wal
drwxr-xr-x 2 root root   4096 May 18 13:48 icon_cache/
-rw-r--r-- 1 root root   1675 May 18 13:48 rsa_key.pem
-rw-r--r-- 1 root root    451 May 18 13:48 rsa_key.pub.pem
drwxr-xr-x 2 root root   4096 May 18 13:48 sends/
drwxr-xr-x 2 root root   4096 May 18 13:48 tmp/
Originally created by @pimlie on GitHub. Originally assigned to: @BlackDex on GitHub. <!-- Please fill out the following template to make solving your problem easier and faster for us. This is only a guideline. If you think that parts are unnecessary for your issue, feel free to remove them. Remember to hide/redact personal or confidential information, such as passwords, IP addresses, and DNS names as appropriate. --> ### Subject of the issue After setting up a new (docker) instance of vaultwarden, all configuration files/folders have 644/755 permissions ### Deployment environment ### Your environment (Generated via diagnostics page) * Vaultwarden version: v1.30.5 * Web-vault version: v2024.1.2b * OS/Arch: linux/x86_64 * Running within a container: true (Base: Debian) * Environment settings overridden: true * Uses a reverse proxy: true * IP Header check: true (X-Real-IP) * Internet access: true * Internet access via a proxy: false * DNS Check: true * Browser/Server Time Check: true * Server/NTP Time Check: true * Domain Configuration Check: true * HTTPS Check: true * Database type: SQLite * Database version: 3.44.0 * Clients used: * Reverse proxy and version: * Other relevant information: ### Steps to reproduce Start a new vaultwarden docker instance and mount the `/data` volume to a new folder ### Expected behaviour Vaultwarden configuration files should not be world readable, maybe even don't let groups have (write) access by default. So all files under /data should have at least 660/770 permissions and maybe 640/750 or 600/700 ### Actual behaviour Vaultwarden configuration files are world readable ### Troubleshooting data ```bash /data$ ls -laF total 308 drwxr-xr-x 6 root root 4096 May 18 13:48 ./ drwxr-xr-x 1 root root 4096 May 18 13:48 ../ drwxr-xr-x 2 root root 4096 May 18 13:48 attachments/ -rw-r--r-- 1 root root 249856 May 18 13:48 db.sqlite3 -rw-r--r-- 1 root root 32768 May 18 13:48 db.sqlite3-shm -rw-r--r-- 1 root root 0 May 18 13:48 db.sqlite3-wal drwxr-xr-x 2 root root 4096 May 18 13:48 icon_cache/ -rw-r--r-- 1 root root 1675 May 18 13:48 rsa_key.pem -rw-r--r-- 1 root root 451 May 18 13:48 rsa_key.pub.pem drwxr-xr-x 2 root root 4096 May 18 13:48 sends/ drwxr-xr-x 2 root root 4096 May 18 13:48 tmp/ ```
OVERLORD added the troubleshootinglow priority labels 2025-10-09 16:34:14 +03:00
Author
Owner

@pimlie commented on GitHub:

There is no sane default you can configure here

It is often best to be secure-by-default, and allow users to be less secure if they have a need for that like with your backup example (even though they should configure that through the group and add their backup user to the vw group). Especially for a product like a password manager, the sane default should be as strict as what is at minimum needed for vw to run.

there unfortunately is no quick and easy solution to solve

Aren't there something like a pre-start or post-release-upgrade hooks?
For existing installations, I don't think this is something that needs to be checked on every write, should be fine just on startup and/or after an upgrade.
For new installations, it sounds like you are saying that configuration files are created implicitly instead of explicitly? Isn't it possible to detect if a file exists and if not create it & set umask after creating it instead of f.e. doing all at once?

the default then still would first be 644/755 i think to not break existing installations

It would probably be best to come up with a migration path that would allow us to fix this behaviour without breaking user space indeed. Cause the rsa_key is world readable too, which is pretty unsafe. Also compare this to ssh behaviour, if your ssh keys are world readable then as a security consideration you often can't even use them at all.

F.e. a migration path could look something like this:

  • on startup, check if user has specifically configured the user permissions (this should be a vw setting, so don't check the file system permissions themselves for this)
  • if user defined permissions, ensure configuration files are using these user defined permissions and either fix & log a warning when permissions are different or just error-out and let the user fix the permissions (as it might be better to be explicit so the user can fe investigate why the permissions have changed)
  • if user did not define permissions, check if this is a new or an existing installation
  • if existing installation, don't try to change the user permissions but log a warning about possible unsafe permissions
  • if new installation, enforce the most secure file permissions when creating all files

For docker, it would probably be best to just always run the vw server as a user instead of root, but let the user specify UID & GID through environmental variables. In docker it should then also be safe to change the default UMASK for that user to 027

@pimlie commented on GitHub: > There is no sane default you can configure here It is often best to be [secure-by-default](https://en.wikipedia.org/wiki/Secure_by_default), and allow users to be less secure if they have a need for that like with your backup example (even though they should configure that through the group and add their backup user to the vw group). Especially for a product like a password manager, the sane default should be as strict as what is at minimum needed for vw to run. > there unfortunately is no quick and easy solution to solve Aren't there something like a pre-start or post-release-upgrade hooks? For existing installations, I don't think this is something that needs to be checked on every write, should be fine just on startup and/or after an upgrade. For new installations, it sounds like you are saying that configuration files are created implicitly instead of explicitly? Isn't it possible to detect if a file exists and if not create it & set umask after creating it instead of f.e. doing all at once? > the default then still would first be 644/755 i think to not break existing installations It would probably be best to come up with a migration path that would allow us to fix this behaviour without breaking user space indeed. Cause the `rsa_key` is world readable too, which is pretty unsafe. Also compare this to ssh behaviour, if your ssh keys are world readable then as a security consideration you often can't even use them at all. F.e. a migration path could look something like this: - on _startup_, check if user has specifically configured the user permissions (this should be a vw setting, so don't check the file system permissions themselves for this) - if _user defined permissions_, ensure configuration files are using these user defined permissions and either fix & log a warning when permissions are different or just error-out and let the user fix the permissions (as it might be better to be explicit so the user can fe investigate why the permissions have changed) - if _user did not define permissions_, check if this is a new or an existing installation - if _existing installation_, don't try to change the user permissions but log a warning about possible unsafe permissions - if _new installation_, enforce the most secure file permissions when creating all files For docker, it would probably be best to just always run the vw server as a user instead of root, but let the user specify UID & GID through environmental variables. In docker it should then also be safe to change the default UMASK for that user to 027
Author
Owner

@twkonefal commented on GitHub:

I discovered this configuration error accidentally after installing my vaultwarden instance. I'm sorry if this is unhappy for you to hear, but there is no way that the rsa_key should ever be world-readable by default. I don't know enough about Bitwarden to say whether the sqlite databases should be private, too, but I'm hoping these are encrypted and shouldn't require special care. Having said that, it will be nice to have them not world-readable, too.

With the current settings, Vaultwarden is a security liability and I would not recommend it to anyone.

@twkonefal commented on GitHub: I discovered this configuration error accidentally after installing my vaultwarden instance. I'm sorry if this is unhappy for you to hear, but there is no way that the rsa_key should ever be world-readable by default. I don't know enough about Bitwarden to say whether the sqlite databases should be private, too, but I'm hoping these are encrypted and shouldn't require special care. Having said that, it will be nice to have them not world-readable, too. With the current settings, Vaultwarden is a security liability and I would not recommend it to anyone.
Author
Owner

@BlackDex commented on GitHub:

There is no sane default you can configure here. Some users are relying on the world readable to be able to backup for example.
Setting it to 660/770 or 640/750 could also be causing issues, but probably less.

Also, there unfortunately is no quick and easy solution to solve this exxcept by always setting the modes during all write actions.
That might cause some overhead. And also, there is no general umask functionality in Rust which respect these settings.

We might be able to centralize all file writing actions maybe and allow something like a umask behavior. Only file uploads need to be handled differently since those are done by Tempfile.

Though, the default then still would first be 644/755 i think to not break existing installations.

@BlackDex commented on GitHub: There is no sane default you can configure here. Some users are relying on the world readable to be able to backup for example. Setting it to 660/770 or 640/750 could also be causing issues, but probably less. Also, there unfortunately is no quick and easy solution to solve this exxcept by always setting the modes during all write actions. That might cause some overhead. And also, there is no general umask functionality in Rust which respect these settings. We might be able to centralize all file writing actions maybe and allow something like a umask behavior. Only file uploads need to be handled differently since those are done by Tempfile. Though, the default then still would first be 644/755 i think to not break existing installations.
Author
Owner

@BlackDex commented on GitHub:

A quick reply regarding the docker user, that isn't something easily changed, as that also breaks existing setups. If something like that is to be done it needs to be announced upfront for a long time.
There might be some way to have root still as a default and be adjustable. But the migration is very error prone.

I do agree that the current way isn't ideal, but changing it also is not that easy with all the different setups already running.

@BlackDex commented on GitHub: A quick reply regarding the docker user, that isn't something easily changed, as that also breaks existing setups. If something like that is to be done it needs to be announced upfront for a long time. There might be some way to have root still as a default and be adjustable. But the migration is very error prone. I do agree that the current way isn't ideal, but changing it also is not that easy with all the different setups already running.
Author
Owner

@tessus commented on GitHub:

I "fixed" the issue on my side by setting the permissions of the /etc/vaultwarden and /data directories to 750 and using a separate vaultwarden uaer and group.

I'm using vaultwarden w/o docker and with MySQL, but your data dir is a bind mount, so you can always change the dir permissions easily.

@tessus commented on GitHub: I "fixed" the issue on my side by setting the permissions of the `/etc/vaultwarden` and `/data` directories to `750` and using a separate `vaultwarden` uaer and group. I'm using vaultwarden w/o docker and with MySQL, but your data dir is a bind mount, so you can always change the dir permissions easily.
Author
Owner

@BlackDex commented on GitHub:

Was taking a look at this today, and it's actually very easy to solve this.
Vaultwarden containers already have an option to run custom scripts before Vaultwarden starts, via this way you set the umask your self.

Ill see if i can add this in a simple way by default though via an ENV.

Simple example:

scripts/umask.sh:

#!/usr/bin/env sh
umask 077
docker run --rm -it \
  -e DISABLE_ADMIN_TOKEN=true \
  -e ROCKET_PORT=8080 \
  -v "${PWD}/data/:/data" \
  -v "${PWD}/scripts/:/etc/vaultwarden.d/:ro" \
  --network=host \
  --name vwtest \
  vaultwarden/server:testing-alpine

Or via docker compose:

---
services:
  vaultwarden:
    image: vaultwarden/server:testing-alpine
    network_mode: host
    container_name: vwtest
    restart: unless-stopped
    volumes:
      - ./data/:/data/
      - ./scripts/:/etc/vaultwarden.d/:ro
    environment:
      - TZ=Europe/Amsterdam
      - ROCKET_PORT=8080
      - LOG_FILE=/data/vaultwarden.log
      - DISABLE_ADMIN_TOKEN=true
@BlackDex commented on GitHub: Was taking a look at this today, and it's actually very easy to solve this. Vaultwarden containers already have an option to run custom scripts before Vaultwarden starts, via this way you set the umask your self. Ill see if i can add this in a simple way by default though via an ENV. Simple example: scripts/umask.sh: ```bash #!/usr/bin/env sh umask 077 ``` ```bash docker run --rm -it \ -e DISABLE_ADMIN_TOKEN=true \ -e ROCKET_PORT=8080 \ -v "${PWD}/data/:/data" \ -v "${PWD}/scripts/:/etc/vaultwarden.d/:ro" \ --network=host \ --name vwtest \ vaultwarden/server:testing-alpine ``` Or via docker compose: ```yml --- services: vaultwarden: image: vaultwarden/server:testing-alpine network_mode: host container_name: vwtest restart: unless-stopped volumes: - ./data/:/data/ - ./scripts/:/etc/vaultwarden.d/:ro environment: - TZ=Europe/Amsterdam - ROCKET_PORT=8080 - LOG_FILE=/data/vaultwarden.log - DISABLE_ADMIN_TOKEN=true ```
Author
Owner

@tessus commented on GitHub:

With the current settings, Vaultwarden is a security liability and I would not recommend it to anyone.

Hmm, I don't think you know what you are talking about. It is certainly not ideal, but it is not a security liability. I suggest you look at the architecture and the security implementation.

@tessus commented on GitHub: > With the current settings, Vaultwarden is a security liability and I would not recommend it to anyone. Hmm, I don't think you know what you are talking about. It is certainly not ideal, but it is not a security liability. I suggest you look at the architecture and the security implementation.
Author
Owner

@BlackDex commented on GitHub:

I have created a PR which allows setting a custom UMASK which should solve your issue.
We will not set the default right now to a more secure mask to not break current installations though.

@BlackDex commented on GitHub: I have created a PR which allows setting a custom `UMASK` which should solve your issue. We will not set the default right now to a more secure mask to not break current installations though.
Author
Owner

@BlackDex commented on GitHub:

Ill create/update a wiki once tagged.

@BlackDex commented on GitHub: Ill create/update a wiki once tagged.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/vaultwarden#490