From 06a84e119dd287da9505fb4b1f2c89709247dfcf Mon Sep 17 00:00:00 2001 From: Elrond <28d6302a099e5225b02c4155ac4236e4912603df2ab08dbfc2f4fef08ce598c8@buzz.block.builderlab.xyz> Date: Fri, 16 Oct 2026 10:02:38 -0400 Subject: [PATCH] fix(seed): run psql with -X so psqlrc cannot retarget after the local guard psql -c no longer implies -X, so ~/.psqlrc or PSQLRC (exportable from .env) ran after the guard and could \connect to another host. Pass -X on both the local and Docker psql paths and assert the control invocation carries it. Signed-off-by: Elrond <28d6302a099e5225b02c4155ac4236e4912603df2ab08dbfc2f4fef08ce598c8@buzz.block.builderlab.xyz> --- crates/buzz-db/tests/observability_source.rs | 25 +++++++++++++------- scripts/seed-admin-dashboard.sh | 5 ++-- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/crates/buzz-db/tests/observability_source.rs b/crates/buzz-db/tests/observability_source.rs index 913ae9cad6..60632e75df 100644 --- a/crates/buzz-db/tests/observability_source.rs +++ b/crates/buzz-db/tests/observability_source.rs @@ -2203,7 +2203,11 @@ fn admin_seed_refuses_remote_database_before_invoking_psql() { ) .expect("copy script without developer .env"); let psql = root.join("psql"); - std::fs::write(&psql, "#!/bin/sh\ntouch \"$SEED_PSQL_WITNESS\"\nexit 1\n").expect("stub psql"); + std::fs::write( + &psql, + "#!/bin/sh\nprintf '%s\\n' \"$@\" > \"$SEED_PSQL_WITNESS\"\nexit 1\n", + ) + .expect("stub psql"); std::fs::set_permissions(&psql, std::fs::Permissions::from_mode(0o755)) .expect("executable stub"); let witness = root.join("psql-was-invoked"); @@ -2218,15 +2222,16 @@ fn admin_seed_refuses_remote_database_before_invoking_psql() { .env("SEED_PSQL_WITNESS", &witness) .output() .expect("run local seed guard"); - let invoked = witness.exists(); - if invoked { + let args = std::fs::read_to_string(&witness).ok(); + if args.is_some() { std::fs::remove_file(&witness).expect("clear witness"); } - (output, invoked) + (output, args) }; // Control: a local host with a plain database name reaches psql, so the // refusals below come from the guard rather than an unrunnable fixture. - let (_, control_invoked) = run("localhost", "", "", "buzz"); + // It must also pass -X so a psqlrc cannot \connect after the guard. + let (_, control_args) = run("localhost", "", "", "buzz"); let cases = [ ("remote host", "shared-db.example.invalid", "", "", ""), ("address override", "localhost", "192.0.2.1", "", ""), @@ -2282,11 +2287,15 @@ fn admin_seed_refuses_remote_database_before_invoking_psql() { ), ]; let results = cases.map(|(name, host, address, service, database)| { - let (output, invoked) = run(host, address, service, database); - (name, output, invoked) + let (output, args) = run(host, address, service, database); + (name, output, args.is_some()) }); std::fs::remove_dir_all(root).expect("remove scratch fixture"); - assert!(control_invoked, "plain local target did not reach psql"); + let control_args = control_args.expect("plain local target did not reach psql"); + assert!( + control_args.lines().any(|arg| arg == "-X"), + "psql invoked without -X: {control_args:?}" + ); for (name, output, invoked) in results { assert!(!invoked, "{name} reached psql"); assert!(!output.status.success(), "{name} accepted"); diff --git a/scripts/seed-admin-dashboard.sh b/scripts/seed-admin-dashboard.sh index 38425b4ff6..96fd2fb091 100755 --- a/scripts/seed-admin-dashboard.sh +++ b/scripts/seed-admin-dashboard.sh @@ -38,15 +38,16 @@ if [[ ! "${PGDATABASE}" =~ ^[A-Za-z0-9_-]+$ ]]; then exit 1 fi +# -X skips psqlrc, which runs after this guard and could \connect elsewhere. if command -v psql >/dev/null 2>&1; then run_psql() { - PGPASSWORD="${PGPASSWORD}" psql -h "${PGHOST}" -p "${PGPORT}" \ + PGPASSWORD="${PGPASSWORD}" psql -X -h "${PGHOST}" -p "${PGPORT}" \ -U "${PGUSER}" -d "${PGDATABASE}" "$@" } elif docker exec buzz-postgres psql --version >/dev/null 2>&1; then run_psql() { docker exec -i -e PGPASSWORD="${PGPASSWORD}" buzz-postgres \ - psql -U "${PGUSER}" -d "${PGDATABASE}" "$@" + psql -X -U "${PGUSER}" -d "${PGDATABASE}" "$@" } else echo "error: neither psql nor buzz-postgres docker psql is available" >&2