Automate Your City Data with Python
Published November 22, 2023
This video features Philip James at DjangoCon US 2016 in Philadelphia, Pennsylvania, USA.
DjangoCon US 2016 - Frog and Toad Learn About Django Security by Philip James
Django Security Talk Notes
Introduction
Philip James, how long I’ve worked with Python and Django, background at EB
Introduction to the story, and the characters
Safe-ish: Talk about Django’s Security Model and how it tries to provide sane defaults for developers
Run-through of the parts of the django security model
XSS (brief definition)
Django escapes characters by default
How?
How do you turn it off? Mark Safe, | n, safe
CSRF (brief definition)
Django has middleware that checks POST requests for a token
How?
Token is stored in cookie, also
Could be better? Make cookie httponly
Side-effect: harder to JS. Also, only an issue if you’re already owned, so maybe not an issue?
How to get around it? csrf_exempt
SQLi (brief definition)
Django’s ORM makes clean sql, (even when given bad data?)
How?
How to get around it: extra()/RawSQL()
Clickjacking protection (brief definition)
Django has middleware that sets headers browsers are supposed to respect
Which browsers? https://docs.djangoproject.com/en/1.8/ref/clickjacking/#limitations
How to get around it: xframe_options_exempt, xframe_options_deny, xframe_options_sameorigin
HTTPS
This one is less "out of the box" than the others, so won’t be talked about here.
Host Header Validation (brief definition)
Django verifies against allowed hosts in settings
How? get_host()
Session security
What are django sessions?
Cookie-based by design
How can we make this better?
Overall: Vigilance. Be aware of uses of this within your product
XSS, CSRF, SQLi, Clickjacking: Have them all enabled, write rules to check for "escape-hatch" functions
HTTPS:
Use it!
Set the correct settings
SECURE_SSL_REDIRECT: How does it work?
Other things
django-secure
http://nerd.kelseyinnis.com/blog/2015/09/08/making-django-really-really-ridiculously-secure/
This talk was presented at: https://2016.djangocon.us/schedule/presentation/10/
LINKS:
Follow DjangCon US 👇
https://twitter.com/djangocon
Follow DEFNA 👇
https://twitter.com/defnado
https://www.defna.org/
Philip James uses Frog and Toad’s fictional book-selling startup to explain the Django security protections that apply to common web threats. Django escapes template output to reduce XSS, checks CSRF tokens, separates SQL queries from data through the ORM, blocks clickjacking, validates hosts, and securely hashes and upgrades passwords, while escape hatches such as `mark_safe`, `safe`, and `csrf_exempt` require care. He argues that Django is secure by default within reason, but teams still need HTTPS, Content Security Policy, encrypted fields where appropriate, secure settings, secret-key hygiene, code review, testing, audits, rate limiting, and continual attention to their attack surface.
Summarised automatically from the transcript.
Automatically transcribed, so expect mistakes in names and technical terms.
Speaker 1: Come on, no.
Speaker 2: Thank you all so much for coming to DjangoCon Story Hour. I'm really happy you could all join me today. Today's story is Frog and Toad Learn Django Security. Frog and Toad are friends. One day, Frog came up to Toad and said, I have this great idea for a startup. I'll do all the businessy work and you, Toad, can code all of it. Doesn't that sound great? The startup is going to be called Bezos Books. It'll be a site for selling books. Authors can have a form where they put in book information, the book information will get put on a page, and people can come to our site and buy books that authors put up. I'm sure it'll be easy. I'm sure we'll make lots of money.
Speaker 2: Now, Toad is a Django Toad, not a flask frog. And so he decides that he's going to make Bezos books in Django. And he goes back to Toad and tells him this. And Toad says, that's great, but all of the other startup friends that I have in the Lily Pond keep losing customers because of security exploits. Is Django secure? So Toad thinks about it and he goes and does some reading and he discovers that yes, within reason, Django is secure, and he goes to tell his friend Frog about it. The first thing he tells Frog about is XXS or cross-site scripting vulnerabilities. Now Frog asks, what's a cross-site scripting vulnerability?
Speaker 2: And Toad says, I'm glad you asked, Frog. A cross-site scripting vulnerability is when someone who Can put information onto our into our site that we render to a page, puts in things to be rendered that are supposed to harm or affect the user in a way we don't want. So because we have a form where authors can put in book information, if they put in some nasty JavaScript, our users could lose their credit card information or have all sorts of secrets stolen, and that would be very bad. Frog says, yes, that would be very bad, Toad. Does Django protect us from this? And Toad says, yes, Django does. If a user puts in something like a script tag, Django, when we render that to HTML, is going to escape the nasty characters in that script tag, or in that uh uh script tag.
Speaker 2: And because Toad is a very clever Toad, he dug into the Django source code and saw exactly the function that is doing this. And Toad was surprised that it's actually a very simple function. A function that basically hasn't been changed since Simon Willison wrote it like a decade ago. What the very simple escaping function does is look for characters that could be harmful and replace them with safe HTML entities. Toad is very clever, Toad, and so he found out where that function lives. And because he wanted a complete picture of how Django handles this rendering system. He learned that where escape is called is in nodes. When the context is used to render a template, a tree of nodes is created to represent the HTML in that template.
Speaker 2: If a template should have something change about it because a variable has been put in, a aptly named variable node is created. That variable node has a render method like all nodes in the Django DOM representation It has a method called a conditional escape, which checks if it should escape the string, and if it does, it calls that escape function that Toad discovered earlier. Frog is very happy about this and asks his friend Toad, but Toad, what if there are cases where we really don't want things escaped? For some reason we actually do want HTML on the page. Toad isn't sure about this. He thinks that's a bad idea for security. But he tells his friend Frog, well we have these helpers called MarkSafe and Pipe N and PipeSafe. That will let us put HTML right into the page and have it rendered the way we expect.
Speaker 2: But we should be very careful about using these frog. Frog nods sagely and says, yes, of course, we should be very careful about using these. The next thing that Toad tells Frog about is CSRF, or cross-site request forgeries. And the way he tells it is, Toad Frog asks, what else does Django protect us from? And Toad replies, well Django tries to protect us from CSRF attacks. CSRF stands for cross-site request forgery, and it could cause our site to do things against the user's wishes. Here's an example. Say our site had a delete button for authors to delete their books. If that button was just a simple request against our site and we didn't have CSRF configured correctly. Some other site could link to our site and trick authors into leading their books through that link.
Speaker 2: Frog says, ooh, that sounds bad. We don't want to do that. Toad agrees, we don't want to do that. And luckily, out of the box Django tries to protect us from that by using CRSV CR CSRF view middleware. Toad is a very clever Toad, so he digs into the source code and finds exactly where the CSRF view middleware is defined. Toad digs even deeper because he wants to have a whole picture of how the system works and comes up with some clever pseudocode to explain to Frog what the CSRF system is doing. If the middleware detects that a request is a post, it gets the CSRF token from the cookie that's on the request, it gets the CSRF middleware token from the request post data. And if they both match, then the request is accepted
Speaker 2: and everything moves on. If they don't match, then the request is rejected and the user gets an error Frog thinks this is amazing. He likes that their site is protected because he heard about some weird thing years ago where Google tried to helpfully preload links and ended up deleting a lot of blog posts. So he asks, This is great, Toad, but is there a way to get around it? And Toad says, Well, yes, again, we should be very careful about using these things, but There is CSRF exempt, which is a decorator that we can put around our views, and when we decorate our views this way, then we skip the CSRF protection in the middleware. Toad is a very clever toad.
Speaker 2: And he looks up exactly where that CSRF exempt decorator lives. And then plays around a bit with how he would use it for both function-based views and class-based views. He notices that for class-based views, he has to import a second method decorator, which strikes him as odd, but he moves on. Appropriately, he now updates his pseudocode. If the request is a post and the view is not CSRF exempt, then we do everything else. Now , Frog and Toad were walking along as they said this, and they were ending their day enjoying some lovely, lovely chocolate chip cookies back at Frog's house
Speaker 2: And Toad said, You know, these cookies remind me. Do you want to know something interesting, Frog? And Frog said, Yes, I would love to know something interesting. You are my friend. And Toad says, there's a special thing you can do with cookies where you can say this cookie should be HTTP only and therefore only be able to be read by the server. But uh the Django CSRF cookies aren't set that way. Isn't that interesting, Frog? Frog isn't exactly sure why that's interesting, but he nods along because he likes Toad and Toad is doing all this work for him. And Toad says, this is interesting because it means that JavaScript can read and affect the CSRF cookie that is set in The
Speaker 2: uh request that is set in the browser. And Frog goes, Well, that certainly is interesting. He's still not sure he gets it. And Toad goes, and we asked some Django people why this might be, and the answer is, for JavaScript forms, when you do that jQuery. And you need to be able to read that CSRF token so it can't be set HTTP only. Isn't that interesting, Frog? And Frog goes, yes, very interesting. What else do we need to be protected from? Next, Toad tells Frog about SQL I injections.
Speaker 2: And he says these are really bad. These are so bad that if we're vulnerable to these, we could lose everything. We could lose all our financial data, all of our user data. People could buy all the books they wanted. It would be horrible. Frog looks appropriately alarmed and says, are we protected from this? And Toad says, well yes, yes, we are protected from this, because Django does the right thing, which as it turns out, is nothing. All Django does is not screw up the barrier between code and data. When you make a query set and you make a request against the database with the ORM , Django keeps the SQL logic separate from the data that is being collected with the SQL logic and passes them as two separate parts all the way to the database
Speaker 2: handler and then the database handler does the escaping that is appropriate for that database. Django just has to not screw things up and it doesn't. Frog goes, that's great. But I was talking to some analysts and they said that sometimes they really need to get like raw SQL into the database. Toad isn't very certain about this, but he says, okay, if we actually need to do this. Django has some methods that can do this. There's the dot extra method, there's the raw SQL, there's the dot raw on managers, but we really shouldn't do this unless we're absolutely certain we want to be doing this. And Frog says, of course Toad, we'll be perfectly safe. The next thing that Toad tells Frog about is clickjacking. Clickjacking, Toad tells Frog, is particularly subtle.
Speaker 2: What people can do is wrap our entire page in an iframe on a different URL and make it look like people are browsing our site when really they're browsing somebody else's site. And if they're browsing somebody else's site with our site and an iframe, then when they enter their password into our site, that person could collect it. Isn't that awful? And Frog goes, yes, that's very awful. How we can prevent that, right? And Toad says, yes. We can prevent that Through the X-Frame Options Middleware, which is also enabled by default on Django. The X-Frames option the X-Frame Options Middleware, Toad learns because he's a very clever Toad, lives in this particular location on GitHub and uh makes sure
Speaker 2: that The browsers which respect it will only display the site if it's the same origin. Of course, you can get around that with the X-Frames option to exempt decorator and it only works in certain browsers unfortunately but it's a very good thing to do if you're worried about running an e-commerce site like say Bezos Books where people could be trying to steal your credit card information or passwords. Next, Toad tells Frog about host header validation. Host header validation works with click-jacking in a way to make sure that only the host that is supposed to be rendering the site can render this site. Toad made the mistake very early on, as many Django developers do, of not setting the correct
Speaker 2: uh allowed hosts. In his settings file before he deployed to production and got that lovely error that means that he spent 10 minutes Googling because he couldn't figure out why Django wasn't working. And the pseudocode looks something like this. The request in in the middleware. The middleware checks the request, checks the domain of the request, sees if it's an allowed host. and then proceeds, otherwise it raises an error. Finally, they get to passwords. And Toad is really excited about passwords, which is weird because nobody should be very excited about passwords. And Frog says, Toad, you're so excited about passwords. Why are you so excited about passwords? And Toad says, the reason I'm so excited about passwords is because what Django does is so cool.
Speaker 2: Django hashes passwords, which is common. All good web frameworks should hash passwords. But the way it hashes passwords and the way it does password upgrades is really nifty. When it hashes your password on login, it checks this Django Contrib auth hashers check password function. And if you have upgraded your hasher It checks against the old hash, the password against the old hash to see if it should be a login. And if so, it automatically rehashes it with the new algorithm. So you get automatic security upgrades as you're moving through the lifetime of your product. Isn't that amazing? Frog says, yes, that's amazing, that's so cool! And Toad smiles. So having gone through all that Frog so all that Toad discovered, Frog asks Toad, that's all great.
Speaker 2: Really quite amazing, but what can we do to make this better? How can we improve the security of our Django site And Toad says, well, the first thing we can do is be constantly vigilant. All those things I talked about, all the ways to get around The built-in Django security features. We should be doing everything we can to limit the use of those One great way of doing this is having our code review tool automatically alert us when it detects things like CSRF exempt or Pipe N or Mark Safe. So that me especially as CTO, I am CTO, right? And Frog says yes, yes, you're CTO.
Speaker 2: That me as CTO get alerted when somebody is using these very unsafe parts of Django. Additionally, we should be doing regular code reviews. And we should be having tests to make sure that all of our security features are up to snuff. We should also be doing regular security audits to make sure that our product can't be hacked into by people who aren't us. Frog says, that sounds like a lot of work. Are you sure we need to do all of that? And Toad says, yes, it's very important. If we don't do this, and if we don't do this on a regular basis. We might be exposed and lose all of our customers' data. Frog looks suitably alarmed and says, yes, that is very, very bad. The next thing that we could be doing, says Toad, is making sure our site is served over HTTPS.
Speaker 2: And luckily, Django makes this easier and easier all the time. You can serve cookies securely. You can set your settings to use to only allow secure URLs, but it's very critical, especially since we're an e-commerce site, that we only use HTTPS on our site. So I know it's going to be a little bit more money to get the HTTPS certificate, Frog, but it is very worth it, I promise you. Do you want the government snooping in on what are on what books our users are buying? Frog thinks about it Thinks about the romances he's been buying recently and says, no, I don't want anybody knowing what I'm buying on our site. The next thing we could be doing says Toad, is having a content security policy. A content security policy is another thing that the browser respects that you set on your server
Speaker 2: And what it says is, hey browser, please only allow content from these domains. And the browser says, well, you've told me to only allow a content from these These domains, I'm going to block hard anything that you tell me to block. But I will also, if you tell me to just log, I will let you know when you are loading content from unauthorized domains. Which is really great for Frog and Toad site because it means they can allow certain HTML to be put in to load images from certain sites, but not allow images or links from other sites And block those at the CSP level rather than having to write complicated rules for checking the HTML in the code So, Toad recommends to Frog, we must set a CSP policy.
Speaker 2: At the very least, we should set a logging policy so we know where our users are trying to access Assets, but if we could, we should be trying to set a blocking policy so we don't allow anything that we don't trust on our site. The next thing we could be doing, says T Is setting Django encrypted fields and using those to store confidential information like passwords or user credit card information or any other personally identifying information. If we set this and set it with a key and come up with a good key management policy, which is unfortunately tricky all in its own right. then we can be reasonably certain that at least at rest, our data our users' data will be protected, which is very important.
Speaker 2: You understand it's important, right, Frog? And Frog says yes, I understand it's important. And Toad says, with Django encrypted fields protecting our data at rest and HTTPS protecting our data in transit, we now have a much tighter attack surface, and it's much harder for our users' data to get leaked. The other thing we could do, which is fortunately now bundled into a lot of later versions of Django , is use Django Secure and set some of the settings there to really tighten down any of the areas of Django that we haven't explicitly covered. And there's a great tool online, says Toad, called Pony Checkup, which will go over our entire site and scan for common Django vulnerabilities.
Speaker 2: And I've heard, says toad that if we get 100% on our site on Pony Checkup, Eric will give us a sticker. Of course, there are lots of other resources in the community. One of which are talks from previous Django cons, like Making Django Ridiculously Secure by Kelsey Eagle Moore in this last year, but also her security talk from PyCon this year. Which Toad very much encourages Frog to go watch. Having done all of this and having tried to firmly explain to Frog all the vagaries of securing a Django site and everything that Django does and digging deep into the code examples to prove to himself that the Django security works the way it should, Toad goes and asks Frog, Frog, do you have any other questions?
Speaker 2: And Frog thinks about it and thinks about it and says, I'm not sure I want to run a startup anymore, but I definitely know a lot more about security. So thank you very much. Uh as Adrian mentioned my name is Philip James. I am a senior software engineer at Eventbrite. If you're interested in hearing more about that, come talk to me. These slides are online. I am deliberately leaving time for questions This was dil supposed to be this uh story is an overview of everything that Django Security is doing and some suggestions for making it better. The reason there isn't a ton more content in this talk is because Django does a pretty great job out of the box trying to secure it.
Speaker 2: Having, as part of my job, had to do kind of audits of other web frameworks and other web security tools. Yeah, Django does it right. Um some things that I didn't mention that are also super important, and part of the reason I didn't mention them is because of my lightning talk. Um Django has a session cookie. Sorry, no session cookie. Django has a secret key that if you caught my lightning talk, you may have seen that uh that secret key does a lot for you that you may not realize under the hood, like doing uh signed Cookies, secure sessions, and password reset tokens. Um so if you in the list of things of ways to make Django better, if you have at any time in the entire lifecycle of your code base, pushed your secret key to a repo and you are still using that secret key, please, please, please change it now, put it in an environment variable and never think about it again.
Speaker 2: Uh I We have probably way more time than I was intending for questions. Sorry about that, but you know, send complaints to Russell Keith McGee at Russell at Keith -Magee. com. And I will open it up for questions this time. Hi.
Speaker 1: Hey. Uh what recommendations do you have around packages or things that help with Django for things like denial of service and uh more sort of behavioral analysis? Um About things that aren't strictly strictly dangerous but can be dangerous.
Speaker 2: Yeah, that's a great question. Um so I'm going to answer this question from two approaches. One is the approach of A lot of users are just hitting my site in some way, and one is a lot of semi-legitimate users are just kind of overloading my site, right? Um I'm going to argue that the hey, a lot of users are hitting my site is firmly in the realm of something that Django should not be handling. That is the web server's job. Either you figure out a way to throw more boxes in front of it or you use varnish to do good caching if it if you don't have a lot of content changing on your pages. Uh but if you are trying to do DDOS mitigation mitigation at the Django level Feel free to disagree with me, I think you've already lost. Um if you are having a lot of legitimate actions come through your site where like people are you think somebody who
Speaker 2: has a real user account might be trying to like heavily spam your site or try to break it through. repetition. I heavily recommend rate limiting both on like web flows and on especially on API flows. A lot of API packages will build in some form of rate limiting right now, but it's also not that difficult to add. I don't remember if REST framework has rate limiting built in. Tom's nodding, so yeah, you can do rate limiting at the API level. Um did that answer your question?
Speaker 1: Yeah. Yeah, thank you.
Speaker 2: Thank you. We're gonna go this way.
Speaker 3: So uh when using encrypted fields, um what um do you have any tips? I know uh it could probably be a talk on its own, but do you have any tips for uh the key management policies?
Speaker 2: Key management is really hard. It's turtles all the way down. Um my advice is twofold. One Make sure that it's something that your entire team is aware of. As in, like, key management is hard, but often the reason key management is hard is because there's like one flaw that turns out to be a human flaw where there was this backdoor that nobody knew about to get to the place where you're storing your keys. But that's the human side. On the technical side, um I have never seen a strong argument against Google Keysar, and especially because there's not really anything out on the market publicly available that's better. I know some companies that have rolled their own solutions on top of Keysar to make that better, but Dig deep into Google Keys are and f tr
Speaker 2: see if that would work for you. Um if you don't have dedicated security people on your team, key management is the kind of thing where it's probably worth hiring a security consultant because Because you really want to get it right and you really want to get it right the first time. But you probably already knew that, because why are you asking the question? So uh my TLDR is use Google Keys R. It solves most of the problem. Yeah. Over here.
Speaker 4: Uh hello. I have a very specific question I'll I'll try to explain. So we have Django project behind Some front-end server over HTTPS. And I would like to use all these uh SS uh SSL related Django settings to secure it. But behind front-end server we have rever reverse proxy server. which is over HTTP. And uh if I will enable all these HTTPS only features, I will break reverse proxy. So what to do?
Speaker 2: That's a great question. I would say that you I I think in your heart of hearts you might already know the answer, and the answer is uh wherever if you're Wherever your HTTPS is terminating is the last place that your server is going to see HTTPS, right? And so if you have an HTTP remote proxy in the middle, does it really need to be HTTP or can you make it HTTPS?
Speaker 4: Um they do automatic uh continue delivery and don't generate this special long URLs
Speaker 2: Right. Um
Speaker 5: for the recording.
Speaker 4: Okay. So unfortunately it's not so easy to use HTTPS for reverse proxy because we generate um dev domain for it which includes version and hash and stuff. So it's complex.
Speaker 2: That guy might have a solution. I think I'm gonna encourage you to talk to him afterwards. It's not an area that I am an expert in, um, but uh uh my it probably is possible. It's also pr There's probably a hole in it somewhere if you try to configure it that way. Looks like you should talk to that guy.
Speaker 4: Okay, thanks.
Speaker 2: Uh hey, yeah, over there.
Speaker 6: Hi. Um so you mentioned the use of Django. encrypted fields and I was just wondering if you had any experience or opinion about doing the uh field level encryption in the application layer versus the database layer using something like MySQL has AES encrypt, um Postgres has a PG encrypt, I think. Um aside from the concern about portability, you know, uh do you have any experience?
Speaker 2: I don't have any experience doing things that way. Um my guess is if you can Uh my general philosophy would be that if you can get it working locally and you can specifically write tests that prove that it works locally, then you're probably fine. Um I'm willing to bet there's probably someone in this room who may have done that, uh, but I don't have any direct experience with it. Hi. Looks like that mic is dead, but she's got one for ya.
Speaker 7: Okay, so um So it's very nice that I can encrypt fields in the database and I should do that probably in more cases than I do. Even emails are PII at some low-level level Anyway, um but I'm also supposed to encrypt database passwords um on the file system. I don't want to put them in settings, but I also don't want to use environment variables because then it's clear text somewhere. This is a standard problem. Wish I could use keys are. But um for government reasons our uh development environment is uh Windows desktop and PyCrypto is hard enough. I don't want to compile cra keys are So is there a way that I can use uh the Django secret key that will be
Speaker 7: an environment variable anyway to decrypt other things that are in settings?
Speaker 2: Does your inv does your secret key need to be consistent? Are you still reliant on sessions and the normal authentication methods?
Speaker 7: Does my secret key need to be consistent from server to server or over time?
Speaker 2: From server to server.
Speaker 7: Uh Yes. Okay. Straight I said CAS is less uh secure than using mod aut auth CAS, and it really is. Sure.
Speaker 2: And the reason I ask is because the um Most of the things that the secret key does in Django are things that are incredibly helpful and incredibly necessary if you are buying into the standard way that Django auth works. If you are using a completely different authentication method, um then you're not as reliant on the secret key, and you could just have the secret key to like, you know, call out to random every time you load up a server, right? If it doesn't need to be consistent, then you don't need to even set it in an environment variable. It's just like there to run um over time. But if you need consistency And you can't use PyCrypto and you can't use Keysar.
Speaker 7: I can use PyCrypto.
Speaker 2: You can use PyCrypto, but it's a pain to recompile, right?
Speaker 7: Right. That's it.
Speaker 2: Okay. But Kizar is the one that I would recommend, so man, that is a great question. And you don't want it in any sort of source control because you don't want it in plain text at all. I mean
Speaker 7: I mean what what I guess what I'm asking is what in the innards of Django, which I don't know as well as you do, would I call to encrypt to decrypt things using the
Speaker 2: Oh, I see what you're saying. Um so in the innards of Django The secret key is used basically in two functions. It's used to create salted Hmacs. For things like the password reset token. So that's not necessarily an encryption, that's just like creating a hash. And it is used for the secure cookie signer.
Speaker 7: Okay. So if you're not using secure cookies, so it's not there, yeah.
Speaker 2: Then you might be fine.
Speaker 7: It is a key that should be secure, so I could use it with PyCrypto, and that's my way forward, probably. So
Speaker 2: possibly.
Speaker 7: Maybe I should try and compile Kizar.
Speaker 2: Maybe you should try and compile Kizar. I recommend you talking to Marcus. Yeah.
Speaker 5: Marcus down here at the front. Y'all should connect. All right. Question over here.
Speaker 2: Hi.
Speaker 8: Hi. Um your talk covered a lot of uh things we should do to protect against known threats. What kind of uh defensive programming things should we be doing to protect us against the unknown threats, the ones that may appear at some point, but we would rather be safe when they come out rather than finding we have to hurry to Fix our signs.
Speaker 2: Uh that's a great question. I'm gonna cover the mic a bit because I'm gonna yell. Constant vigilance Seriously, uh you if you're in a large enough company to have a um uh like a group of coders who care about security, making sure that they are trying to review as much code as possible. Um You there's no such thing as perfect security. You can't predict the threats that are going to come. What you can do is make sure that you are following good security practices like sanitizing data when it comes in. thinking about how it renders when it goes out and making sure that that is probably still going to be sane no matter what the exploit is. Because I think we're reaching a point where the exploits are in We're finding more exploits in the browsers, we're finding some exploits in the servers.
Speaker 2: There's a whole category of like certificate exploits that Is kind of outside the scope of what Django can do. Django assumes that by the time a request gets to it, that a lot of the SSL and certificate termination has already happened. Um if you want to ask what we do specifically We have a group of security reviewers. We have a group of PCI reviewers that look at different things because PCI comes with its own bundle of tricks Um and we also make sure that we are in our chat, which happens to be Slack, subscribing to a lot of security feeds. So as soon as the CVEs get announced, we know and we can get on top of it. And a lot of times We find that because we've been doing security review thinking about what's going in and what's coming out, that we don't need to do much. Um and we also
Speaker 2: don't Django has been looked at by so many eyes and reviewed so many times that oftentimes the new security bugs that are coming out are in semi-obscure parts of Django that we weren't using already. So, you know The answer to your question is constant vigilance, but be try to be aware of your attack surface. And that's why I really recommend people going and watching Kelsey Gilmer Innes ' talk from last year, because she describes: think about your attack surface. Think about if somebody wanted to attack me, who's the most likely person to attack me? And what is their motivation? Where are they going to be coming from? Um at Eventbrite, our attack service is manifold, but To go with the obvious case, people might want free tickets, right? So let's make sure that the
Speaker 2: everything around orders and everything around registration is really tight so that people can't just like willy-nilly get a free ticket. But there are some places where we may not need to focus as much. That was a roundabout answer. Sorry, did I kind of answer your question?
Speaker 8: expanding on all the other things that go with security rather than pre protect against this problem. Because people who uh think about security and say, uh here's the five things I have to protect against, now I'm done miss the whole other side of the p of perspective, which is there are any number of threats out there, think about this in a systemic way rather than just one, two, three, four, five.
Speaker 2: And I'm gonna riff off what you said, which is to say that there are kind of two ways to think about security. One is the descriptive nomenclature way where you try to like Name every possible attack out there and then come out with mitigation steps for every name. And then and then there's like the holistic strategy where it's like, well, we know these are common attack patterns. We know where the attack vectors could be. Let's focus on like building skills that are for these specific patterns I'm not a fan of the nomenclature-specific model of looking at security. I don't care what you call this exploit. I want general practices that will help me in the future.
Speaker 5: Okay, one final question, and then we'll wrap up.
Speaker 8: Thanks for the talk. Are there any tools out there to check that my website that I don't use like pipe safe in templates anywhere? So like
Speaker 2: Say that again?
Speaker 8: Are there tools out there out there to brute for uh to try to brute for most my site in terms of making sure that I don't use pipe safe in templates where I should not? Uh CSF CSRF exempt that's where I should not
Speaker 2: that is a great question. Um I don't know if it was a lead-in question. Maybe you were trying to suggest a tool. Uh there's one that I actually saw that just came out yesterday called brute CSS. That is going to try, you feed it a URL and it's going to try to do a bunch of brute XSS attacks against your site. What we do at um Eventbrite is we do have auditors that try to do some of that for us. We don't have a ton of automated tools to try to check for XSS because our site is very large and very old. And so what we do do is anytime anybody is using anything that looks like that even like matches the character's safe or pipe N, we make sure a security reviewer is right there looking at Making sure that like this isn't vulnerable.
Speaker 2: And the same for CSRF exempt, right? Like if it has CSRF in the name of the review, a security reviewer is going to have eyes on it and is going to have to approve it before it goes out. I'm sure there are tools out there. Feel free to tweet them at that hashtag and I'll retweet them and people can find them. But I keep harping on the same thing of constant vigilance. Just like try to be as aware as possible of what your code base has.
Speaker 5: All right. Philip, if uh people w have further questions for you, it sounds like uh tweeting at you is a good suggestion. Are you gonna be around during sprints? Are you open to folks just coming up to you in the hall and talking about this subject.
Speaker 2: You're welcome to just come talk to me. I will be here with sprints. I will be sprinting with the beware folk. Uh Come get a coin, come talk to me about security. And yeah, I'm always happy to talk about more security stuff or to talk about frog and toad. Uh oh, if you do have feedback Um you can like be you can give me the feedback directly or you can use the guidebook feedback form. This was a bit of an experiment being more story-driven with the talk. I'm curious if people liked it or not. You don't have to tell me right now. I don't want you all like shouting at me. But do leave me feedback, tweet at me, send me email. I don't have my email up there. But you can tweet at me. You can even send me a DM. If you're bad, I'll block you. And that's it. Thank you all so much.
Speaker 2: Uh one uh if you would like more James family uh experiments, uh Nicole James around the corner right after this is giving a talk on beginner workshops. So if you just can't get enough of the James family, go see her workshop or her talk next.
Yes, within reason. Django provides substantial protection against common web vulnerabilities, but developers must use its security features correctly and avoid unsafe bypasses.
Discussed at 1:03Django automatically escapes potentially harmful characters when rendering template variables as HTML, turning injected script-like content into safe HTML entities. Developers should be especially cautious with MarkSafe, the safe template filter, and similar helpers that deliberately bypass escaping.
Discussed at 1:50A CSRF attack tricks a user’s browser into performing an unwanted action, such as deleting a book. Django’s CSRF middleware compares a token from the cookie with one submitted in the request and rejects the request if they do not match.
Discussed at 4:59The csrf_exempt decorator disables CSRF checks for a view, including class-based views when used with the appropriate method decorator. It should be used very sparingly because it removes an important protection.
Discussed at 5:54Django’s ORM keeps SQL logic separate from user-supplied data and passes them separately to the database, which performs the appropriate escaping. Raw SQL features such as extra() and raw() should only be used when genuinely necessary.
Discussed at 8:57Django’s X-Frame-Options middleware prevents browsers that support it from displaying the site in an unauthorized iframe. The xframe_options_exempt decorator can disable that protection, so it should be used only when required.
Discussed at 10:30Host header validation checks the request’s domain against the configured ALLOWED_HOSTS values and raises an error for unrecognized hosts. It must be configured correctly before deploying to production.
Discussed at 12:06On login, Django checks the password against the stored hash and, when a stronger configured hasher is available, automatically rehashes the password with the newer algorithm. This allows security improvements to happen over the lifetime of an application.
Discussed at 12:52Use code review, automated checks for dangerous helpers such as csrf_exempt and mark_safe, security tests, and regular audits. The talk also recommends HTTPS, a Content Security Policy, encrypted fields for confidential data, and Django’s security-related settings.
Discussed at 13:41HTTPS protects data in transit, including users’ browsing and purchase information, and Django provides settings for secure cookies and secure URLs. For an e-commerce site, the speaker considers HTTPS essential despite the certificate cost.
Discussed at 15:13A CSP tells the browser which domains may provide content and can either log or block unauthorized resources. It can limit the impact of unsafe HTML by controlling where images, scripts, and other content are allowed to load from.
Discussed at 16:04Django encrypted fields can protect confidential or personally identifying information in storage when used with a sound key-management policy. Combined with HTTPS, encryption at rest reduces the ways users’ data can be exposed.
Discussed at 16:51Change it immediately, move the replacement into an environment variable, and do not continue using the exposed key. The secret key supports signed cookies, sessions, and password-reset tokens, among other security functions.
Discussed at 20:05Large-volume traffic and DDoS mitigation generally belong at the web-server or infrastructure layer, using additional capacity or caching rather than Django itself. Rate limiting is recommended for legitimate users who may overload the site, especially on API endpoints.
Discussed at 21:30Key management should be understood by the whole team and reviewed for human as well as technical weaknesses. The speaker recommends considering Google Keyzar and hiring a security consultant if the team lacks dedicated security expertise.
Discussed at 22:58No one can predict every future exploit, so the practical defense is constant vigilance: review code, sanitize incoming data, reason about rendered output, monitor security feeds, and understand the application’s attack surface. General secure-development practices are more useful than trying to enumerate every possible attack by name.
Discussed at 30:33The speaker mentions Brute CSS for attempting brute-force XSS attacks, while noting that Eventbrite also relies heavily on security reviewers. Their reviewers inspect uses of patterns such as mark_safe, the safe filter, and csrf_exempt before release.
Discussed at 34:39Note: 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.
Published July 15, 2026
Published July 15, 2026
Published July 15, 2026
Published July 15, 2026
Published July 15, 2026
Published July 14, 2026