URL encoding of password wrong/incomplete
Hi,
I created a database like this
users:
- name: step-ca
databases:
- stepca
options: 'SUPERUSER'
I got this random password here
Lgrd}oKjF287_nUn6,=s<:O|
The URI in the secret looks like this:
postgresql://step-ca:Lgrd%7DoKjF287_nUn6,=s%3C%3AO%[email protected]:5432/stepca
But my client does not like it:
Error opening database of Type postgresql: error parsing PostgreSQL DSN: cannot parse `postgresql://step-ca:Lgrd%7DoKjF287_nUn6`: failed to parse as URL (parse "postgresql://step-ca:Lgrd%7DoKjF287_nUn6": invalid port ":Lgrd%7DoKjF287_nUn6" after host)
I reconstructed the uri by myself by url encoding the password with another implementation and now got this:
postgresql://step-ca:Lgrd%7DoKjF287_nUn6%2C%3Ds%3C%3AO%[email protected]:5432/stepca
Now my client is happy. So the difference is
Lgrd%7DoKjF287_nUn6,=s%3C%3AO%7C
Lgrd%7DoKjF287_nUn6%2C%3Ds%3C%3AO%7C
Obviously the comma (,) and equal sign (=) should be escaped as well.
We use Go's net/url package to create these, and that's following RFC 3986, which says , and = do not need to be percent-encoded in the user/password portion, but Postgres connection strings deviate from the RFC:
URIs generally follow RFC 3986, except…
The connection URI needs to be encoded with percent-encoding if it includes symbols with special meaning in any of its parts. Here is an example where the equal sign (
=) is replaced with%3Dand the space character with%20…
We should do more here to work correctly with libpq and other clients.
In the meantime, you can set spec.users.password.type to AlphaNumeric to avoid special characters altogether.
@dkrizic does your client accept u/p in the query portion of the URI?
postgresql://master-primary.persistence.svc:5432/stepca?user=step-ca&password=Lgrd%7DoKjF287_nUn6%2C%3Ds%3C%3AO%7C
@dkrizic does your client accept u/p in the query portion of the URI?
postgresql://master-primary.persistence.svc:5432/stepca?user=step-ca&password=Lgrd%7DoKjF287_nUn6%2C%3Ds%3C%3AO%7C
Yes, this connection string works.
My Postgres client is: https://github.com/smallstep Which uses the pox driver for Go to access the database: https://github.com/smallstep/nosql/blob/master/postgresql/postgresql.go The driver itself is here: https://github.com/jackc/pgx
BTW: My workaround is to use the urlencode from terraform: postgresql://step-ca:${urlencode(data.kubernetes_secret.step-ca-password.data.password)}@master-primary.persistence.svc:5432/stepca
(I know, my password is compromised, but it is only a PoC I am working on)