A Pentester's Thoughts on Django Security - Pascal Uter

This video features Pascal Uter at DjangoCon Europe 2020 in Online.

A Pentester's Thoughts on Django Security - Pascal Uter
0:34:40
Published September 30, 2020
570 views

DjangoCon Europe 2020 (Virtual)
September 18, 2020 - 15h50 (GMT+1)

“A Pentester's Thoughts on Django Security” by Pascal Uter

Django can make you feel like you are in security heaven and yet there are some pitfalls to avoid. In this talk, I want to praise Django design choices, give an overview of Django's security features and their limitations and conclude with some general security best practices to keep in mind.

Summary

Pascal Uter argues that Django is reassuringly secure because its history consistently favors security over developer convenience: secure template escaping, CSRF protection, safer defaults for cookies and headers, password validation, safer session serialization, and careful fixes such as removing password-reset tokens from referrers. He explains where Django’s protections stop, including unsafe template contexts, URLs and JavaScript data, third-party libraries such as DataTables, unsafe state-changing GET requests, and raw SQL or ORM misuse. He recommends treating all client input as hostile, using secure failure defaults, inspecting requests with an intercepting proxy, keeping dependencies and TLS settings current, setting security headers, and evaluating Content Security Policy carefully.

Key takeaways

  • Django’s security culture is visible in design choices that accept extra developer friction to provide safer defaults.
  • Automatic escaping does not prevent every XSS issue; developers must handle attributes, URLs, JavaScript data, and third-party libraries carefully.
  • CSRF protection should remain enabled, and state-changing actions should never be placed in safe methods such as GET.
  • The Django ORM provides strong SQL-injection protection, but raw SQL helpers and careless user-controlled query parameters can reintroduce risk.
  • Developers should use intercepting proxies, test TLS and response headers, keep software updated, and design features to fail securely.
  • Content Security Policy is useful as a second line of defense, but third-party dependencies can make a strong policy difficult to deploy.

Summarised automatically from the transcript.

Transcript

5,273 words · auto-generated Show

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

0:05

Speaker 1: Hello everyone. I am Really happy to be here. My name is Pascal Ute. I'm a physicist. I work as a pen tester by day and a Django developer by night. As a pen tester, I see a lot of web applications written in a lot of different frameworks. Unfortunately in the enterprise world, very few uh Django written apps, I think. And um yeah, as a developer, I only worked with Django so far and ever since I started in um 2018. I um Never stop being amazed um by how much um focus

0:50

Speaker 1: Django puts on security. Just uh Um let me check that I'm not missing anything here. Yeah, it seems to be alright. Okay, cool. So um yeah. In this talk, I mainly want to share with you why um I like Django so much for its security focus. And first of all, I would like to point it out in the history of Django going through different changes in different versions and pointing out why I like those changes. Then I would like to point out a few Django security features and the limitations. So something for you to take away where you should be aware of. And then in the end, I would like to share a few general best practices. All right. If you open the Django Project. com

1:35

Speaker 1: website already above the fold, you can read that Django is reassuringly secure. That is nice to read, but this claim you already can find in a lot of places. And actually to me, Django is reassuringly secure. And now let's um have a look why So I think Django went off with a good start in version 1. 0 already with the automatic escaping of template variables. So an anti-crossed anti-crosset scripting measure. Which um I think is a good start. Then um the first change I want to point out is in Django version one two five, um when they made um when they got rid of the exception in the CSRF framework for HX requests.

2:20

Speaker 1: I don't want to get into the specifics why it was a good idea to do so. What I do like is the um reason they gave to do so. So basically they explained why they did it and then they said um the security risks have been judged to outweigh the compatibility concerns in this case. And um while in this case I agree with them, I um think it's really nice um to see throughout the history of Django that as I feel almost whenever there was uh To make a judgment between security and compatibility, they chose security. And that I really like. That's what is actually reassuring to me. So

3:06

Speaker 1: let's continue to have a look at the history. They then also with the CSIF framework realized rather soon we also should protect put and delete um requests Because they are more used nowadays with all of this modern HX stuff becoming so popular. We probably should take care of those as well. But not only did they c take care of those, they decided, okay, let's do it right. Let's take care of all request methods and only then go the other way around and say, okay, only those who are explicitly marked as safe those we will uh not protect and all others we will. So I really like the security mindset which is um demonstrated there to just

3:51

Speaker 1: go all the way and then just go back where it's necessary instead of doing only the bare minimum. In those cases, um all of them, whether it's allowed hosts or switching the default session serialization to JSON or even requiring model forms to explicitly state which uh fields they should work on. Um all of those changes require some effort on the or introduce some friction. And again, obviously the choices were made to favor security over the friction it causes for the developers. And that's something which uh makes me happy. Even though I every now and then, of course, um was annoyed that something didn't work out, then I realized ah okay, it's the JSON serialization which got me there.

4:42

Speaker 1: Or Um I see the error messages of the allowed hosts and I think, nah, okay. But in those moments, besides being a little bit annoyed, I felt really happy that um Django made those choices. Also the next um three uh things I want to point out, password validation, the removal of the remove text filter. as well as the support of content security policy for the Django admin, all of them require work. Password validation requires work for the user. Um if you remove a filter, it's um pretty obvious that you cost some developers uh some work. And um the last one, the Django admin, I assume

5:27

Speaker 1: took a lot of work and on the side of the Django developers to get the admin ready. In um my daily business as a pen tester, I rarely see applications which use content security policy in actually an effective manner. Just because it's so much effort. And if you look around, even Google Maps, if you want to include Google Maps, on the page you include Google Maps, you can't do proper content security policy anymore. So It's it's really cool that uh the Django admins did what Google didn't uh that the Django developers did with uh Django Admin, what the Google developers didn't do with Google Maps so far. And yeah, I like

6:14

Speaker 1: I like that the developers again made the choice to put in the effort to make people to put in the effort in favor of security once again. Then um the password reset confirm view was changed to avoid the token leakage through the referral. By a self-redirect. Now what happened before that? Um when you open the view, you have the sensitive um token in the URL, which is Not an ideal place in general to have sensitive stuff there because it ends up in the browser history, in proxy histories, in any locks. So you really don't want to have sensitive stuff in the URL, but in case of the password reset functionality, it's not really avoidable.

7:01

Speaker 1: So The idea that a token could be leaked through the referral of some CSS which you include or some JavaScript, some images you load from third party pages, uh is Quite a neat idea, I think, and I like this specific choice. Not so what they did is then they uh chose to do a self-redirect store that token inside the session and then render the template after there's nothing sensitive anymore in the URL. So nice choice there. But what I do like much more than the fact that they fixed this tiny tiny security issue is that they take They took the time to do that, to realize that.

7:49

Speaker 1: So it's just shows how much attention to detail they put into security uh choices. And already to conclude our history of um Django security related changes We arrived on the last page with Django 2. 1 in 2018. They chose to make the same site cookie flag. on default to legs. That's something as um Russell already pointed out in in his talk today, Google started doing this year in February. Other browsers are on the verge of doing it It's a little bit back and forth. And so that's happening now two years later. But Django already two years ago

8:35

Speaker 1: took the step to say, okay, let's uh let's do that for our framework. Let's make this default setting a little bit more secure. Same thing here with the X frame options. They now default to deny instead of Same origin, which is relevant, for example, in cases you try to circumvent the content security policy, then it can come in handy for the attacker if it's same origin instead of deny. So Once again, something which shows that they continue to think about security there. And the last setting is something which Really amazes me how it's still possible that it's not a browser default. The same origin, so to set the secure referral policy to the same origin.

9:22

Speaker 1: meaning you only send referrals to your within your own domain, but when you go to another um domain, you won't send the referrer anymore. I would imagine if a feature like the referrer was invented today, there would be a huge outcry by all data privacy activists. Um media coverage and everything. But since we got used to it over decades, it's alright that every website gets to know where we come from and not only from which domain, but from which exact page we come from. And It's it's so obvious that that's not a good idea, but yeah, I like that uh Django now addresses it since Django 3. 1 with uh a more sane default there.

10:09

Speaker 1: All right, so much for our um history of Django security related changes. One last detail I would like to point out, which uh makes me happy every time I see it, is the red bar in the documentation. So when I'm somewhere on Stack Overflow Find the link to the Django documentation, I more often than not end up in an old version of Django. And um You immediately notice it due to the red bar. But the red bar says this document is for an insecure version of Django that is no longer supported. Please upgrade to a new release. And what I really like there is that they don't say it's for an old version, but for an insecure version. Yes, there might not even be a vulnerability already known.

10:56

Speaker 1: but it's insecure per default because it's not supported anymore. And even the people who took care of the documentation have the security uh mindset there, which is something I really admire. Now, let's have a look at a few Django security features and their limitations. Cross-site scripting, here's an easy example of how it could look like if you did not have the auto-escaping feature, which is thankfully Turned on on default in Django. So the basic idea of cross-site scripting, you execute the attacker's code in the Victims browser within the context of the vulnerable application.

11:47

Speaker 1: Sometimes in some pen test reports it sounds like it's a big deal that the attacker gets to execute JavaScript code. Oh no. Um now the attacker can run browser exploits and dangerous things. But It's not a big deal to execute uh JavaScript in someone else's browser. You always can do that. Just send them a link to something, promise them a funny cat picture, like make it fit into the context, and they will always click on the link. I would, everyone would, I guess. So executing JavaScript there is not the big deal. The big deal is to do it within the context of um the application because then the attacker can do basically anything with the application the victim could do. Alright. But it can be prevented of course. And already since Django 10

12:34

Speaker 1: we have the crosshead scripting protection activated on default. So those characters are um escaped, converted to uh look like this, and that's a perfectly fine protection against cross-site scripting if you are in the right context. But there are many cases in which it's not enough to just rely on okay cross-head scripting is not a not something I don't it's something I don't need to care of because um It's already taken care of for me. Unfortunately, it's not that easy. And those are a few examples in which it's um relevant to think about it yourself. So the very first example is straight out of the Django documentation.

13:19

Speaker 1: If you don't use quotes around your attributes, it's super easy to bypass. the the filter and once again you're vulnerable to cross site scripting. Also URLs are um an issue because you again can come with this um like fake protocol and Get your code executed. So take care with URLs as well. And I think one of the most um common cases What happens when you develop? You want to get some values from the server into your JavaScript. So now imagine um you want to write a price in here. You can't even quote it because it's supposed to be an integer, not um Not a string. And if that's what your price looks like, you again have a cross-head scripting right there.

14:08

Speaker 1: So what to do in those cases? Well, missing quotes, it's rather easy, just add the quotes. URLs, I think I would check to start with um if the to check if the URL actually starts with HTTPS colon slash slash Then you should be good to go, I guess, but I would Google that before I go further with that. And um the last part I think is the most complicated case. And I would like to show you what I do. to get my values in um in the code, but I'm not sure if there's a better way. So My boundary conditions are I want to have static JavaScript files, so I don't want to use the templating system inside JavaScript files because it's not made for that And I also don't want to do inline

14:53

Speaker 1: scripts because that's um bad style. I can't use content security policy anymore if I would want to do that. So Now in my template, I just add uh diff which is not shown with the value which I want to transfer. I pick it up in JavaScript like this. And Without any accidents, I got my value into a JavaScript variable. Now I of course shouldn't do anything stupid with it at this point, but the transfer into the JavaScript variable happened without an opportunity for a cross-site scripting attack there. It feels a little bit uncomfortable to do that for every single single uh value I want to transfer. So maybe you have a better idea how to how to do that. But at least it's a way which uh should be secure.

15:40

Speaker 1: So if you do have a better idea, please uh let me know in the chat. I will check it after the talk. All right, so those were the three um things we looked at. How How it could go wrong. The list is not complete, so if you do something which is um out of the ordinary, always consider it again. But I want to show you one more or maybe two more ways how um it could go wrong. And in this case, um it's the first cross-site scripting I produced as a developer. So There are many other ways how it could go wrong, but this is the one how it went wrong for me, and I want to

16:27

Speaker 1: share it with you now. So I wanted to use data tables. So first um I needed to set it up. Easy enough. Already on the front page you find instructions. Include a little bit of CSS in JavaScript, have your table ready in HTML, and execute the data table function, and your data tables are ready. Easy enough. But now I wanted to use HX data as a source. Two or three clicks in the documentation, and the HJAX source was set up and working. Easy enough So I thought, okay, it's good, everything is working. But at a later point, I thought, okay, now I also would like to include some some HTML elements in there.

17:13

Speaker 1: And That's that okay. Now I need to figure out how I tell data tables that the values it's received are supposed to be considered as safe. So like the Django um mark safe um thing. I wanted something like this for data tables and um I was already ready to search for it and to figure out the way how to do that in with data tables. I set up my test case, so my HX point was now endpoint was now delivering some HTML in there, and it already worked. And I was like, what happened there? That's a cross-site scripting. And I then Googled for um data tables and XSS, and it turns out it's actually not secure on default. If you want data tables to

18:00

Speaker 1: uh Take care of this issue. You need to um set a renderer and tell it it's a text field and then it will encode everything properly. So that's um came as a surprise to me there. And I think what what happened there is um it's two different things which um you can see there. what can cause um a cross-site scripting. So one is to use um not secure library or to use uh secure library the wrong way And um the other one is to assume that everyone does security on default, like Django does. So if you come out of the Django world and you step out of it into the big

18:46

Speaker 1: dangerous world Just always be sure not everyone is taking care of your security as well as Tjango does Alright, on to cross-site request forgery. Cross-site request forgery, the idea is simple. The attacker tricks the victim into sending a request. Which then does something dangerous, like for example, in this case, assigning admin privileges to any user. And um The basic idea of defense is just as simple. I add a random value to every protected request. I check if it's the same random value which was submitted as I put in the In the form

19:32

Speaker 1: in the first place, and in this way it's impossible for an attacker to know what they need to submit in order to make a valid request. Yeah. The Django cross-head request forgery uh framework also um checks the referrals on HTTPS connections, which is just an additional Cross-head request for tree measure there. Antique cross-head request fortress measure. All right. Of course it needs to be turned on, which is the case on default. It uh needs to be you need to be sure, and I think that's the biggest issue here, not to do anything unsafe in safe requests met

20:18

Speaker 1: methods such as get. So Don't do anything which um causes an action. Ideally, no action at all. Um maybe you want to mark something as red, that might be alright. Um but Don't do anything which is dangerous inside a safe request. And evil subdomains could be an issue too, but I think that's not the case in most use cases. While the first um point sounds super super obvious, um it needs to be turned on. It's actually such um It's actually really great that it's turned on on default. And I would highly recommend to keep it that way, even though you maybe have a lot of endpoints which you need to exempt from it.

21:06

Speaker 1: Maybe because you have it as a webhook or something. Um but to leave the defaults um turned on is really nice. For example, it every now and then happens to me, I write a new view, I write the form which then is supposed to send the data, and when I first time send the request, I see the CSRF validation error Why? Of course, I forgot to include the token. But it's a very small pain to forget to include the token in your form and then immediately noticing it because the form doesn't work. as opposed to I forgot to activate the CSRF protection for my function in total, then I might even not notice it. So I think the chances quite the chances are quite good that if it wasn't turned on on default

21:52

Speaker 1: for every request There might be a few requests now in my applications where I actually would have forgotten about it in the end. So secure defaults are so important in so many cases, and unfortunately I don't have the time. But I could tell you so many stories where I saw stuff going horribly wrong because the defaults were wrong. So I think it's very often very underrated how important it is to have secure defaults and not only some point in the documentation pointing out like well You should do it like this or like that. All right. SQL injection. Um a very severe vulnerability, fortunately not seen that often anymore. uh I would say. And the protection in general, of course, use prepared statements.

22:38

Speaker 1: And in Django, let the ORM take care of that for you. You're almost Completely safe if you use the ORM and don't do your own um own SQL statements More precisely, avoid using the extra or raw functionality Django provides and only because someone on Stack Overflow suggests this thing as the first solution which you found for your current problem. Really think if you want to do that. Like it's so easy to make a mistake, even though you know how you should do it. And I'm super confident that I know okay, I never use the extra Aura functionality, so I don't even need to worry about this whole um kind of vulnerability. And of course, also don't do anything stupid, like

23:24

Speaker 1: don't uh use user-supplied uh keyword arguments for the filter functionality. It's not an technically an SQL injection, of course, but it's not much better than that either. So It's always important to think and not do anything stupid, but in this case the Django ORM got you covered pretty well if you managed to avoid the extra overall functionality. So for the end, I would like to give you a few best practices. Just some of them are really important, I think, and actually helps you to make your application a lot more secure. And some of them just help you to avoid some unnecessary minor fantas pentest findings. All right, always ask yourself what could possibly go wrong.

24:10

Speaker 1: No matter what you do, always have in mind when there is a user-supplied value, that it could be an attacker supplied value, assume your users are evil. Always think about what could possibly go wrong. Um I would recommend you to use an intercepting proxy. I'm very used to use an intercepting proxy for my work, so As a pen tester we use Burp Suite, but there's also the open source version from OWASP, OWASP ZEP, the Z attack proxy, which you could use. And uh it allows you to intercept the requests, to change them, to send requests again and all of this. stuff. I know a lot of developers use Postman for uh trying out their

24:57

Speaker 1: functionality if they want to generate requests, but maybe try an intercepting proxy there. Uh there's also a free version of Web Suite available. The most annoying thing is it doesn't allow you to save um your project, which is a little uncomfortable, I think. Um yeah. But the value in there is I think that you can um you can have an idea of what an attacker can do you actually get into the mindset of accepting that all data coming from the client is evil because you see how easy it is to manipulate it. Be prepared for your own mistakes. Um, as I already gave the example with the CSRF functionality, try to write your code in a way that if you forget something, that it fails

25:44

Speaker 1: in a secure default. Like if I forget to add the marker for this um functionality can be used without a login. Okay, then someone will complain that they can't see this uh this view. But if I have if I need to mark every view which should be behind the login. Then I don't have a secure default. So try to prepare for your own mistakes. Of course, keep all your stuff up to date. And regarding cookie flags or cookies, make sure you set all the cookie flags. And uh if you didn't see the talk this morning

26:29

Speaker 1: from Russell. It's um it's a great talk. I highly recommend it. And then you will know what all those uh flags do and a lot more about cookies as well. Regarding TLS, I just want to recommend actually to test your TLS settings. Don't rely on, hey, I already included it in the config, should be fine. Well maybe you included it in the wrong virtual hosts. Um maybe your settings were not the way you think they were. So really make sure you check them. If you do check them, you can use the Qualest SSL labs without any setup um but also the test SSL script. It's super easy, it's one script, no dependencies, just um go for it, test it, and sometimes the results can be surprising. Also, um

27:17

Speaker 1: I thought okay, probably I'm I'm taken care of there. I have the let's encrypt defaults, but the let's encrypt defaults are not that good anymore. Uh so If you're using those, just check it what uh the scripts tell you and um try to improve your configuration there. And um as a last thing to take care of, which um produces findings in every pen test is missing Missing response headers. Have a look at the OVASP project, what they recommend, and I only want to point out a few headers here which I highly recommend. HTTP strict transport security, HSTS With this header, you ensure that

28:02

Speaker 1: the browser always tries to connect to your website um using HTTPS. No matter what the user or an attacker might tell the browser to do. X-Frame options obviously protect you from click-checking attacks. and um also some marketing measures. So it's really a good idea to uh Have this header set as well. And the content security policy, well, it's a really nice second line of defense against cross-head scripting. I highly recommend you set it if you can. But to be honest, it's a big big effort. And even if you wrote your own code clean from the beginning with no inline JavaScript and all of that. As soon as you have a few third-party library dependencies, chances are high that

28:51

Speaker 1: it's not possible anymore to set up a solid content security policy there. If you do put in the effort to uh activate the policy, I highly recommend you to check it with the CSP evaluator Because it also comes with a library which then tells you like look what you included here has known vulnerabilities which can be used to circumvent your policy. So if you do put in the effort, also check it with the CSP evaluator. All right, that's um about it. That's the best practices which um I wanted to give you. And uh yeah, that concludes my talk. If you have any questions, please let me know.

29:44

Speaker 2: So I have a question for you.

29:47

Speaker 1: All right.

29:48

Speaker 2: Have you ever contributed to the Django core from something related to

29:56

Speaker 1: No, unfortunately not.

29:58

Speaker 2: Okay, and have you ever found something to improve reading the code, the code base?

30:07

Speaker 1: Um I Do have a minor minor idea which at some point I want to report, but it's I didn't report it yet because it's really a minor minor issue and uh Yeah, I'm not even sure if it's worth fixing, but

30:20

Speaker 3: please do tell us.

30:22

Speaker 1: I will, I will.

30:25

Speaker 3: You can't tease us like this.

30:30

Speaker 1: I'm a little bit embarrassed because it's not I guess um I can tell you right now because it's not really really super sensitive. Um If you're interested. And no one else. But um Adam had a question, so maybe I will answer that one first. Ah okay, okay

30:51

Speaker 3: Shall I ask it out loud now?

30:53

Speaker 1: Yeah, sure.

30:54

Speaker 3: Okay. So you mentioned about intercepting proxies. Uh which would you recommend for like day-to-day development that could help pick up security issues whilst we're just working on our apps?

31:04

Speaker 1: Right. Um I think I can't give a very good recommendation there because as a pentister I always work with burp suite Um which is obviously made for attacking scenarios, but um I use it personally for developing as well, just because that's the tool I know. So I don't know if there's any w more suitable for development um purposes. But if um your only tool is a hammer, like yeah. So I I didn't look for for any other ones.

31:36

Speaker 3: And would that be something you'd run in front of run server and it would report things that look suspicious going past?

31:43

Speaker 1: Um you you put it between the client and the server, so you you put it you set it up as a proxy in the browser. And um then it doesn't matter which um which endpoint you're talking to. So you could um use like Foxy proxy or something like that to tell it only to redirect the traffic you're interested in through um through burp or through your proxy. And in this way you can see everything which is happening between your browser and the server. And There are some passive checks which would let you know if it thinks there's something wrong, but that's not really what I would rely on too much. I think there are probably better um tools which you can integrate into your tool chain, like CI tools and stuff like that. But um I would use it as an interactive tool.

32:28

Speaker 1: Like oh this function doesn't work, um let's send it to the repeater and in this way I don't need to go through the whole workflow, click myself through the interface in the browser, just send the request I'm interested again and something like that.

32:40

Speaker 3: Okay, cool.

32:42

Speaker 1: Yeah.

32:46

Speaker 3: So do tell us Or you spotted.

32:51

Speaker 1: I'm a little bit embarrassed. It's not really a big a big thing. I don't like that Django Sends a new session cookie everything every time I change something in the session server side. Um I have an idea where it could come from because um if you have Um a cookie based session backend. Obviously, every time you change something in the session, you need to set the cookie again. But if um if your um Using, as probably most people do, adjust the session ID in your cookie and everything else on the back end side It's just an info leak which is not necessary. Like I try to construct an example for something like

33:36

Speaker 1: why it would be a bad idea to do that. The best they could come up with is you have um a lottery or something and you can try to submit the winning the winning uh phrase as many times as you want to, and only the last one you submitted counts. And if you see that there's a change in the session state, it might be a hint that it was the correct um the

34:01

Speaker 3: correct.

34:03

Speaker 1: So it's it's I don't know, I I thought about some like crypto oracle stuff, but I couldn't come up with anything there. So it's probably not a big deal. But just

34:12

Speaker 3: you basically get like a one bit of information.

34:15

Speaker 1: Right, right. Yeah, that's all. Otherwise I

34:20

Speaker 3: think it's it's worth submitting.

34:23

Speaker 1: Okay, then I will write an email.

34:26

Speaker 3: Thank you. And thanks again for the talk.

34:31

Speaker 1: Thank you guys.

Questions this talk answers

Why is Django considered secure by default?

Django has repeatedly chosen security over compatibility or developer convenience, including automatic escaping, secure cookie and header defaults, CSRF protection, password validation, and warnings for unsupported releases. The speaker sees this consistent security-first approach as the reason Django is “reassuringly secure.”

Discussed at 1:35

What are the limitations of Django’s automatic XSS protection?

Template auto-escaping is effective only when used in the right context. Unquoted HTML attributes, unsafe URLs, inserting values into JavaScript, and insecure third-party libraries can still create cross-site scripting vulnerabilities.

Discussed at 12:34

How can I safely pass server-side values into JavaScript in Django?

The speaker recommends putting the value in a hidden or otherwise non-displayed HTML element and reading it from a static JavaScript file, rather than using templating inside JavaScript or inline scripts. This transfers the value without creating an XSS opportunity in the example shown.

Discussed at 14:53

How does Django CSRF protection work, and what should I avoid?

Django adds a random token to protected requests and verifies that the submitted token matches, with additional referrer checks on HTTPS. Keep CSRF protection enabled, and never perform dangerous state-changing actions in supposedly safe methods such as GET.

Discussed at 18:46

How do I prevent SQL injection in Django?

Use Django’s ORM so it can generate prepared, parameterized queries, and avoid the `extra()` and `raw()` functionality unless absolutely necessary. Do not pass user-controlled keyword names into filtering operations either, since that can create similarly serious problems.

Discussed at 21:52

What security best practices should Django developers follow?

Treat every user-supplied value as potentially attacker-controlled, use an intercepting proxy to inspect and manipulate requests, design secure failure defaults, keep dependencies and Django updated, and test the actual deployment configuration. The speaker also recommends checking TLS settings and setting appropriate security response headers.

Discussed at 24:10

Which security headers should I configure for a Django site?

The speaker highlights HSTS to force HTTPS, `X-Frame-Options` to help prevent clickjacking, and Content Security Policy as an additional XSS defense. CSP is valuable but often difficult to deploy with third-party dependencies, so it should be checked with a CSP evaluator.

Discussed at 28:02

How should I use an intercepting proxy during Django development?

Put the proxy between the browser and the server, optionally routing only selected traffic through it with a browser proxy switcher. It is useful interactively for inspecting requests and sending them to a repeater, but passive checks should not be treated as a complete security-testing solution.

Discussed at 31:03

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 from DjangoCon Europe