Context
XBlocks have enabled JWT authentication via its own custom code here:
|
# In this case, we are using Session based authentication, so we need to check CSRF token. |
|
if request.user.is_authenticated: |
|
error = CsrfViewMiddleware(get_response=lambda request: None).process_view(request, None, (), {}) |
|
if error: |
|
return error |
|
|
|
# We are reusing DRF logic to provide support for JWT and Oauth2. We abandoned the idea of using DRF view here |
|
# to avoid introducing backwards-incompatible changes. |
|
# You can see https://github.com/openedx/XBlock/pull/383 for more details. |
|
else: |
|
authentication_classes = (JwtAuthentication, BearerAuthenticationAllowInactiveUser) |
|
authenticators = [auth() for auth in authentication_classes] |
|
|
|
for authenticator in authenticators: |
|
try: |
|
user_auth_tuple = authenticator.authenticate(request) |
|
except APIException: |
|
log.exception( |
|
"XBlock handler %r failed to authenticate with %s", handler, authenticator.__class__.__name__ |
|
) |
|
else: |
|
if user_auth_tuple is not None: |
|
request.user, _ = user_auth_tuple |
|
break |
This code does not respect JWT scopes, and someone with a JWT with more limited scopes could call this endpoint when they are not supposed to.
Our JWT scope code is somewhat brittle. It relies on this middleware code to add a scope related permission class if no other scope related permission class is found. It then relies on DRF permissions to enforce this permission.
A solution might be to have custom code that makes use of that permission as well.
Ideally, our auth code (which is quite complex) would all live in edx-drf-extensions and this custom code for enabling JWT authentication (or DRF Authentication and permissions) on a Django request, would live with the rest of the other auth code so individual services don't implement custom solutions.
Aside: this custom code happened to cause an unexpected bug because it is authenticating using a Django request object, rather than a DRF request object.
Impact
Someone with a JWT with more limited scopes could call this endpoint when they are not supposed to.
Patches
Has the problem been patched? What versions should users upgrade to?
Workarounds
Is there a way for users to fix or remediate the vulnerability without upgrading?
References
|
# In this case, we are using Session based authentication, so we need to check CSRF token. |
|
if request.user.is_authenticated: |
|
error = CsrfViewMiddleware(get_response=lambda request: None).process_view(request, None, (), {}) |
|
if error: |
|
return error |
|
|
|
# We are reusing DRF logic to provide support for JWT and Oauth2. We abandoned the idea of using DRF view here |
|
# to avoid introducing backwards-incompatible changes. |
|
# You can see https://github.com/openedx/XBlock/pull/383 for more details. |
|
else: |
|
authentication_classes = (JwtAuthentication, BearerAuthenticationAllowInactiveUser) |
|
authenticators = [auth() for auth in authentication_classes] |
|
|
|
for authenticator in authenticators: |
|
try: |
|
user_auth_tuple = authenticator.authenticate(request) |
|
except APIException: |
|
log.exception( |
|
"XBlock handler %r failed to authenticate with %s", handler, authenticator.__class__.__name__ |
|
) |
|
else: |
|
if user_auth_tuple is not None: |
|
request.user, _ = user_auth_tuple |
|
break |
Context
XBlocks have enabled JWT authentication via its own custom code here:
edx-platform/lms/djangoapps/courseware/block_render.py
Lines 752 to 775 in 0b3e4d7
This code does not respect JWT scopes, and someone with a JWT with more limited scopes could call this endpoint when they are not supposed to.
Our JWT scope code is somewhat brittle. It relies on this middleware code to add a scope related permission class if no other scope related permission class is found. It then relies on DRF permissions to enforce this permission.
A solution might be to have custom code that makes use of that permission as well.
Ideally, our auth code (which is quite complex) would all live in edx-drf-extensions and this custom code for enabling JWT authentication (or DRF Authentication and permissions) on a Django request, would live with the rest of the other auth code so individual services don't implement custom solutions.
Aside: this custom code happened to cause an unexpected bug because it is authenticating using a Django request object, rather than a DRF request object.
Impact
Someone with a JWT with more limited scopes could call this endpoint when they are not supposed to.
Patches
Has the problem been patched? What versions should users upgrade to?
Workarounds
Is there a way for users to fix or remediate the vulnerability without upgrading?
References
edx-platform/lms/djangoapps/courseware/block_render.py
Lines 752 to 775 in 0b3e4d7