From 35e80ba69abdbac2f7998c2ee2f4be99d8a055a6 Mon Sep 17 00:00:00 2001 From: Gaurav Sharma <223556219+Copilot@users.noreply.github.com> Date: Tue, 30 Jun 2026 11:45:49 +0530 Subject: [PATCH 1/2] CHORE: align connection string sanitizer with its documented key masking sanitize_connection_string documents masking of the PWD and Password keys, but _SENSITIVE_KEYS only listed pwd, so the password synonym passed through unmasked. add password to _SENSITIVE_KEYS so the implementation matches the docstring, and add regression tests covering password / Password / PASSWORD and a braced value. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- mssql_python/connection_string_parser.py | 2 +- tests/test_007_logging.py | 33 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/mssql_python/connection_string_parser.py b/mssql_python/connection_string_parser.py index cad78180..a9b002bd 100644 --- a/mssql_python/connection_string_parser.py +++ b/mssql_python/connection_string_parser.py @@ -21,7 +21,7 @@ from mssql_python.helpers import sanitize_user_input from mssql_python.logging import logger -_SENSITIVE_KEYS = frozenset({"pwd"}) +_SENSITIVE_KEYS = frozenset({"pwd", "password"}) class _ConnectionStringParser: diff --git a/tests/test_007_logging.py b/tests/test_007_logging.py index ba4fd7b8..a0ec37e0 100644 --- a/tests/test_007_logging.py +++ b/tests/test_007_logging.py @@ -359,6 +359,39 @@ def test_pwd_case_insensitive(self, cleanup_logger): assert "PWD=***" in sanitized assert "secret" not in sanitized + def test_password_synonym_sanitization(self, cleanup_logger): + """The 'password' synonym for PWD should be masked, matching the docstring contract.""" + from mssql_python.helpers import sanitize_connection_string + + conn_str = "Server=localhost;password=secret123;Database=test" + sanitized = sanitize_connection_string(conn_str) + + assert "secret123" not in sanitized + + def test_password_synonym_case_insensitive(self, cleanup_logger): + """password/Password/PASSWORD should all be masked.""" + from mssql_python.helpers import sanitize_connection_string + + test_cases = [ + "Server=localhost;password=secret;Database=test", + "Server=localhost;Password=secret;Database=test", + "Server=localhost;PASSWORD=secret;Database=test", + ] + + for conn_str in test_cases: + sanitized = sanitize_connection_string(conn_str) + assert "secret" not in sanitized + + def test_password_synonym_braced_value_with_semicolon(self, cleanup_logger): + """password with a braced value containing semicolons must be fully masked.""" + from mssql_python.helpers import sanitize_connection_string + + conn_str = "Server=localhost;Password={Top;Secret};Database=test" + sanitized = sanitize_connection_string(conn_str) + + assert "Top" not in sanitized + assert "Secret" not in sanitized + def test_pwd_braced_value_with_semicolon(self, cleanup_logger): """PWD with braced value containing semicolons must be fully masked.""" from mssql_python.helpers import sanitize_connection_string From 0b7f8202646227cd1cdebd7d0bd16bc8ce7c5fed Mon Sep 17 00:00:00 2001 From: Gaurav Sharma <223556219+Copilot@users.noreply.github.com> Date: Tue, 30 Jun 2026 12:23:53 +0530 Subject: [PATCH 2/2] CHORE: strengthen sanitizer password tests to assert masking, not just absence address review feedback: the password synonym tests asserted only that the secret substring was absent, which would also pass under full-redaction fallback. assert password=*** is present and that the output did not fall back to the redacted placeholder. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tests/test_007_logging.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_007_logging.py b/tests/test_007_logging.py index a0ec37e0..e773524b 100644 --- a/tests/test_007_logging.py +++ b/tests/test_007_logging.py @@ -366,7 +366,9 @@ def test_password_synonym_sanitization(self, cleanup_logger): conn_str = "Server=localhost;password=secret123;Database=test" sanitized = sanitize_connection_string(conn_str) + assert "password=***" in sanitized assert "secret123" not in sanitized + assert "redacted" not in sanitized.lower() def test_password_synonym_case_insensitive(self, cleanup_logger): """password/Password/PASSWORD should all be masked.""" @@ -380,7 +382,9 @@ def test_password_synonym_case_insensitive(self, cleanup_logger): for conn_str in test_cases: sanitized = sanitize_connection_string(conn_str) + assert "password=***" in sanitized assert "secret" not in sanitized + assert "redacted" not in sanitized.lower() def test_password_synonym_braced_value_with_semicolon(self, cleanup_logger): """password with a braced value containing semicolons must be fully masked.""" @@ -389,8 +393,10 @@ def test_password_synonym_braced_value_with_semicolon(self, cleanup_logger): conn_str = "Server=localhost;Password={Top;Secret};Database=test" sanitized = sanitize_connection_string(conn_str) + assert "password=***" in sanitized assert "Top" not in sanitized assert "Secret" not in sanitized + assert "redacted" not in sanitized.lower() def test_pwd_braced_value_with_semicolon(self, cleanup_logger): """PWD with braced value containing semicolons must be fully masked."""