PYTHON-4463 Disallow comma character in authMechanismProperties connection string value (#1646)

This commit is contained in:
Steven Silvester 2024-06-05 14:39:00 -05:00 committed by GitHub
parent 42d30b31ac
commit e9c86f4c00
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 48 additions and 16 deletions

View File

@ -454,8 +454,11 @@ def validate_auth_mechanism_properties(option: str, value: Any) -> dict[str, Uni
return props
value = validate_string(option, value)
value = unquote_plus(value)
for opt in value.split(","):
key, _, val = opt.partition(":")
if not val:
raise ValueError("Malformed auth mechanism properties")
if key not in _MECHANISM_PROPS:
# Try not to leak the token.
if "AWS_SESSION_TOKEN" in key:
@ -473,7 +476,7 @@ def validate_auth_mechanism_properties(option: str, value: Any) -> dict[str, Uni
if key == "CANONICALIZE_HOST_NAME":
props[key] = validate_boolean_or_string(key, val)
else:
props[key] = unquote_plus(val)
props[key] = val
return props

View File

@ -494,16 +494,11 @@ def parse_uri(
collection = None
options = _CaseInsensitiveDictionary()
host_part, _, path_part = scheme_free.partition("/")
if not host_part:
host_part = path_part
path_part = ""
if path_part:
dbase, _, opts = path_part.partition("?")
host_plus_db_part, _, opts = scheme_free.partition("?")
if "/" in host_plus_db_part:
host_part, _, dbase = host_plus_db_part.partition("/")
else:
# There was no slash in scheme_free, check for a sole "?".
host_part, _, opts = host_part.partition("?")
host_part = host_plus_db_part
if dbase:
dbase = unquote_plus(dbase)

View File

@ -559,7 +559,7 @@
},
{
"description": "should handle a complicated url-encoded TOKEN_RESOURCE (MONGODB-OIDC)",
"uri": "mongodb://user@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:abc%2Cd%25ef%3Ag%26hi",
"uri": "mongodb://user@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:abcd%25ef%3Ag%26hi",
"valid": true,
"credential": {
"username": "user",
@ -568,7 +568,7 @@
"mechanism": "MONGODB-OIDC",
"mechanism_properties": {
"ENVIRONMENT": "azure",
"TOKEN_RESOURCE": "abc,d%ef:g&hi"
"TOKEN_RESOURCE": "abcd%ef:g&hi"
}
}
},

View File

@ -37,6 +37,25 @@
"options": {
"tls": true
}
},
{
"description": "Colon in a key value pair",
"uri": "mongodb://example.com?authMechanismProperties=TOKEN_RESOURCE:mongodb://test-cluster",
"valid": true,
"warning": false,
"hosts": [
{
"type": "hostname",
"host": "example.com",
"port": null
}
],
"auth": null,
"options": {
"authmechanismProperties": {
"TOKEN_RESOURCE": "mongodb://test-cluster"
}
}
}
]
}

View File

@ -93,6 +93,21 @@
],
"auth": null,
"options": null
},
{
"description": "Comma in a key value pair causes a warning",
"uri": "mongodb://example.com?authMechanismProperties=TOKEN_RESOURCE:mongodb://host1%2Chost2",
"valid": true,
"warning": true,
"hosts": [
{
"type": "hostname",
"host": "example.com",
"port": null
}
],
"auth": null,
"options": null
}
]
}

View File

@ -474,9 +474,9 @@ class TestURI(unittest.TestCase):
res = {"tls": True, "appname": "myapp"}
self.assertEqual(res, parse_uri(uri)["options"])
def test_unquote_after_parsing(self):
quoted_val = "val%21%40%23%24%25%5E%26%2A%28%29_%2B%2C%3A+etc"
unquoted_val = "val!@#$%^&*()_+,: etc"
def test_unquote_during_parsing(self):
quoted_val = "val%21%40%23%24%25%5E%26%2A%28%29_%2B%3A+etc"
unquoted_val = "val!@#$%^&*()_+: etc"
uri = (
"mongodb://user:password@localhost/?authMechanism=MONGODB-AWS"
"&authMechanismProperties=AWS_SESSION_TOKEN:" + quoted_val
@ -511,7 +511,7 @@ class TestURI(unittest.TestCase):
)
with self.assertRaisesRegex(
ValueError,
"auth mechanism properties must be key:value pairs like AWS_SESSION_TOKEN:<token>",
"Malformed auth mechanism properties",
):
parse_uri(uri)