-
Notifications
You must be signed in to change notification settings - Fork 1.8k
fix(auth): parse hostname for mTLS and PSC endpoint certificate rotat… #18153
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
f11e33d
e863710
c4fc118
07f4549
615ae8b
2eb5fe3
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 |
|---|---|---|
|
|
@@ -21,6 +21,7 @@ | |
| from cryptography.hazmat.primitives import hashes, serialization | ||
| from cryptography.hazmat.primitives.asymmetric import ec | ||
| import pytest # type: ignore | ||
| import urllib3.util | ||
|
|
||
| from google.auth import environment_vars, exceptions | ||
| from google.auth.transport import _mtls_helper | ||
|
|
@@ -1888,3 +1889,80 @@ def test_remove_oserror_ignored( | |
| mock_fh.flush.assert_called_once() | ||
| mock_fsync.assert_called_once() | ||
| mock_remove.assert_called_once_with("/path/to/secret") | ||
|
|
||
|
|
||
| class TestIsMtlsEndpoint(object): | ||
| @pytest.mark.parametrize( | ||
| "url", | ||
| [ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This lacks examples with explicit port numbers (example: https://pubsub.mtls.googleapis.com:443/v1) and queries and fragments (e.g. "https://pubsub.mtls.googleapis.com/v1/projects?pageSize=10#frag")
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added unit test cases in |
||
| "https://mtls.googleapis.com", | ||
| "https://mtls.googleapis.com/", | ||
| "https://mtls.googleapis.com/v1/projects", | ||
| "https://mtls.sandbox.googleapis.com", | ||
| "https://mtls.sandbox.googleapis.com/v1/projects", | ||
| "https://pubsub.mtls.googleapis.com", | ||
| "https://pubsub.mtls.googleapis.com/v1/projects/my-project", | ||
| "https://storage.mtls.sandbox.googleapis.com/b/my-bucket", | ||
| "https://my-service.us-east1.rep.mtls.googleapis.com/v1", | ||
| "https://my-service.us-east1.rep.mtls.sandbox.googleapis.com/v1", | ||
| "https://storage.p.googleapis.com/b/my-bucket", | ||
| "https://my-custom-endpoint.p.googleapis.com/v1", | ||
| "https://my-service.us-east1.p.googleapis.com/v1", | ||
| "HTTP://PUBSUB.MTLS.GOOGLEAPIS.COM/V1", | ||
| b"https://pubsub.mtls.googleapis.com", | ||
| b"https://storage.p.googleapis.com/b/my-bucket", | ||
| urllib3.util.parse_url("https://pubsub.mtls.googleapis.com/v1"), | ||
| urllib3.util.parse_url("https://storage.p.googleapis.com/b/my-bucket"), | ||
| "https://pubsub.mtls.googleapis.com.", | ||
| "https://storage.p.googleapis.com./b/my-bucket", | ||
| "https://mtls.googleapis.com.", | ||
| "https://pubsub.mtls.googleapis.com:443/v1", | ||
| "https://pubsub.mtls.googleapis.com:8443/v1", | ||
| "https://storage.p.googleapis.com:443/b/my-bucket", | ||
| "https://pubsub.mtls.googleapis.com/v1/projects?pageSize=10#frag", | ||
| "https://pubsub.mtls.googleapis.com:443/v1/projects?pageSize=10&filter=foo#frag", | ||
| "https://storage.p.googleapis.com:443/b/my-bucket?param=1#section", | ||
| "https://mtls.googleapis.com:443/", | ||
| "https://p.googleapis.com", | ||
| "https://p.googleapis.com/", | ||
| "https://p.googleapis.com:443/v1", | ||
| "https://p.googleapis.com.", | ||
| ], | ||
| ) | ||
| def test_is_mtls_endpoint_true(self, url): | ||
| assert _mtls_helper.is_mtls_endpoint(url) is True | ||
|
|
||
| @pytest.mark.parametrize( | ||
| "url", | ||
| [ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider adding a bare PSC case (example "https://p.googleapis.com").
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Additionally a case like https://[2001:db8::1]:443/mtls.googleapis.com would be good to demonstrated handling of IPv6 syntax handling
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added "p.googleapis.com" to Added IPv6 test cases (https://[2001:db8::1]:443/mtls.googleapis.com and https://[::1]:8443/mtls.googleapis.com) to confirm that bracketed IPv6 host syntax is handled properly. |
||
| "https://storage.googleapis.com", | ||
| "https://storage.googleapis.com.", | ||
| "https://storage.googleapis.com:443/b/my-bucket", | ||
| "https://storage.googleapis.com:443/bucket/mtls.googleapis.com?pageSize=10#frag", | ||
| "https://storage.googleapis.com/bucket/mtls.googleapis.com", | ||
| "https://[2001:db8::1]:443/mtls.googleapis.com", | ||
| "https://[::1]:8443/mtls.googleapis.com", | ||
| "https://logging.googleapis.com/v2/entries?filter=mtls.googleapis.com", | ||
| "https://logging.googleapis.com/v2/entries?filter=mtls.sandbox.googleapis.com", | ||
| "https://logging.googleapis.com/v2/entries?filter=service.p.googleapis.com", | ||
| "https://example.com/mtls.googleapis.com", | ||
| "https://fake-mtls.googleapis.com.attacker.com/v1", | ||
| "https://fake-p.googleapis.com.attacker.com/v1", | ||
| "http://localhost:8080/", | ||
| "http://localhost:8080/mtls.googleapis.com", | ||
| b"https://storage.googleapis.com", | ||
| b"https://storage.googleapis.com/bucket/mtls.googleapis.com", | ||
| b"\xff\xfeinvalid", | ||
| urllib3.util.parse_url("https://storage.googleapis.com/b/my-bucket"), | ||
| urllib3.util.parse_url( | ||
| "https://storage.googleapis.com/bucket/mtls.googleapis.com" | ||
| ), | ||
| "https://.", | ||
| "", | ||
| None, | ||
| 123, | ||
| "not a url", | ||
| ], | ||
| ) | ||
| def test_is_mtls_endpoint_false(self, url): | ||
| assert _mtls_helper.is_mtls_endpoint(url) is False | ||
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.
In
urllib3, theurlparameter passed tourlopencan be aurllib3.util.Urlobject (or other string-like/URL objects) rather than a plainstrorbytes. Currently, passing aurllib3.util.Urlobject tois_mtls_endpointwill causeurlsplit(url)to raise aTypeError, which is caught and results in returningFalse—even if the object represents a valid mTLS endpoint.To prevent this and ensure robust compatibility with
urllib3's native URL objects, we should check if the input has a.urlattribute (whichurllib3.util.Urlexposes as a property returning the string representation) or fall back to converting it to a string.References
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.
@attharva-24 PTAL
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.
Addressed in the latest commit!
is_mtls_endpointnow checks for.urlonurllib3.util.Url(and other URL objects), supportsbytesinputs with safe UTF-8 decoding, and falls back to string conversion. Added unit tests coveringurllib3.util.Url,bytes, andstrinputs across standard, PSC, and regional mTLS endpoints.