pgx icon indicating copy to clipboard operation
pgx copied to clipboard

Sensitive Password Exposure in Error Message

Open aviman1109 opened this issue 1 year ago • 1 comments

Describe the bug

When using pgx.Connect with the connection string format "host=%s port=%s user=%s password=%s dbname=%s", if the user field is left empty, the password field is mistakenly interpreted as the user. This leads to the following error:
failed to connect to 'user=password=**** database=***': ****: failed SASL auth: FATAL: password authentication failed for user "password=****" (SQLSTATE 28P01)

In this case, the password is displayed in plain text, which constitutes an unacceptable information disclosure from a security perspective.

To Reproduce

Steps to reproduce the behavior:

  1. Use the following connection string format: "host=%s port=%s user=%s password=%s dbname=%s".
  2. Leave the user field empty, and set a valid password.
  3. Attempt to connect using pgx.Connect.

Example code:

package main

import (
	"context"
	"log"
	"os"

	"github.com/jackc/pgx/v5"
)

func main() {
	connString := "host=localhost port=5432 user= password=secret dbname=mydb"
	conn, err := pgx.Connect(context.Background(), connString)
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close(context.Background())
}

Expected behavior

The connection attempt should fail with a clear error indicating that the user field is empty, without exposing the password in the error message.

Actual behavior

The password field is mistakenly interpreted as the user, resulting in an error that exposes the password in plain text: failed to connect to 'user=password=**** database=***': : failed SASL auth: FATAL: password authentication failed for user "password="

aviman1109 avatar Jan 03 '25 04:01 aviman1109

When using pgx.Connect with the connection string format "host=%s port=%s user=%s password=%s dbname=%s", if the user field is left empty, the password field is mistakenly interpreted as the user.

The resulting connection string is incorrect. It's not a parsing error. This matches PostgreSQL behavior.

From the docs:

To write an empty value, or a value containing spaces, surround it with single quotes

psql has the same behavior.

jack@glados ~/dev/pgx ±master » psql "host=localhost port=5432 user= password=secret dbname=mydb"
psql: error: connection to server at "localhost" (::1), port 5432 failed: FATAL:  role "password=secret" does not exist

jackc avatar Jan 04 '25 01:01 jackc