In views.py in _get_access_token_jwt() it allows embedding the username in the JWT payload:
if request.POST.get('username'):
extra_data['username'] = request.POST.get('username')
This username is then used in authentication.py to figure out who the user is.
But, when using the "Authorization Code" flow, I can't see how the username is verified in views.py to check that it actually is the same as the user who is requesting the access code.
I experimented and I found that I was able to get an access code with user A, but then enter a different user in the POST request to get the token and it just accepted this.
Here is a test case to prove this issue. Add the following code to test_views.py:
def test_get_token_authorization_code_wrong_user(self):
"""
Request an access token using Authorization Code Flow
"""
Application.objects.create(
client_id='user_app_id',
client_secret='user_app_secret',
client_type=Application.CLIENT_CONFIDENTIAL,
authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE,
name='user app',
skip_authorization=True,
redirect_uris='http://localhost:8002/callback',
)
self.client.force_login(self.test_user)
response = self.client.get(reverse("oauth2_provider_jwt:authorize") +
'?response_type=code&client_id=user_app_id')
self.assertEqual(302, response.status_code)
match = re.match(r'http://localhost:8002/callback\?code=(\w+)',
response.url)
self.assertIsNotNone(match)
code = match.group(1)
# To simulate that the token call is normally made unauthenticated
self.client.logout()
data = {
'client_id': 'user_app_id',
'client_secret': 'user_app_secret',
'code': code,
'grant_type': 'authorization_code',
'redirect_uri': 'http://localhost:8002/callback',
'username': 'some_fake_user', # Pass in wrong user
}
response = self.client.post(reverse("oauth2_provider_jwt:token"), data)
self.assertNotEqual(200, response.status_code)
Near the end, we pass in the wrong username. This is bad because this username is baked into the JWT payload.
Hi there,
I think I have found a security problem.
In
views.py
in_get_access_token_jwt()
it allows embedding the username in the JWT payload:This
username
is then used inauthentication.py
to figure out who the user is.But, when using the "Authorization Code" flow, I can't see how the
username
is verified inviews.py
to check that it actually is the same as the user who is requesting the access code.I experimented and I found that I was able to get an access code with user A, but then enter a different user in the POST request to get the token and it just accepted this.
Here is a test case to prove this issue. Add the following code to
test_views.py
:Near the end, we pass in the wrong
username
. This is bad because this username is baked into the JWT payload.