Skip to content

Fix _cast_urlstr to use unquote vs unquote_plus #357

@KyleKaniecki

Description

@KyleKaniecki

Currently, Env.db_url_config uses _cast_urlstr to url unquote the username and password from database connection URIs. The underlying problem occurs when you try to use a + in your postgres password.

_cast_urlstr uses unquote_plus, (introduced in this PR here), which which will turn plus signs into spaces when unquoted. This is undesired, as plus signs should only be replaced for spaces in HTML form values that are URL encoded, not in connection URIs.

Unquote docs
unquote vs unquote_plus

This bug was discovered when using CrunchyData's PGO on kubernetes. The PGO autogenerates postgres URIs for users and stores them inside of a kubernetes secret. An example URI is shown below:

postgresql://myuser:Le-%7BFsIaYnaQw%7Da2B%2F%5BV8bS+@postgres-pgbouncer.postgres-operator.svc:5432/mydb

Using the different unquotes to decode the password:

>>> unquote('Le-%7BFsIaYnaQw%7Da2B%2F%5BV8bS+')
'Le-{FsIaYnaQw}a2B/[V8bS+'

>>> unquote_plus('Le-%7BFsIaYnaQw%7Da2B%2F%5BV8bS+')
'Le-{FsIaYnaQw}a2B/[V8bS '

The first one can be used to sign into the database using both psql and psycopg2.connect, while the second gives an auth error.

I ran the test suite for django-environ using both unquote_plus and unquote and all tests passed, regardless of which implementation is used, so I believe moving to unquote shouldn't be a huge change. I'll open a PR with changes and link them to this issue.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions