Stop using environment variables for sending database passwords to PostgreSQL #1012

Closed
opened 2025-02-28 22:04:00 +00:00 by witten · 1 comment
Owner

What I'd like to do and why

Providing passwords to PostgreSQL via environment variable (e.g. PGPASSWORD, which borgmatic uses today) has security implications. That's because the password can potentially be spied upon by child processes or, with root access, by looking at OS-level process metadata.

So as part of this ticket, modify the borgmatic PostgreSQL hook to pass the configured password to the database client command via a more secure mechanism.

Other notes / implementation ideas

#1009 changed the MariaDB/MySQL hooks to use an anonymous pipe instead of an environment variable for transmitting the database password. A similar approach could work for PostgreSQL. It might go something like this:

  • Remove the use of PGPASSWORD and --username.
  • Add the use of PGPASSFILE. The value of the file should be something like /dev/fd/9 where "9" is the file descriptor of an anonymous pipe created for this purpose.
  • Populate the anonymous pipe with a password file with the appropriate username and password. E.g., something like: *:*:*:myuser:thepassword

EDIT: This approach won't work, at least not via anonymous pipe, because Postgres disallows non-plain files to serve as the password file:

WARNING: password file "/dev/fd/5" is not a plain file

A PostgreSQL mailing list discussion on the topic starts here: https://postgrespro.com/list/id/CABvH9hXLDEhy8eGxLyXzaXMdPuQYd5_=f-u4VUZ4SQs_VMSe2Q@mail.gmail.com

### What I'd like to do and why Providing passwords to PostgreSQL via environment variable (e.g. `PGPASSWORD`, which borgmatic uses today) has [security implications](https://www.postgresql.org/docs/current/libpq-envars.html). That's because the password can potentially be spied upon by child processes or, with root access, by looking at OS-level process metadata. So as part of this ticket, modify the borgmatic PostgreSQL hook to pass the configured password to the database client command via a more secure mechanism. ### Other notes / implementation ideas #1009 changed the MariaDB/MySQL hooks to use an anonymous pipe instead of an environment variable for transmitting the database password. A similar approach could work for PostgreSQL. It might go something like this: * Remove the use of `PGPASSWORD` and `--username`. * Add the use of `PGPASSFILE`. The value of the file should be something like `/dev/fd/9` where "9" is the file descriptor of an anonymous pipe created for this purpose. * Populate the anonymous pipe with a [password file](https://www.postgresql.org/docs/current/libpq-pgpass.html) with the appropriate username and password. E.g., something like: `*:*:*:myuser:thepassword` EDIT: This approach won't work, at least not via anonymous pipe, because Postgres disallows non-plain files to serve as the password file: ``` WARNING: password file "/dev/fd/5" is not a plain file ``` A PostgreSQL mailing list discussion on the topic starts here: https://postgrespro.com/list/id/CABvH9hXLDEhy8eGxLyXzaXMdPuQYd5_=f-u4VUZ4SQs_VMSe2Q@mail.gmail.com
Author
Owner

Closing this wontfix for now... The anonymous pipe approach is a non-starter (see above). And while using a named temporary password file would be possible, doing it in such a way that it'd actually get cleaned up / deleted at the proper time would be a pain.

Closing this wontfix for now... The anonymous pipe approach is a non-starter (see above). And while using a named temporary password file would be possible, doing it in such a way that it'd actually get cleaned up / deleted at the proper time would be a pain.
Sign in to join this conversation.
No milestone
No assignees
1 participant
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
borgmatic-collective/borgmatic#1012
No description provided.