Django and Web Security Headers

This video features Adam Johnson at DjangoCon Europe 2019 in Copenhagen, Denmark.

Django and Web Security Headers
0:32:13
Published April 23, 2019
2,511 views

Summary

Adam Johnson explains how HTTP security headers let browsers opt into safer behaviour while preserving the web’s backward compatibility. He covers Django’s built-in protections—XSS filtering, HSTS, MIME-sniffing prevention, and clickjacking protection—and shows how third-party packages add Referrer-Policy, Content Security Policy, and the experimental Feature-Policy header. He argues that the built-in settings should generally be enabled, while HSTS and CSP require careful, gradual rollout; he also explains where to set headers, how cookie flags relate, and how reporting tools can reveal violations.

Key takeaways

  • Django’s security middleware can enable XSS filtering, HSTS, MIME-sniffing protection, and clickjacking protection, with deployment checks warning about missing settings.
  • HSTS should be introduced gradually because enabling it for a domain also affects subdomains and can permanently prevent HTTP access in browsers; preload should only be used once the whole domain is ready.
  • Referrer-Policy limits the leakage of sensitive URL information, while Content Security Policy restricts the external scripts, images, and other resources a page may load.
  • CSP is powerful but difficult to add to an established site, so report-only mode can identify legitimate resources before enforcement is enabled.
  • Headers may be set in Django, a reverse proxy, or a CDN, but application-level configuration is useful when policies need to vary between views; cookie flags provide related protections for session and other cookies.

Summarised automatically from the transcript.

Transcript

5,272 words · auto-generated Show

Automatically transcribed, so expect mistakes in names and technical terms.

0:05

Speaker 1: Hello, there we go So security can often be considered a boring topic. In fact, two speakers today have already said that. Marcus made a passing comment to boring security features in his talk. And Nathan put up a list of interesting topics and then said, oh no, two of these aren't interesting. They were the security features. Thankfully, security is really quite easy to put in your Django application. And I'm going to talk through one specific part of security, which is these security headers. But first, briefly about me I'm Adam Johnson. I am one of the Django core team. You can find me at GitHub or Twitter by the username Adam Chains. My email address is me at adamj.

0:50

Speaker 1: eu and that's also my website, adamj. eu. On the 12th of April, I may have to change my domain name because I will no longer be an EU citizen. We'll find out. So what are these web security headers? So the web is a platform with a lot of uh backwards compatibility concerns. Um all the browsers are trying to keep all the websites working for all time. So Timburn is the homepage, the first website still needs to work, and then the latest Hotness with HTTP3 or whatever needs to work as well. As a result of this, a lot of the uh problems we find in the web behavior, um they cannot be instantly changed

1:38

Speaker 1: So there are lots of things where you need to opt in to get the more secure behavior. And there are a bunch of mechanisms that have been used over time, but one that seems to have been settled on is setting headers So your server says in the HTB header, by the way, browser, you need to act like this. And it's quite easy to check these. There's a checker called securityheaders. com. You can point this at a URL, it will tell you which headers are being set and give you a score from F to A plus. This is a great checker, it's by security researcher Scott Helm, who I'll talk about a bit more. There's also one called Mozilla Observatory that will tell you a lot more problems with your website. This one focuses just on headers, so that's why I'm using it here. Here's what yahoo.

2:24

Speaker 1: com scores. So they're getting an A plus. So they're doing extremely well. Here's Google. com scoring a C. So I think this illustrates the first point is that you can be secure without turning these all on, but it's worth knowing about all of them. and choosing which ones to turn on in which situations and maybe putting enough on to get that A plus score, you can impress your boss and say, hey look, we're better than Google. So this is a kind of listicle talk. Everyone loves listicles, so it might make their talk a bit more interesting. These are all the headers. I'm not going to read them out right now because I might stumble. They're quite complicated But we'll go through them one at a time. The first four, Django

3:11

Speaker 1: provides a feature for us to enable in the most secure manner. The last three, we'll install a third-party package to help configure them And I'll explain them one by one. So, XSS protection. Try saying that ten times quickly XSS is cross-site scripting. It's not the best name for uh what's happening when this happens. Um It's really a kind of code injection attack. Initially it was, you know, code being included from other sites. Sometimes it can mean code being included from your own site or perhaps one of your other domains And uh this happens when you've got some bad code on your server that allows a user to inject uh their own code.

3:59

Speaker 1: um onto the site perhaps by putting it in the database or by putting it through a URL parameter. So that second one is kind of easy to catch. And because of that, browsers have built in these things called XSS auditors. So the auditor is a little class, a function that's running on every single page request in the browser Each of the browsers have built their own individual ones, but they all work very similarly, and they will try and spot an XSS attack in action. And if they see that, they will say, actually, let's not do that So they're kind of like a guardrail that have been put on the internet. They're not entirely backwards compatible , but they opted for a like

4:45

Speaker 1: midpoint. So if uh an XSS attack happens, I'll show you a demo in a second, they will stop that one request. But if you set this header XXSS protection and give the mode block, you can actually have it block the whole page. And you'd probably want to do this because um If there's one thing going wrong, it might be an indicator that the auditors managed to spot one corner of an attack and there's other things going on on the page, so you don't want to harm your users Here's the demo from that security researcher Scott Helm. You can just Google Scotthelm XXSS protection if you want to try this. So his site has the header set with this mode equals block flag. And then he tells you, try loading this page, but with this different link.

5:33

Speaker 1: And if we inspect the link, you can see it's got a query parameter called foo that includes a script tag. So the XSS auditor will will scan that and see, oh look, there's a script tag on the page and the script tag was in the query parameter. We should probably be not loading that script and because he has the header it gets blocked instead Which looks like this. And so Chrome just says this page isn't working, there's nothing you can do to bypass this. And if we look Like the error message says error blocked by XSS Auditor. So if someone sends you a screenshot, you can kind of figure out what's going on. To activate this in Django, it's quite simple. It's built-in. As with all these built-in ones as well, if you run manage.

6:19

Speaker 1: py check-deploy, you'll get a warning that you haven't enabled it if you haven't. So you simply have the security middleware in your middleware setting. This is done in the default start project template. And then you switch this flag over to true. Secure browser XSS filter equals true. And I would suppose this isn't in the default project template simply because Django projects themselves have to try and be backwards compatible. This is quite an easy one to turn on. The second one, strict transport security. This is a little more complicated. So if you're surfing your site over HTTPS, that's great. That is what we want. It's modern. If you're using HTTP2, the only way to make that work is over HTTPS.

7:08

Speaker 1: Most websites on the internet are HTTPS now, especially most websites being launched. The one problem with doing this is that browsers will automatically ask for HTTP first. And this redirect step is still insecure. So if someone comes to your server, asks for the HTTP mode of the website And you say, no wait, we're HTTPS now, they get a redirect. But that first redirect, if an attacker in the middle managed to serve different content to them, they could say, no, no, our domain is now over here at evil. com. So if you set this header, strict transport security, the first time someone loads your site, the browser remembers the header and says, okay, I'll never talk to you on HTTP

7:54

Speaker 1: again. then in a week or a month, and basically depending upon uh your choice as the website operator, um if they load the page again from a link or by typing into their URL bar, the browser will not make that initial HTTP request. So it's great we can set it in a header, and then there's this bonus of this preload database. And this is a list maintained by Google. that um is loaded into most browsers these days, uh, of all the websites that have not only set strict transport security, but have also said we want to be in this preload list, and that way the browser will never ever make the initial HTTP request. They load the local database built into the browser. So your website can be on this list of the most secure domains. Here's what the preload list looks like.

8:41

Speaker 1: You simply enter in your domain, it has to be your top-level one. So example. com, not subdomain. example. com. And that means that everything within your domain will be loaded by HTTPS only ever by all the browsers, at least the versions that include you in the preload list. Again, very easy to turn on in Django. We have a bunch of checks when you run check-deploy. And the first step you just need to take is to set this secure HSTS seconds. So that's the countdown that says how long the browsers out there of your users should remember to load you over HTTPS only.

9:26

Speaker 1: This needs a lot of care. And a Django warning for one of these says, puts it very nicely, enabling HSCSS carelessly can cause serious irreversible problems. If you set it on your top-level domain and somewhere else in your organization someone is running an application on a subdomain that's HTTP only, you break it for them. Anyone who sees the header on the top-level domain, their browser will only make HTTPS requests from that point onwards, and they can never get to that application on our subdomain. So I recommend you ramp up seconds gradually. Make a deploy with a 30-second timeout, then a minute, then an hour. Do this over a period of days. uh whatever monitoring is appropriate to get feedback from your users.

10:13

Speaker 1: And then these two flags which first push it push you down onto the subdomains. And then this preload flag that allows you to be loaded into that database, only set them when you're really quite sure that your whole domain is set up properly. It's a lot easier to um do this with some TLDs. So Google have released a few um Top level domains recently, dot dot app, dot dev, these are already HSTS preloaded. So if you get one of these domains, you cannot host HTTP content on them. Similarly, if you start at an organization that already has this on their top-level domain, you're never going to have any problems. Okay, the third header. X Content Type Options.

11:00

Speaker 1: So there's another browser feature here at play called MindSniffing. And this is a kind of a patch that is a bit regrettable. In early web browsers, people were browsing the internet, coming across servers which had been misconfigured, so the content type header would be set incorrectly. So the browsers man browser vendor said, Hey look, we can fix these websites. for you and we'll just look at what's inside the um content we download and try and guess what type it is. This backfires and can backfire very badly. For example, if you have a function on your site to upload images and you serve them directly out your domain and The person manages to upload some HTML looking stuff. It doesn't have to be pure HTML.

11:47

Speaker 1: It might be enough to bypass your filters, but then enough to trigger the browser's mind -sniffing filters. So then it gets interpreted as HTML. Suddenly they can it host whatever the content they want on your domain. They could put in a script that steals passwords, etc. So you simply set this header x content type options to this no sniff value and you say, browsers, don't try and sniff the mime type. MIME sniffing, as I said, was a bit different in every browser. It's recently been turned into a spec. I had a brief look at the spec. It is very, very big. You ideally don't want to have to think about this when you're developing a website, so just try opting out instead Again, in Django, we've got a warning telling you, please opt out.

12:35

Speaker 1: You put the security middleware in, you set a flag, and you're sorted. You don't need to think about it again. Now for the fourth one built into Django , this is the click jacking uh attack that you can prevent. I'll demonstrate that briefly. But basically, clickjacking relies on putting your site inside a frame on another site. And putting this header on your site, you say, Browsers, please don't include me in a in a frame on other sites Or you can set an allow list and say only these sites can include me in a frame. Give a trusted list, perhaps those that are within your organization or some partner. So this is the click-jacking attack.

13:21

Speaker 1: I'm going to use uh Troy Hunt's blog post images here. He's another security researcher that has worked on the security headers site. So imagine we have one site called WiniPad. And look, it's a great deal. They're giving away an iPad mini. Okay, the example might be a little dated, but Yeah, and we just need to click that win button and it's ours. Over here we also logged in on a website called My Bank and it's got a transfer page And it simply has two buttons to invest it wisely or donate it all to Kim. com, the one behind Mega. Well, what you didn't realize, and we'll make clear here, is that WiniPad Actually has a framed version

14:07

Speaker 1: of the bank site and it was transparent. So if we just fade it in a little, you can see that the win button is right over the donate the money to Kim. com And this is like a single click, but some websites use like loads of dynamic um things. They make you click all these buttons that you think, oh, that's weird, these buttons are all over the screen. You don't realize you're logging into Google and sending all your money and your password or something. Again, to opt out, it's very simple. You set this header and we again have a middleware in Django to do it. It's called the X-Frame Options middleware. And you change the option to deny. Deny is the most strict version.

14:52

Speaker 1: That means you can never be included in a frame. There are other options where you whitelist particular sites, as I explained. They're all in the documentation. This is quite a complicated topic, so it has its own middleware and its own documentation page compared to the others that were just in the vanilla security middleware. But it is in the start project template and there is a check telling you to go research it. So now we move on to those that are not built into Django, at least not yet. The first is referrer policy. And we need to be a little bit careful there. So every time you click through the web, you're setting that you're passing this referrer header to the next page you navigate to.

15:38

Speaker 1: And that has one R due to a typo in the original spec. So you're basically telling every website you visit where you just came from. This is Uh it sounds perfectly legitimate, especially if you're browsing within the same website. They might want to understand how traffic flows. Do people go from the login page to the user page? Something like that. But and one thing that's become very clear uh across the history of the web is that URIs can leak information. For example, imagine if And I'm not saying this is the case, that there's a webpage on my site called uh Illuminati Funding. I may or may not be funded by the Illuminati, but I definitely don't want to leak that information to the outside world.

16:26

Speaker 1: Other things get into URLs as well. like uh parameters, there might be uh private information of your customers, uh you might have like the email address of someone on a search field, and you don't want this to get to other parties that you might just happen to link to. So this header called referrer policy with two R's in the middle, correctly spelled confusingly, controls who gets the referrer with one R. Got it? So it's quite simple again. We activate it in Django uh by installing a package that provides a middleware It's by another core developer called James Bennett. It's very well documented.

17:12

Speaker 1: It's very straightforward. It's the kind of thing that I'd like to see merged in Django. And you simply set this referral policy to one of the values that are possible according to the spec. The one that you probably want is same origin. So this means that whilst you're browsing around within that one domain, then the referral header is set. So you can understand traffic within your own website. As soon as they click to another domain, it's no longer seen There isn't a way of specifying a whitelist, so it's really kind of all or nothing on your domain or other domains, etc. And this this is the sixth header to talk about, content security policy.

17:58

Speaker 1: So we talked about XSS attacks before, which is including content from other sites. There are a bunch of related attacks and other problems. You might not want to include content from other sites Because it doesn't look good on you or allows some people to change things on you. So it could be images, it could be videos, it could be scripts that we're talking about And content security policy is the strongest way to prevent this whole ranges of attacks. It is a huge topic, and it could be a presentation in itself, or perhaps a book. There are 23 different directives you can set in this policy and a myriad of options for each of those. I'm going to explain just basics.

18:45

Speaker 1: This is an example policy. It's a series of these directives separated by semicolons. This one simply says The default source for resources that our web pages can include is ourselves. That means just the current domain. It wouldn't even allow you to include from like static. example. com. But then we say, but we don't mind including images from anywhere. And we also allow scripts to be included from a domain called userscripts. example. com. So if this is set in the header content-security-policy, um the browser will enforce this. And every single script tag, image tag Anything that could reference external media will first pass through this policy, and if it's not allowed, you get a block message.

19:34

Speaker 1: And here's an example of those block messages. Scott Helmer set this up on his uh CSP demo site. He's tried to put a script tag that includes evil. com slash keylogger. js. And that doesn't sound great. And you get this error in the development console. It's saying, look, this has violated the CSP. It was particularly this directive. And you can see his real-world directive which allows scripts from a large number of um locations , is printed out in full for us. So he's allowing self, discuss. com, discuss CDN, Instagram, etc. things that he he trusts and allows to embed content on his site.

20:21

Speaker 1: So how do we put this into our Django app? Mozilla have a third-party package called Django -csP. We install that, we put the CSP middleware into the middleware, and then we set a bunch of settings to build up the policy. For example, CSP default source is the first one that I described saying the default source, and you might want to start off with this saying self. Again, like like HSTS, the strict transport security, it's quite hard to roll out, especially if you have a big site. If you're starting off with a greenfield project brand new, it's very easy. Just set a very restrictive policy to begin with. And just as you develop the site, you'll find that this feature doesn't work or that feature doesn't work.

21:08

Speaker 1: Inspect the messages, decide whether or not you want to embed content from, say, twitter. com or you want to figure out a solution where you don't depend on them If you've got an existing site, very, very hard because you might have thousands of pages with loads of content editors have worked on for years to include from all different places. And maybe you want to reconsider whether or not you trust all these sites, especially if they're somewhat like Myspace or something that have um gone out of fashion, gone quite old, badly maintained. Here's a resource that will help you start with a very strict policy, if that's what floats your boat, the Google strict CSP page. And one thing worth mentioning that helps with the rollout and with the maintenance of this is the report mode.

21:54

Speaker 1: And there's also report only mode. So the report reporting allows the browser to send you back a request every time they block it blocks something. And report only means that the policy is not enforced, but only ever sends these reports back. So you can roll this out with the report only mode on, get back a bunch of information about what users are seeing that would be blocked. Change the policy and once you stop seeing reports that you think are legitimate, then know that you can turn it on. And the last one I'm going to talk about, which is quite a bonus and is not needed for this A rating, is feature policy. It's also very experimental. So at the moment it's not enabled by default in browsers.

22:41

Speaker 1: Chrome is the browser with the most implementation and they're pushing this. but you still need to enable the experimental flags mode to get it on. And what this does is it lets you disable browser features. So rather than not just like distrusting code being pulled in, it also says I'm not entirely trusting the code that I am running, so let's not do some things that um we don't want to do, sp uh that we shouldn't need to do, rather. For example, for you or for your iframes, for example, autoplay. And I know Firefox just disabled autoplay by default, but this is a policy where you can say nothing on this website should ever autoplay. If you're loading something that autoplays, just don't autoplay it. Similarly, you can block the geo colocation feature.

23:27

Speaker 1: Nothing should be requesting for my user's location. Nothing should be requesting to use the camera. So if bad code ever does get onto your site, it just can't do that much damage. The Chrome team are pushing this, they've got this demo app that you can go visit and browse around if you search for feature policy kitchen sink Here's an example page that blocks autoplay and you can browse around and turn it on and off. And it also shows you what the header looks like. feature policy, autoplay, none or self. Again, like a CSP, you can say I'm allowed to autoplay, but others aren't. The way to turn this on in Django is to install a library I've built called Django Feature Policy, put its middleware in, very familiar, and enable a setting.

24:16

Speaker 1: It is very experimental. I just did an update the other week where Chrome had changed a number of features and the names of them. So if you're going to turn it on, it's just like a treat it as an extra bonus at this time and don't rely on it. And once you've done the first six, uh you get this A plus rating. Hooray It may or may not be worth it for you and uh it's definitely worth knowing about all of these and maybe switching on those that are built into Django, but considering the others depending upon your organization's like a posture CSP is quite hard to roll out. HSTS very hard to roll out in a somewhere that has a lot of existing projects on the same domain.

25:01

Speaker 1: But yeah, hopefully you're now well educated. Thank you for listening to me and you can get my talk at the link at the bottom.

25:16

Speaker 2: Thank you, Adam. This was wonderful. Are there questions? Yes, there's at least one. It is on test.

25:38

Speaker 3: Hi Thank you for the important talk. I'm relaying two questions from the Slack channel. The first is um do you see any upsides or downsides of doing this in Django as opposed to setting those headers in Nginx or a similar front-end web server

25:52

Speaker 1: So the question is whether it's uh better to set them on a different layer to Django. So you could do Nginx, you could do this at your CDN. Um it does depend on your application So you might be gluing together multiple parts on an Nginx setup or a CDN. You might be serving static media through Nginx Although I'd say it's better to use something called White Noise these days that serves them directly out of Django. There are definite benefits to putting it inside the application. For example, with CSP, you might have a restrictive policy at the top domain and then on just a few views, set a less restrictive policy that allows a third-party script to run only on those views. So the dynamic nature can be very useful there. Others that are just like a static flag, perhaps like XSS

26:40

Speaker 1: protection, you might want to put on a top-level thing. But generally if they're built into Django, just switch them on uh to begin with.

26:49

Speaker 3: Okay, thanks. And the other question is do you have any opinions on the defaults that Django does have or Django should have? Once you turn debug to off.

26:59

Speaker 1: Do I have opinions on the defaults? I think a a couple of them could be switched, like XXSS protection, but it's uh really a matter of depending on how much we want to break the backwards compatibility I think more important task is to merge in some of those features that are currently in third-party libraries so everyone gets them by default.

27:20

Speaker 4: Hi. Um I'm a pen tester, so pi when people don't use these kinds of headers, it makes me very happy. And when they're not implemented, um yeah, I ha have a very good day. Um and quite often people don't implement them correctly. But one of the things that I was That that plays into this quite a bit that I was hoping you would talk about a little bit was cookie flags as well because those get set on head that's set for the cookie. And I wondered if you could speak a bit about how cookie flags work in Django because that's something that can interact with these headers as well.

27:57

Speaker 1: Yes. Um so cookie flags are a bunch of Options similar to the headers that let you say this cookie should only be served over HTTPS, this cookie should not be readable by JavaScript, etc. Django has a bunch of these flags on by uh available by default. Some of them may be on by default, and there's certainly warnings when you run the check-deploy command. So they're they're there. We recently merged a patch, I think Maris merged one around language settings as well. So the next version of Django, I guess 3. 0 will have that. Yeah, so that certainly is built in. I just wanted to restrict the scope of the talk. If you run that tool I discussed at a beginning called Mozilla Observatory, that will tell you about the cookie flags as well as the security headers

28:43

Speaker 1: Yeah.

28:44

Speaker 4: And I had a second question because I still have a lot of feelings about this topic.

28:50

Speaker 1: Excellent.

28:50

Speaker 4: And that is that uh CSP is awesome. Uh and it's great and you're right that it's really hard to implement properly. But um I know that one of the things that can make CSP really hard to implement is the fact that a lot of popular Third party JavaScript libraries require you to set insecure CSP defaults. Um so even if your security team says please turn this on if you depend on something, then it won't work. And I was wondering If you knew any libraries that that do this kind of thing that are good to avoid if you're trying to marry your site with CSP.

29:26

Speaker 1: I don't know any off the top of my head. I've certainly experienced them. I'd say it's best to always try and self-host JavaScript, although some partners force you to set it like include it from their domain and just trust that they won't get hacked and their code will be replaced with bad code. Yeah. I can't speak anymore to that, I'm afraid

29:46

Speaker 5: Hello. Nice talk. I was actually wondering in the beginning you mentioned the uh cross-site scripting header. And I thought it was interesting because it seemed to me that instead of trying to protect the user, it was preventing an attack, like when the URL had a script in it yet it's trying to prevent. I was just wondering Can you just go through that or pass that if you use a different browser or is there more to it than that?

30:13

Speaker 1: Certainly all the browsers have slightly different XSS auditors. And the user might get to that page and try loading a different browser. But it's it's it's definitely protecting the user by blocking the page if something like that happens, because it's normally a sign of a very bad vulnerability. And uh there is a reporting mode for that, I believe, as well, so you can also get ping back whenever that happens. So you can discover in real time that it's happening on your site.

30:42

Speaker 5: Okay. Thanks Uh

30:45

Speaker 6: hello. Those features are uh all very important and some of them as you just mentioned are being added uh gradually. Can you say something about which of these features are available in which Django versions?

31:02

Speaker 1: So I believe all the first four I talked about came from security middleware. which was made by Adrienne Horvadi, I think. And that was merged in Django 1. 18. So Hopefully they're accessible to most Django users at this point. If not, you can install the package that they came from called Django-security.

31:24

Speaker 3: One more question from myself. Um you talked about that many of these headers allow to report back if there are any issues. Do you know of any ideally open source self-hostable software to collect and evaluate those reports?

31:41

Speaker 1: So I know of two that are able to do this. One is not open source and it's called report-uri. com. That is by the security researchers I've talked about, Scott Helmer and Troy Hunt. And then there's Sentry, which you can pay for for it's known for its error logging, but they have some reporting features, and that you can self-host it is open source and it is also a Django application.

32:09

Speaker 2: All right, thank you. Adam

32:11

Speaker 1: Thank you very much

Questions this talk answers

What are web security headers, and how can I check which ones my site uses?

Security headers let a server tell browsers to use safer behavior while preserving web compatibility. SecurityHeaders.com checks the headers on a URL and gives a score from F to A+, while Mozilla Observatory reports additional security issues.

Discussed at 1:38

How do I enable XSS protection in Django?

Enable Django’s security middleware and set `SECURE_BROWSER_XSS_FILTER = True`. Django’s `check --deploy` command warns when this protection is not enabled.

Discussed at 6:19

How do I enable HSTS in Django without breaking subdomains?

Set `SECURE_HSTS_SECONDS`, but increase it gradually while monitoring the site. Only enable subdomain coverage and preload after confirming that every relevant subdomain supports HTTPS, because HSTS can make HTTP-only subdomains inaccessible.

Discussed at 8:41

How do I prevent MIME sniffing in Django?

Set the `X-Content-Type-Options` header to `nosniff`. Django’s security middleware supports this, and its deployment checks warn when it is missing.

Discussed at 11:00

How do I prevent clickjacking in Django?

Use Django’s `X-Frame-Options` middleware and set the option to `DENY` for the strictest protection. Other settings can allow framing by selected sites when that is required.

Discussed at 12:35

What Referrer-Policy should I use for a Django site?

A same-origin policy is usually a good choice: referrer information remains available within your own domain but is not sent to other domains. Django can add it through a third-party middleware package.

Discussed at 17:12

How do I roll out a Content Security Policy on an existing Django site?

Use a CSP middleware package and start with a restrictive policy on new projects. For an existing site, use report-only mode to collect violations, adjust the policy based on legitimate reports, and enforce it once the reports are understood.

Discussed at 21:54

What is Feature Policy, and can Django use it?

Feature Policy lets a site disable browser capabilities such as autoplay, geolocation, and camera access, including for iframes. Django can use it through the `django-feature-policy` package, but the speaker describes it as experimental and not something to rely on yet.

Discussed at 22:41

Should security headers be configured in Django or in Nginx or a CDN?

It depends on the application. Application-level configuration is useful when policies vary by view, while static flags can be set at a higher layer; in general, the speaker recommends enabling Django’s built-in protections when available.

Discussed at 25:52

Which Django versions include the built-in security headers?

The first four built-in protections discussed come from Django’s security middleware, which was merged in Django 1.8. Older projects can use the original `django-security` package if needed.

Discussed at 31:02

How can I collect Content Security Policy violation reports?

Report URI is one service for collecting reports, while Sentry also supports security reporting. Sentry is open source, self-hostable, and itself a Django application.

Discussed at 31:21

Presenters

Note: We understand that names change, people change, and bodies change. We respect each individual's journey and privacy. If you have any concerns about a video or need us to remove content, please don't hesitate to contact us. We will handle your request with care and promptly address any issues.

More videos by Adam Johnson

More videos from DjangoCon Europe