Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit d14d4d7

Browse filesBrowse files
author
Jon Wayne Parrott
authored
Fix ID token verification (#87)
1 parent 304ed9f commit d14d4d7
Copy full SHA for d14d4d7

File tree

Expand file treeCollapse file tree

5 files changed

+40
-6
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

5 files changed

+40
-6
lines changed
Open diff view settings
Collapse file

‎packages/google-auth/google/auth/_helpers.py‎

Copy file name to clipboardExpand all lines: packages/google-auth/google/auth/_helpers.py
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
"""Helper functions for commonly used utilities."""
1616

17+
import base64
1718
import calendar
1819
import datetime
1920

@@ -194,3 +195,19 @@ def string_to_scopes(scopes):
194195
return []
195196

196197
return scopes.split(' ')
198+
199+
200+
def padded_urlsafe_b64decode(value):
201+
"""Decodes base64 strings lacking padding characters.
202+
203+
Google infrastructure tends to omit the base64 padding characters.
204+
205+
Args:
206+
value (Union[str, bytes]): The encoded value.
207+
208+
Returns:
209+
bytes: The decoded value
210+
"""
211+
b64string = to_bytes(value)
212+
padded = b64string + b'=' * (-len(b64string) % 4)
213+
return base64.urlsafe_b64decode(padded)
Collapse file

‎packages/google-auth/google/auth/jwt.py‎

Copy file name to clipboardExpand all lines: packages/google-auth/google/auth/jwt.py
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def encode(signer, payload, header=None, key_id=None):
9696

9797
def _decode_jwt_segment(encoded_section):
9898
"""Decodes a single JWT segment."""
99-
section_bytes = base64.urlsafe_b64decode(encoded_section)
99+
section_bytes = _helpers.padded_urlsafe_b64decode(encoded_section)
100100
try:
101101
return json.loads(section_bytes.decode('utf-8'))
102102
except ValueError:
@@ -124,7 +124,7 @@ def _unverified_decode(token):
124124

125125
encoded_header, encoded_payload, signature = token.split(b'.')
126126
signed_section = encoded_header + b'.' + encoded_payload
127-
signature = base64.urlsafe_b64decode(signature)
127+
signature = _helpers.padded_urlsafe_b64decode(signature)
128128

129129
# Parse segments
130130
header = _decode_jwt_segment(encoded_header)
Collapse file

‎packages/google-auth/google/oauth2/id_token.py‎

Copy file name to clipboardExpand all lines: packages/google-auth/google/oauth2/id_token.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def _fetch_certs(request, certs_url):
4747
Mapping[str, str]: A mapping of public key ID to x.509 certificate
4848
data.
4949
"""
50-
response = request('GET', certs_url)
50+
response = request(certs_url, method='GET')
5151

5252
if response.status != http_client.OK:
5353
raise exceptions.TransportError(
Collapse file

‎packages/google-auth/tests/oauth2/test_id_token.py‎

Copy file name to clipboardExpand all lines: packages/google-auth/tests/oauth2/test_id_token.py
+4-3Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import pytest
1919

2020
from google.auth import exceptions
21+
import google.auth.transport
2122
from google.oauth2 import id_token
2223

2324

@@ -28,7 +29,7 @@ def make_request(status, data=None):
2829
if data is not None:
2930
response.data = json.dumps(data).encode('utf-8')
3031

31-
return mock.Mock(return_value=response)
32+
return mock.Mock(return_value=response, spec=google.auth.transport.Request)
3233

3334

3435
def test__fetch_certs_success():
@@ -37,7 +38,7 @@ def test__fetch_certs_success():
3738

3839
returned_certs = id_token._fetch_certs(request, mock.sentinel.cert_url)
3940

40-
request.assert_called_once_with('GET', mock.sentinel.cert_url)
41+
request.assert_called_once_with(mock.sentinel.cert_url, method='GET')
4142
assert returned_certs == certs
4243

4344

@@ -47,7 +48,7 @@ def test__fetch_certs_failure():
4748
with pytest.raises(exceptions.TransportError):
4849
id_token._fetch_certs(request, mock.sentinel.cert_url)
4950

50-
request.assert_called_once_with('GET', mock.sentinel.cert_url)
51+
request.assert_called_once_with(mock.sentinel.cert_url, method='GET')
5152

5253

5354
@mock.patch('google.auth.jwt.decode', autospec=True)
Collapse file

‎packages/google-auth/tests/test__helpers.py‎

Copy file name to clipboardExpand all lines: packages/google-auth/tests/test__helpers.py
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,19 @@ def test_string_to_scopes():
151151

152152
for case, expected in cases:
153153
assert _helpers.string_to_scopes(case) == expected
154+
155+
156+
def test_padded_urlsafe_b64decode():
157+
cases = [
158+
('YQ==', b'a'),
159+
('YQ', b'a'),
160+
('YWE=', b'aa'),
161+
('YWE', b'aa'),
162+
('YWFhYQ==', b'aaaa'),
163+
('YWFhYQ', b'aaaa'),
164+
('YWFhYWE=', b'aaaaa'),
165+
('YWFhYWE', b'aaaaa'),
166+
]
167+
168+
for case, expected in cases:
169+
assert _helpers.padded_urlsafe_b64decode(case) == expected

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.