#33180: Debug 500 HTML broken with strict Content-Security-Policy (CSP)
-------------------------------------------+------------------------
               Reporter:  Adam Johnson     |          Owner:  (none)
                   Type:  Bug              |         Status:  new
              Component:  Error reporting  |        Version:  dev
               Severity:  Normal           |       Keywords:
           Triage Stage:  Unreviewed       |      Has patch:  0
    Needs documentation:  0                |    Needs tests:  0
Patch needs improvement:  0                |  Easy pickings:  0
                  UI/UX:  0                |
-------------------------------------------+------------------------
 When using a strict CSP header, the debug view is broken as the inline CSS
 and JS get blocked by the browser. The page is somewhat usable as all the
 text is all visible, but it isn't particularly friendly or necessarily
 obvious why it's broken.

 For example:

 I thought of a couple of potential fixes:

 1. Make the debug http response a special class that deletes any CSP
 header added to it. This would work for most cases but not if the CSP
 header is added outside of Django (WSGI middleware, a server wrapping
 runserver).
 2. Move the CSS and JS to separate URL's so they're compatible with CSP.
 They could be served by a special route/path in `runserver`.

 I am personally leaning towards #2 - even though it's more complex, it is
 more general.

 There's also some opportunity to modernize the CSS and JS in the debug
 page a bit, such as rewriting use of window.onload and onclick handlers.

 To reproduce, you can save the below as `app.py` and run `python app.py
 runserver`:

 {{{
 import sys

 from django.conf import settings
 from django.urls import path

 settings.configure(
     DEBUG=True,
     ROOT_URLCONF=__name__,
     SECRET_KEY="django-insecure-
 r42jn$xf4g+=w@=l#m6ghqo0!$icww-h4+$5gojq(1ld$x%!6f",
     MIDDLEWARE=[f"{__name__}.CSPMiddleware"],
 )


 class CSPMiddleware:
     def __init__(self, get_response):
         self.get_response = get_response

     def __call__(self, request):
         response = self.get_response(request)
         response[
             "Content-Security-Policy"
         ] = "object-src 'none'; base-uri 'none'; default-src 'self';"
         return response


 def index(request):
     1 / 0


 urlpatterns = [path("", index)]

 if __name__ == "__main__":
     from django.core.management import execute_from_command_line

     execute_from_command_line(sys.argv)
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/33180>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/053.2e7c709237d5a6140ff8dc6a8430b282%40djangoproject.com.

Reply via email to