From 212fd7c653e48e9aa96bec49afb12daa544b5dbc Mon Sep 17 00:00:00 2001 From: logbie Date: Thu, 16 Jul 2026 11:02:27 -0500 Subject: [PATCH] Stop echoing unsupported database URLs --- CHANGELOG.md | 2 ++ src/interpreter/database.rs | 22 +++++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 061ce563..c05dadda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] ### Security +- Unsupported database URL errors no longer echo the full connection URL, + preventing embedded credentials from being disclosed in diagnostics. - **Subprocess policy is enforced on every process launch** (shell path and direct-exec / `with arguments` path). Previously, `shell_execution_mode` and related checks ran only when the engine believed a shell was required, so diff --git a/src/interpreter/database.rs b/src/interpreter/database.rs index 8d96fc60..482feed9 100644 --- a/src/interpreter/database.rs +++ b/src/interpreter/database.rs @@ -123,9 +123,10 @@ pub async fn connect(url: &str) -> Result { .map(DbPool::MySql) .map_err(|e| format!("Failed to connect to MariaDB/MySQL database: {e}")) } else { - Err(format!( - "Unsupported database URL '{url}'. Supported schemes: sqlite://, postgres://, postgresql://, mysql://, mariadb://" - )) + Err( + "Unsupported database URL scheme. Supported schemes: sqlite://, postgres://, postgresql://, mysql://, mariadb://" + .to_string(), + ) } } @@ -419,6 +420,21 @@ row_to_value!(mysql_row_to_value, MySqlRow, mysql_int); mod tests { use super::*; + #[tokio::test] + async fn unsupported_database_url_does_not_echo_credentials() { + const SECRET: &str = "WFL_TEST_SECRET_unsupported_password_d5e0ec"; + let url = format!("oracle://wfl:{SECRET}@database.example/app"); + + let error = match connect(&url).await { + Ok(_) => panic!("unsupported database URL unexpectedly connected"), + Err(error) => error, + }; + + assert!(error.contains("Unsupported database URL scheme")); + assert!(!error.contains(SECRET)); + assert!(!error.contains(url.as_str())); + } + #[test] fn whole_numbers_bind_as_integers() { assert!(matches!(