Skip to content

fix(security): pin PostgreSQL credential destinations - #580

Open
dviejokfs wants to merge 1 commit into
mainfrom
fix/postgres-credential-transport
Open

fix(security): pin PostgreSQL credential destinations#580
dviejokfs wants to merge 1 commit into
mainfrom
fix/postgres-credential-transport

Conversation

@dviejokfs

Copy link
Copy Markdown
Contributor

Summary

  • resolve PostgreSQL hosts once and pin every approved address with hostaddr across the TLS ladder while preserving the original hostname for certificate verification and SNI
  • replace interpolated cluster-admin connection strings and the ungated NoTls fallback with typed configuration and a private-only credential transport policy
  • treat monitor rows as state only: a primary nodename must uniquely match a persisted running data member, and credential destinations come exclusively from persisted member/node topology
  • document why passwordless monitor probes remain safe with sslmode=require

Security properties

  • DNS rebinding cannot change the destination between private-address authorization and connection
  • both TLS rungs use SslMode::Require; only the explicit pinned private rung can use cleartext
  • managed-cluster credentials are rejected for public addresses before verified TLS is attempted
  • monitor-supplied nodehost and nodeport never authorize a credential destination
  • username, password, database, and host are values in typed tokio_postgres::Config, not connection-string syntax

Independent security-auditor review: APPROVED, with no remaining findings for either issue or the adjacent cluster-health credential path.

Evidence

DNS authorization and dialing use the same pinned addresses

cargo test -p temps-query-postgres connection_config_pins_every_preapproved_address -- --nocapture
cargo test: 1 passed, 71 filtered out (1 suite, 0.00s)

Connection-string injection text remains credential data and TLS stays required

cargo test -p temps-query-postgres connection_config_treats_credentials_as_values_and_requires_tls -- --nocapture
cargo test: 1 passed, 71 filtered out (1 suite, 0.00s)

Managed cluster credentials reject public destinations before connecting

cargo test -p temps-query-postgres private_ladder_rejects_a_public_address_before_connecting -- --nocapture
cargo test: 1 passed, 71 filtered out (1 suite, 0.00s)

Forged monitor identities cannot authorize unstored, monitor, stopped, or ambiguous members

cargo test --lib -p temps-providers monitor_primary_identity_cannot_authorize_an_unstored_endpoint -- --nocapture
cargo test: 1 passed, 456 filtered out (1 suite, 0.00s)

Crate suites

cargo test --lib -p temps-query-postgres
cargo test: 72 passed (1 suite, 0.01s)

cargo test --lib -p temps-providers
cargo test: 457 passed (1 suite, 4.78s)

Build and lint gates

cargo check --lib
cargo build: 0 errors

cargo clippy --lib -p temps-query-postgres -p temps-providers -- -D warnings
cargo clippy: 0 errors

pre-commit cargo clippy --all-targets --all-features -- -D warnings
Passed

Closes #560
Closes #561

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

📓 Changelog preview

This is what your commits will add to the generated CHANGELOG.md at release time (via git-cliff). Do not edit CHANGELOG.md by hand — it is generated from your Conventional Commit messages.

## [Unreleased]

### Fixed

- **security:** Harden postgres credential transport

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.

security: ensure_cluster_app_database sends the cluster admin password in cleartext security: host_is_private is defeated by DNS rebinding (TOCTOU)

1 participant