Skip to content

fix: redact DSN passwords from connection error messages and label the failing side - #78

Open
Apakottur wants to merge 1 commit into
mainfrom
feat/redact-dsn-password
Open

fix: redact DSN passwords from connection error messages and label the failing side#78
Apakottur wants to merge 1 commit into
mainfrom
feat/redact-dsn-password

Conversation

@Apakottur

@Apakottur Apakottur commented Jul 13, 2026

Copy link
Copy Markdown
Owner

What

Scrub passwords from connection error messages. libpq echoes the raw connection string — password included — when a DSN fails URI parsing and falls back to keyword=value parsing; pgmig wrapped that text verbatim into the user-facing error, leaking the password to stderr and to library users' logs. Errors now also say which side (source/target) failed, so the redacted message stays actionable.

Behavior

Before:

Could not connect to database: missing "=" after "user:secretpw@localhost:5432/db" in connection info string

After:

Could not connect to source database: missing "=" after "user:***@localhost:5432/db" in connection info string

Notes

  • Scrub-by-value: password candidates are extracted from the raw DSN (URI userinfo, with or without the postgresql:// scheme, and password=... keyword form incl. quoted values) and replaced with *** wherever they appear in the wrapped error text. This covers any fragment libpq chooses to echo, and applies to all wrapped connect errors (auth/network too) as defense in depth, even though today only parse errors echo the DSN.
  • Host, user, database and port stay visible for diagnosis, matching SQLAlchemy/psql practice.
  • Redaction sits in DbConnection.connect, the single place a DSN is handed to the driver, so every connection path is covered. label is threaded agenerate -> introspect_db -> DbReadOnlyConnection.connect -> DbConnection.connect.
  • label is a required parameter rather than an optional one: an optional label needs an if label branch whose unlabeled-failure arm nothing exercises, which would fail the 100% coverage gate. The cost is mechanical label= additions at the test call sites.
  • All touched APIs are private (_db, _introspect._engine, _redact), so this is not a public-facing signature change.
  • Rebased onto current main — the original branch predated the async introspection refactor, so the change is reapplied against DbConnection rather than the since-removed build_db_info.

libpq echoes the raw connection string (password included) when a DSN
fails URI parsing and falls back to keyword/value parsing. Scrub any
password found in the DSN from the wrapped error text, and label which
side (source/target) failed so the redacted message stays actionable.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PVv1LWaK7pBKshBE18DJzv
@Apakottur
Apakottur force-pushed the feat/redact-dsn-password branch from 343b464 to 85e243d Compare July 29, 2026 11:32
@Apakottur Apakottur changed the title fix: redact DSN passwords from connection error messages fix: redact DSN passwords from connection error messages and label the failing side Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant