postgres-operator icon indicating copy to clipboard operation
postgres-operator copied to clipboard

URL encoding of password wrong/incomplete

Open dkrizic opened this issue 3 months ago • 4 comments

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.

dkrizic avatar Sep 15 '25 11:09 dkrizic

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 %3D and 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.

cbandy avatar Sep 16 '25 17:09 cbandy

@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

cbandy avatar Sep 16 '25 20:09 cbandy

@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

dkrizic avatar Sep 16 '25 22:09 dkrizic

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)

dkrizic avatar Sep 16 '25 22:09 dkrizic