-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
POSTGRES_USER should not be superuser #175
Comments
this is a bad idea. Please leave it as a superuser. A lot of applications need to be able to enable extensions such as uuid support. There is no clear way to do something like that without the user being a superuser. |
An example #!/bin/bash
set -e
psql -v ON_ERROR_STOP=1 --username="$POSTGRES_SUPERUSER" --dbname="$POSTGRES_DB" <<-'EOSQL'
CREATE EXTENSION IF NOT EXISTS pg_buffercache;
EOSQL |
Common sense tells us that using the superuser by default is a security risk. |
I think we're too late to change the default here (and tend to agree that by default, |
I'd love to hear from Postgres people on whether they think a default of
superuser is "to be expected". (Is it a safe default? Because otherwise it
should be treated as a security issue and fixed.)
I mean, it'd be great to hear it from the horse's mouth...
…On 26 Jan 2017 07:31, "Tianon Gravi" ***@***.***> wrote:
I think we're too late to change the default here (and tend to agree that
by default, SUPERUSER is probably expected), but I'm definitely +1 to
adding an easy way to opt out of that! (something like
POSTGRES_USER_NOT_SUPER -- definitely want to hear alternate name
suggestions for that)
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#175 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAhf6z1A-bLrL2Ms6NH79XkyRGRbgUq_ks5rV9tggaJpZM4JLTjI>
.
|
Any news on this, would be great to have an option to create a user without superuser rights. |
The security model of PostgreSQL is complex but in operation
So I as a system integrator deploying PostgreSQL servers in containers using an "official" image would expect that I could log into the command line of a running container with |
I don't understand that argument, because you can easily do (where psql --username="$POSTGRES_SUPERUSER" Things should definitely be secure by default. |
Security by obscurity? |
@teohhanhui More like only allowing intra-server connections via Unix sockets - PostgreSQL service isn't even listening on localhost or the internet. With Docker, that corresponds to only listening on the internal Docker network. I can't see a reason to host a PostgreSQL server listening on the internet unless you're a cloud provider and you're selling the service. If you're using PostgreSQL you should be the only one capable of connecting to it. |
@znmeb You are right about your arguments, but you are still increasing the attack surface - if my app/service does not need super-user rights at runtime (and it doesn't) it should not have them. |
@Globegitter Absolutely! A lot of this is a carry-over from the Linux-Apache-RDBMS-PHP model where everything lived on a single server and only Apache talked to the user and only PHP talked to Apache and the RDBMS. In the Docker model, you have a lot more flexibility. |
How about a way to pass in a list of extensions to create / enable via something more generic of what @teohhanhui recommended? I agree superuser is likely a security issue... but anything that requires a superuser needs to have a way to have those actions performed without users forking and editing the postgres base container. (aka Bob's old-postgresql-with-uuid-suppport) |
That's a pretty minimal example that needs more work though. Then in the environment: |
@avongluck-r1soft I don't see how that's better than #175 (comment) We shouldn't create more shortcuts to do the same thing. But maybe it'd be great to have helper scripts like |
@teohhanhui your version would not work in CI setups for example - the behavior needs to be fully controlled through environment variables. The gitlab runner is one example. |
Security aside it's just safer from an application perspective. For example, this protects if someone "accidentally" adds code to the app, say, to drop the entire database. |
In hindsight the I see a two options that are mostly backwards compatible (new env names are up for debate):
Even though is more complicated I am partial to number two. Basically if you only supply a single user (via Any discussion about extensions is orthogonal to this issue and would be better suited to its own issue. |
@yosifkit just putting it out there, could there be another option:
|
@masterBrog's comment sounds good. |
I'm having good luck with this, added to I'm using the latest alpine image, so YMMV: https://gist.github.com/dakotahawkins/d67054072d3ea2e507b1327ca544855f WARNING Indent with tabs or the #!/usr/bin/env bash
####################################################################################################
# Initializes a new non-superuser user and password for use with the database
#
# This may be officially supported soon: https://github.com/docker-library/postgres/issues/175
main() {
file_env 'POSTGRES_DB_USER'
file_env 'POSTGRES_DB_PASSWORD'
if [ "$POSTGRES_DB_USER" ] && [ "$POSTGRES_DB_PASSWORD" ] && [ "$POSTGRES_DB" ]; then
"${psql[@]}" <<-EOSQL
CREATE ROLE "$POSTGRES_DB_USER" WITH NOSUPERUSER LOGIN PASSWORD '$POSTGRES_DB_PASSWORD' ;
GRANT ALL PRIVILEGES ON DATABASE "$POSTGRES_DB" TO "$POSTGRES_DB_USER" ;
EOSQL
else
error-exit "POSTGRES_DB_USER, POSTGRES_DB_PASSWORD, POSTGRES_DB must all be set."
fi
}
error-exit() {
echo "$1" >&2
echo
exit 1
}
main "$@"
Note: I'm using Hopefully this helps somebody else! |
Hi, Thanks for all this greate works. @tianon does this commit close this request or something slightly different ? regards, |
No, it does not. |
@petrus-v no, that commit does something slightly different, but it does IMO clarify the reason for our choice -- |
In case it helps anybody else, I've modified what I use for #175 (comment) mostly because I use a windows host and a semi-recent change stopped sourcing the file all the time if it's executable. Nothing major, just copied the |
I'd still argue that it's a security risk to run as a db superuser out of the box. |
Sure, but no matter what we do, postgres will create a super user.
|
Sorry for ressurecting an old thread, but since no-one pointed out the obvious I thought i'd add this: even though you are not exposing your database connection to the world, you don't want your web app to have superuser access. If your web app has a sql injection vulnerability, it might be possible to indirectly execute nasty commands on your postgresql server from the web. And if your web app has superuser access, it is even possible to mess with the containerized filesystem or possibly even get code executed (as the user that postgres is running as or root even). It would not be the first time this is how sensitive data ends up in the public. Security is an in-depth matter: every chain in the link needs to be strong, just one weak link can be exploited for fun & profit. We've created our own postgres container based on this one, that has additional variables to initialize a non-superuser account for use by the application. I sleep better at night knowing that my web app has no superuser access :) |
@quantumkoen 👍 and also do you have a link to your version of the Dockerfile? |
@embray sadly it's in a private repo, and open-sourcing anything here involves a lot of red-tape. But it's just two files and rather trivial: Dockerfile:
docker-entrypoint-initdb.d/init-user-db.sh
It adds two variables: Oh, and it also runs the postgresql daemon as the We may tighten the permissions a bit later on, they're still quite broad for a web app. |
@quantumkoen Thanks for the hints; that's certainly enough to go on. |
@embray actually, according to @oschusler (who created the dockerfile I quoted) the script was heavily inspired by the script on the dockerhub readme. |
Cpt. Obvious here who just wants to note that |
I totally get this, and I'm sure there are requests to add env var configs for all sorts of things. However, this specific use case (wanting to create a non-superuser in addition to the superuser specified by |
Exactly what @shane-axiom said - this is (and very much should be) a common enough use case to justify including environment variables to let us do this in a couple lines in a docker-compose file (for example) vs having to write an entrypoint script every time. |
What if we added something like |
Makes sense to me and would cover a wide range of use cases. |
That could be useful, but I still think there should be an environment variable explicitly for this use case. Ideally almost every time this image is used this environment variable would be used, as it's a significant security benefit and very few apps need superuser access to the database. Therefore, I feel it's certainly worth its own environment variable. I particularly like #175 (comment) 's suggestion we use POSTGRES_SUPERUSER together with POSTGRES_USER to create the nonprivileged user. Doesn't break anybody's existing setups and allows a superuser and an unprivileged user to be created together. |
I'm adding notes to our deployment tools about how using In the meantime, is there any reason not to put together a PR for |
This is so weird to see the lack of one of the most commmon sense and not advanced feature in a docker image of the "most advanced" DB. Considering how well PG configuration is designed in general, it was a huge surprise for me. |
For lack of a DOCKERDB_INITDB_EXTRA_SQL env var, the suggested approach to override the entrypoint and put the creation of initdb scripts into the Docker command is pretty clever:
Quote management gets nasty etc, but it's possible if you really can't/don't want to template separate initdb files. (Code for demo only, use a hashed password in |
You can also easily adjust that to make it use an environment variable for slightly simpler quoting (and significantly simpler quoting if you're using YAML like in Compose or k8s); (Also using |
Please make the user / database setup in line with the mysql image. Default database owned by superuser is most likely not what most would expect from a service.
The text was updated successfully, but these errors were encountered: