fix: normalize trailing slashes before length check in check_resource_allowed (#2074)
This commit is contained in:
parent
705497a593
commit
be5bb7c4f2
3 changed files with 5 additions and 16 deletions
|
|
@ -493,12 +493,6 @@ class OAuthClientProvider(httpx.Auth):
|
|||
if not prm_resource:
|
||||
return # pragma: no cover
|
||||
default_resource = resource_url_from_server_url(self.context.server_url)
|
||||
# Normalize: Pydantic AnyHttpUrl adds trailing slash to root URLs
|
||||
# (e.g. "https://example.com/") while resource_url_from_server_url may not.
|
||||
if not default_resource.endswith("/"):
|
||||
default_resource += "/"
|
||||
if not prm_resource.endswith("/"):
|
||||
prm_resource += "/"
|
||||
if not check_resource_allowed(requested_resource=default_resource, configured_resource=prm_resource):
|
||||
raise OAuthFlowError(f"Protected resource {prm_resource} does not match expected {default_resource}")
|
||||
|
||||
|
|
|
|||
|
|
@ -51,22 +51,17 @@ def check_resource_allowed(requested_resource: str, configured_resource: str) ->
|
|||
if requested.scheme.lower() != configured.scheme.lower() or requested.netloc.lower() != configured.netloc.lower():
|
||||
return False
|
||||
|
||||
# Handle cases like requested=/foo and configured=/foo/
|
||||
# Normalize trailing slashes before comparison so that
|
||||
# "/foo" and "/foo/" are treated as equivalent.
|
||||
requested_path = requested.path
|
||||
configured_path = configured.path
|
||||
|
||||
# If requested path is shorter, it cannot be a child
|
||||
if len(requested_path) < len(configured_path):
|
||||
return False
|
||||
|
||||
# Check if the requested path starts with the configured path
|
||||
# Ensure both paths end with / for proper comparison
|
||||
# This ensures that paths like "/api123" don't incorrectly match "/api"
|
||||
if not requested_path.endswith("/"):
|
||||
requested_path += "/"
|
||||
if not configured_path.endswith("/"):
|
||||
configured_path += "/"
|
||||
|
||||
# Check hierarchical match: requested must start with configured path.
|
||||
# The trailing-slash normalization ensures "/api123/" won't match "/api/".
|
||||
return requested_path.startswith(configured_path)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ def test_check_resource_allowed_trailing_slash_handling():
|
|||
"""Trailing slashes should be handled correctly."""
|
||||
# With and without trailing slashes
|
||||
assert check_resource_allowed("https://example.com/api/", "https://example.com/api") is True
|
||||
assert check_resource_allowed("https://example.com/api", "https://example.com/api/") is False
|
||||
assert check_resource_allowed("https://example.com/api", "https://example.com/api/") is True
|
||||
assert check_resource_allowed("https://example.com/api/v1", "https://example.com/api") is True
|
||||
assert check_resource_allowed("https://example.com/api/v1", "https://example.com/api/") is True
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue