-
Notifications
You must be signed in to change notification settings - Fork 0
If password was encoded, it would double encode. Switched to only enc… #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d75e331
97cea5c
ad8cff7
74aeb21
e9976a5
08c84ae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| from urllib.parse import quote | ||
| from urllib.parse import unquote | ||
|
|
||
|
|
||
| def fix_connection_url(url: str) -> str: | ||
|
|
@@ -10,7 +11,9 @@ def fix_connection_url(url: str) -> str: | |
| user_pass = url[scheme_end:at_pos] | ||
| if ":" in user_pass: | ||
| username, password = user_pass.split(":", 1) | ||
| encoded_password = quote(password, safe="") | ||
| # If password is already encoded, decode it. | ||
| plain_password = unquote(password) | ||
| encoded_password = quote(plain_password, safe="") | ||
| return url[:scheme_end] + username + ":" + encoded_password + url[at_pos:] | ||
|
||
| except Exception as e: | ||
| print(e) | ||
|
Comment on lines
18
to
19
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| import pytest | ||
|
|
||
| from postgres_mcp.utils.url import fix_connection_url | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| "input_url, expected_output", | ||
| [ | ||
| ("postgresql://user:pass?word@localhost:5432/db", "postgresql://user:pass%3Fword@localhost:5432/db"), | ||
| ("postgresql://user:pass%3Fword@localhost:5432/db", "postgresql://user:pass%3Fword@localhost:5432/db"), | ||
|
||
| ("postgresql://user:pass%word@localhost:5432/db", "postgresql://user:pass%25word@localhost:5432/db"), | ||
| ("postgresql://user:?pass%25wo%%rd@localhost:5432/db", "postgresql://user:%3Fpass%25wo%25%25rd@localhost:5432/db"), | ||
| ], | ||
| ) | ||
| def test_fix_connection_url_encoding(input_url: str, expected_output: str) -> None: | ||
| """Verifies that passwords are encoded once and only once.""" | ||
| assert fix_connection_url(input_url) == expected_output | ||
|
Comment on lines
+15
to
+17
|
||
|
|
||
|
|
||
| def test_fix_connection_url_no_mutation(): | ||
| """Ensure a standard safe URL is not changed.""" | ||
| url = "postgresql://readonly:securepassword123@db.example.com:5432/postgres" | ||
| assert fix_connection_url(url) == url | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The unconditional unquote-then-quote approach can cause issues with passwords that legitimately contain percent-encoded sequences. For example, if a password is literally "pass%3Fword" (containing the literal characters %, 3, F), unquoting it would convert it to "pass?word", then quote it back to "pass%3Fword", which would be incorrect.
This approach assumes that any percent-encoding in the password is meant to be decoded, but percent signs could be part of the actual password. The current implementation cannot distinguish between a password that was already URL-encoded versus a password that literally contains percent-encoded sequences as part of its plaintext value.