Unset bootstrap credentials before exec-ing the server#1412
Conversation
POSTGRES_PASSWORD (and related vars) are only needed during initdb and the temporary-server initialisation phase. After that they serve no purpose, but remain in the process environment for the entire lifetime of the container, where any loaded C extension can read them via environ. Unsetting them immediately before the final exec ensures the running PostgreSQL server process starts with a clean environment.
| fi | ||
|
|
||
| unset POSTGRES_PASSWORD POSTGRES_USER POSTGRES_DB POSTGRES_INITDB_ARGS |
There was a problem hiding this comment.
This should move up inside the final fi above (so it lives inside the if [ "$1" = 'postgres' ] && ! _pg_want_help "$@"; then block) so that it's only unset for postgres itself. I think I'd also prefer to do something like unset "${!POSTGRES_@}" so it catches anything else too (PostgreSQL itself doesn't use this naming scheme, to my knowledge).
| fi | |
| unset POSTGRES_PASSWORD POSTGRES_USER POSTGRES_DB POSTGRES_INITDB_ARGS | |
| unset "${!POSTGRES_@}" | |
| fi | |
It also needs to be applied across all the templated files (./apply-templates.sh).
There was a problem hiding this comment.
This should move up inside the final
fiabove (so it lives inside theif [ "$1" = 'postgres' ] && ! _pg_want_help "$@"; thenblock) so that it's only unset forpostgresitself. I think I'd also prefer to do something likeunset "${!POSTGRES_@}"so it catches anything else too (PostgreSQL itself doesn't use this naming scheme, to my knowledge).
I could not find any usage of that pattern (for environment variables) in the Postgres source code. Most of the getenv() calls have hard-coded names not matching this, or are in libpq or in binaries (and does seem to use that either, but these are variables).
It also needs to be applied across all the templated files (
./apply-templates.sh).
Done.
tianon
left a comment
There was a problem hiding this comment.
This is technically a breaking change, but maybe it's OK?
(COPY ... FROM PROGRAM '...')
Co-authored-by: Tianon Gravi <admwiggin@gmail.com>
Not sure what you're referring to here. Where would that SQL be added? |
|
I mean that end users can run SQL commands that read these environment variables from the server's environment via running explicit server-side programs with I also don't know if that's the only way these might have been historically exposed to end-users or PostgreSQL itself (environment variables in config, etc); just trying to watch out for Hyrum's Law because it tends to bite us every time we harden something like this. 😂 |
|
@tianon, there could be extensions that read the environment as well (like @mkindahl wrote about on their blog or the So, this seems good to me, but I agree that we will likely have someone affected. |
Ah, I see. 😄 Yes, that scenario would break, but only for reading these variables.
Yeah, that is always a risk. 😄 |
Thank you. Who normally hits the merge button? Submitter or reviewers? It is different everywhere. |
POSTGRES_PASSWORD (and related vars) are only needed during initdb and the temporary-server initialisation phase. After that they serve no purpose, but remain in the process environment for the entire lifetime of the container, where any loaded C extension can read them via environ.
Unsetting them immediately before the final exec ensures the running PostgreSQL server process starts with a clean environment.