Kolibri: Use CSP middleware to block online sources in DEBUG mode

Created on 8 Feb 2017  路  7Comments  路  Source: learningequality/kolibri

Summary

With KA Lite, we debugged some issues fetching online sources with JavaScript.

During this process, I had a theory that external content (fetched from our update/content server) was blocked due to inadequate security definitions. This wasn't true, however a CSP middleware came out of it.

I made it so it only triggers in DEBUG=True mode. The advantage is that we can ensure that ALL resources fetched from online sources etc. are blocked while we are developing. Or explicitly allowed. That way, we can ensure that we don't accidentally fetch an online source during testing or development that won't actually be available in an offline context.

class CSPMiddleware:
    """
    Implements the Content-Security-Policy response header, which
    conforming user-agents can use to restrict the permitted sources
    of various content.
    See http://www.w3.org/TR/CSP/
    """

    def process_response(self, request, response):

        # Check for debug view
        status_code = response.status_code
        if not settings.DEBUG or status_code in (403, 404, 500):
            return response

        header = 'Content-Security-Policy'
        if getattr(settings, 'CSP_REPORT_ONLY', False):
            header += '-Report-Only'

        response[header] = "default-src 'self' 'unsafe-eval' 'unsafe-inline' data: *.learningequality.org; img-src data: *; script-src 'self' *.learningequality.org 'unsafe-eval' 'unsafe-inline'"
        return response

How to reproduce

  1. Use an external JS library that has an online-dependent behavior
  2. Don't notice it during development or testing
  3. Be baffled when stuff breaks offline.

Real-life consequences (anything community should be aware of, for instance how it affects your deployment)

I think the threat is real, as we don't necessary profile the networking behavior of all client-side browser scripts.

tech update / debt

Most helpful comment

we could also block eval and inline if we want to be even more strict

Would be interesting to see whether this is transitive into sandboxed iframes. We probably wouldn't want to prevent them from doing inline JS or whatever they want (within the confines of the sandbox specifications), but we similarly would want to prevent them from trying to load online resources, as described in the initial proposal above.

All 7 comments

Btw. we could also block eval and inline if we want to be even more strict. There could be a security policy in the future or in school environments that increases what JS can and cannot do.

Very cool! A perhaps marginally more efficient way to have it only run in development is to have it only added to MIDDLEWARE in the dev settings module.

we could also block eval and inline if we want to be even more strict

Would be interesting to see whether this is transitive into sandboxed iframes. We probably wouldn't want to prevent them from doing inline JS or whatever they want (within the confines of the sandbox specifications), but we similarly would want to prevent them from trying to load online resources, as described in the initial proposal above.

Very cool! A perhaps marginally more efficient way to have it only run in development is to have it only added to MIDDLEWARE in the dev settings module.

Yup, could also be a double-safety mechanism. We shouldn't put CSP into production before being very sure of its effects. https://www.troyhunt.com/how-to-break-your-site-with-content/

Is this user-security-related, meant to prevent uncaught bugs, or both?

All our dependencies are bundled with webpack so I don't think we're at risk of inadvertently depending on online behaviors. However if there are security benefits this could still be valuable.

@indirectlylit This is mainly meant to prevent uncaught bugs.

For our online demos and other online applications of Kolibri (which are hard to rule out), it is indeed security related.

I've seen third-party JS adding online assets.

A supplemental approach can be Zulip's test suite that prohibits remote connections during tests:

https://zulip.readthedocs.io/en/latest/testing/testing.html#internet-access-inside-test-suites

Was this page helpful?
0 / 5 - 0 ratings