Propagating X-Frame-Options header to debug view responses on errors

240 views
Skip to first unread message

Ben Dickinson

unread,
Jan 24, 2022, 2:32:41 PM1/24/22
to Django developers (Contributions to Django itself)
Hi all,

I'm one of the maintainers of django-pattern-library, which allows Django templates to be rendered with dummy context provided in static files. These rendered versions of the templates are show in an iframe, which means we have a bit of a niche issue.

There's a bit more context on the Github issue, but in brief:

On Django >= 3.0, if a user has DEBUG = True in their settings, although our template rendering view correctly sets the X-Frame-Options header to "SAMEORIGIN" on responses, if the rendering of the template throws an error and the user doesn't also have X_FRAME_OPTIONS = 'SAMEORIGIN' set in their settings, then the browser will block the debug response from being shown.

The current solution is to instruct users to set X_FRAME_OPTIONS = 'SAMEORIGIN' or looser in their (development) settings, but this seems less than ideal to me.

I was wondering if it would be possible to copy the value of the X-Frame-Options from the view that threw an error to the debug views' responses so that in the case the original response was allowed to be shown in an iframe, the stacktrace could be shown instead without changing the project-wide default of a security heading.

I'd be happy to have a go at this, but from a quick look it's not trivial. Any thoughts about whether this would be desirable or even possible and guidance about how I might start  would be very gratefully received!

Cheers,
Ben

Adam Johnson

unread,
Jan 26, 2022, 2:04:33 PM1/26/22
to Django developers (Contributions to Django itself)
I was wondering if it would be possible to copy the value of the X-Frame-Options from the view that threw an error

The problem here is that, because the view threw an error, there is no response object to copy the X-Frame-Options header from. So there's no way for the middleware to know that the view *would* have set that header.

At least as a workaround, I would suggest you add a middleware to your package to add the header to error responses from your view(s). You might be able to use the process_view and process_exception hooks to detect when your views are called, and if they error. Alternatively your middleware might just set X-Frame-Options for all url's with the prefix your app is installed at.

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/29e4223f-e035-49de-8397-7043a26cae73n%40googlegroups.com.

Ben Dickinson

unread,
Jan 28, 2022, 3:13:02 AM1/28/22
to Django developers (Contributions to Django itself)
Thanks Adam, that makes sense. The middleware is good idea, I hadn't thought of that. I think that's the way to go, at least that way we can keep it scoped to our URLs.

Cheers!

Adam Johnson

unread,
Jan 28, 2022, 3:53:37 AM1/28/22
to django-d...@googlegroups.com
Thinking again: since it’s a debug view, Django could set the most permissive X-Frame-Options header on debug 500 responses. This would help every kind of framed view.

If anyone agrees, we could make a ticket.

Reply all
Reply to author
Forward
0 new messages