openedx.core.djangoapps.cors_csrf package#
Submodules#
openedx.core.djangoapps.cors_csrf.authentication module#
Django Rest Framework Authentication classes for cross-domain end-points.
- class openedx.core.djangoapps.cors_csrf.authentication.SessionAuthenticationCrossDomainCsrf#
Bases:
SessionAuthenticationSession authentication that skips the referer check over secure connections.
Django Rest Framework’s SessionAuthentication class calls Django’s CSRF middleware implementation directly, which bypasses the middleware stack.
This version of SessionAuthentication performs the same workaround as CorsCSRFMiddleware to skip the referer check for whitelisted domains over a secure connection. See cors_csrf.middleware for more information.
Since this subclass overrides only the enforce_csrf() method, it can be mixed in with other SessionAuthentication subclasses.
- enforce_csrf(request)#
Skip the referer check if the cross-domain request is allowed.
openedx.core.djangoapps.cors_csrf.decorators module#
Decorators for cross-domain CSRF.
- openedx.core.djangoapps.cors_csrf.decorators.ensure_csrf_cookie_cross_domain(func)#
View decorator for sending a cross-domain CSRF cookie.
This works like Django’s @ensure_csrf_cookie, but will also set an additional CSRF cookie for use cross-domain.
- Parameters:
func (function) – The view function to decorate.
openedx.core.djangoapps.cors_csrf.helpers module#
Helper methods for CORS and CSRF checks.
- openedx.core.djangoapps.cors_csrf.helpers.is_cross_domain_request_allowed(request)#
Check whether we should allow the cross-domain request.
We allow a cross-domain request only if:
The request is made securely and the referer has “https://” as the protocol.
The referer domain has been whitelisted.
- Parameters:
request (HttpRequest)
- Returns:
bool
- openedx.core.djangoapps.cors_csrf.helpers.skip_cross_domain_referer_check(request)#
Skip the cross-domain CSRF referer check.
Django’s CSRF middleware performs the referer check only when the request is made over a secure connection. To skip the check, we patch request.is_secure() to False.
openedx.core.djangoapps.cors_csrf.middleware module#
Middleware for handling CSRF checks with CORS requests
CSRF and referrer domain checks#
When processing HTTPS requests, the default CSRF middleware checks that the referer domain and protocol is the same as the request’s domain and protocol. This is meant to avoid a type of attack for sites which serve their content with both HTTP and HTTPS, with a man in the middle on the HTTP requests.
This doesn’t work well with CORS requests, which aren’t vulnerable to this attack when the server from which the request is coming uses HTTPS too, as it prevents the man in the middle attack vector.
We thus do the CSRF check of requests coming from an authorized CORS host separately in this middleware, applying the same protections as the default CSRF middleware, but without the referrer check, when both the request and the referer use HTTPS.
- class openedx.core.djangoapps.cors_csrf.middleware.CorsCSRFMiddleware(*args, **kwargs)#
Bases:
CsrfViewMiddleware,MiddlewareMixinMiddleware for handling CSRF checks with CORS requests
- process_view(request, callback, callback_args, callback_kwargs)#
Skip the usual CSRF referer check if this is an allowed cross-domain request.
- class openedx.core.djangoapps.cors_csrf.middleware.CsrfCrossDomainCookieMiddleware(*args, **kwargs)#
Bases:
MiddlewareMixinSet an additional “cross-domain” CSRF cookie.
Usage:
Decorate a view with @ensure_csrf_cookie_cross_domain.
- Set CROSS_DOMAIN_CSRF_COOKIE_NAME and CROSS_DOMAIN_CSRF_COOKIE_DOMAIN
in settings.
Add the domain to CORS_ORIGIN_WHITELIST
Enable FEATURES[‘ENABLE_CROSS_DOMAIN_CSRF_COOKIE’]
- For testing, it is often easier to relax the security checks by setting:
CORS_ALLOW_INSECURE = True
CORS_ORIGIN_ALLOW_ALL = True
- process_response(request, response)#
Set the cross-domain CSRF cookie.
openedx.core.djangoapps.cors_csrf.models module#
Models for cross-domain configuration.
- class openedx.core.djangoapps.cors_csrf.models.XDomainProxyConfiguration(*args, **kwargs)#
Bases:
ConfigurationModelCross-domain proxy configuration.
See openedx.core.djangoapps.cors_csrf.views.xdomain_proxy for an explanation of how this works.
- exception DoesNotExist#
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned#
Bases:
MultipleObjectsReturned
- change_date#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- changed_by#
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- changed_by_id#
- enabled#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- get_next_by_change_date(*, field=<django.db.models.fields.DateTimeField: change_date>, is_next=True, **kwargs)#
- get_previous_by_change_date(*, field=<django.db.models.fields.DateTimeField: change_date>, is_next=False, **kwargs)#
- id#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- whitelist#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
openedx.core.djangoapps.cors_csrf.views module#
Views for enabling cross-domain requests.
- openedx.core.djangoapps.cors_csrf.views.xdomain_proxy(request)#
Serve the xdomain proxy page.
Internet Explorer 9 does not send cookie information with CORS, which means we can’t make cross-domain POST requests that require authentication (for example, from the course details page on the marketing site to the enrollment API to auto-enroll a user in an “honor” track).
The XDomain library [jpillora/xdomain] provides an alternative to using CORS.
The library works as follows:
A static HTML file (“xdomain_proxy.html”) is served from courses.edx.org. The file includes JavaScript and a domain whitelist.
The course details page (on edx.org) creates an invisible iframe that loads the proxy HTML file.
A JS shim library on the course details page intercepts AJAX requests and communicates with JavaScript on the iframed page. The iframed page then proxies the request to the LMS. Since the iframed page is served from courses.edx.org, this is a same-domain request, so all cookies for the domain are sent along with the request.
You can enable this feature and configure the domain whitelist using Django admin.