Closing session
Published June 13, 2025
This video features Keira and Sky at DjangoCon Europe 2019 in Copenhagen, Denmark.
https://2019.djangocon.eu/talks/pentesting-your-django-apps/
By Keira and Sky: https://twitter.com/RedAndBlackTech
Keira and Sky explain penetration testing as scanning an application, exploiting suspected vulnerabilities to confirm them, and doing so with the owner’s permission to improve security. They argue that Django developers should learn basic pentesting because it helps prevent vulnerabilities, improves code quality, protects users, and provides a practical security skill when budgets are limited, while stressing that it does not replace professional testing. They demonstrate using OWASP ZAP with a Django app and Behave/Selenium BDD tests: run the app over HTTPS, proxy browser traffic through ZAP, then spider and actively scan the application and generate a report. Their Django Goat project provides an intentionally vulnerable app, fixed and broken branches, examples of Django-specific authentication and CSRF configuration, and a template for integrating ZAP into existing tests; they recommend starting with the OWASP Top Ten and testing locally or on a test system rather than production.
Summarised automatically from the transcript.
Automatically transcribed, so expect mistakes in names and technical terms.
Speaker 1: Anyway, without further ado, I would like to invite our next speakers to the stage. We have a pair of speakers on this one, Kira and Kira and Skye, uh talking about pen testing Django applications. Everyone, please welcome to the stage.
Speaker 2: So hi, I'm Kira. This is Sky And we're both Django developers, but today we're here to talk to you about pen testing. So we want to tell you how to ordinary, completely ungifted Self-taught developers can get into pen testing and why we think you should try to. Before we move on, the slides are up on our GitHub for anyone who needs to follow on on their own device So we care about security. We think it's interesting, we worry about our users, but more than that, Sky and I need to care about security. Because in our own time for love, we run a free, not-for-profit, zero-budget application that supports activist groups.
Speaker 2: So we need to. And we think this is a pretty common problem across Django and across other communities. So we wanted to share our solution. So before we do, a few caveats We're not security professionals. We're just developers. And we can't make you a security professional either. So I hope you get something out of the talk, but don't go updating your LinkedIn profile just yet. Okay. And we don't want to talk anybody out of using professional security services. So if you have access to professional securities either uh in a prevention team, in a local team, or as pen testers, please use them. But we don't all have access, and so we think it's pretty valuable for developers to learn anyway.
Speaker 2: So what the next 20 minutes will look like, I'm gonna tell you what penetration testing is Sky 's going to tell you why we think you should learn it. We'll both show you what it looks like to use it with a Django app in a BDD test suite. And we'll tell you a little bit about how you can start learning So what is it? So it's short for penetration testing. And like any other tech issue, there are a lot of opinions, there's a lot of different definitions. We're going to be talking about it at its most basic. And what we generally agree on is it includes these four things. So a scan of your application for vulnerabilities. This can be automated or a code review or a mixture of both, but it includes a scan.
Speaker 2: Skipping ahead. Uh attacking to exploit those vulnerabilities and prove that they exist because you can get some false positives With the purpose of securing your app and with the permission of the owner of the app. And those last two are really important. We've already heard a few laughs. If you don't have those, you're just hacking. It's probably illegal. There will probably be consequences. You'll probably get caught. Just don't do that. And the last thing to keep in mind with the definition is what it isn't. So it's not perfect. It's not a security panacea, especially when done by an amateur. However enthusiastic.
Speaker 2: So be careful. And there's a really good quote I like that explains this. So I'll let you read it. So for anyone who can't quite see it, it says, if you fail a penetration test, you know you have a very bad problem indeed. If you pass a penetration test, you don't know that you don't have a very bad problem. That aside, we think it's absolutely worth doing, and Sky is going to tell you why. So
Speaker 3: why should we as developers learn to pen test? Developer unemployment is low, pretty much every developer who's looking for a job manager. manages to find one fairly easily. Generally speaking, we have more work to do than we have time to do it in. And our tech is constantly changing. We're constantly having to learn about new tech and existing tech as it changes. just to stay relevant in the jobs that we do. And because we're so busy, our clients and our bosses really aren't pushing us at the moment to learn pen testing or these sorts of security skills. So why is it worth our time to put in the effort to learn yet another new thing? Well, we think there are a lot of really good reasons to do this. And the first is knowledge.
Speaker 3: So knowing about what vulnerabilities are, how they work, how they're exploited, what they look like, puts us in a really good position not to create them in the first place as developers when we write code. Django does a great job of protecting us from introducing most sorts of vulnerabilities into our code, at least when we're doing the fairly sort of vanilla basic tasks. But the more complex our code gets, the less able Django is to protect us from every single vulnerability that we can introduce. So if we know what the vulnerabilities are, what they look like, we're in a much better position not to introduce them into our code And there's budgets. So we all know that there's a lot of money floating around in tech right at the moment. But like the rest of society, that money's not evenly distributed.
Speaker 3: Outside the hot startups and the unicorns, the rest of the internet runs on a budget. And most of those budgets don't include as much money for security as they possibly could or should. And so if as developers we can pick up some pen testing tools, some pen testing skills, we're in a position to improve the security of our code without necessarily being able to control the budgets And there's fun. So just ask any little kid. Breaking stuff is fun. And at its most basic, that's what pen testing is about. It's about breaking stuff. So it's a lot of fun and it's interesting as well. And then on the flip side of fun, we've got fear.
Speaker 3: So who here wants to be responsible for a data breach on a project or an app that you work on? And of course that's a rhetorical question because none of us want to be. So learn some pen testing, do some pen testing, and you can relax a little bit more about uh the quality of the code when it comes to a security perspective. One of the unexpected consequences that we found of learning pen testing was that it actually improved the overall quality and cleanliness of our code. So Pentesting tools interact with your app in ways that you as developers and we as developers wouldn't expect. They do things that ordinary human users just wouldn't think to do. And so as a result, they
Speaker 3: turn up not just security vulnerabilities and security issues, but they turn up just plain boring bugs as well. So when we run pen testing tools over our code. It crashes it. Which is great because when you know about a bug, you can fix a bug. And you can fix it at a time that's convenient to you rather than at a time when it pops up unexpectedly So pen testing not just gives us more secure code, but it gives us better quality, cleaner code as well. And then there's empathy because we care about our clients and our users. Sure, they're the ones that find weird ways to break our apps, but they're also the people that pay our wages and they're the reasons that we have the jobs that we have.
Speaker 3: So when we talk about security We're really talking about the security of our users because it's the users whose accounts are compromised when something goes wrong It's the users whose data and credentials leak. And in the worst cases, it's the users whose identities are stolen and whose computers are ransomware. So they're the reasons that we do what we do, and we want to make sure that bad things don't happen to them. And then we get responsibility, which is the main motivation for Kira and I in in terms of learning pen testing. So it's 2019 and software is infrastructure now. Before we were developers, I was in construction engineering, Ciara worked in the public sector.
Speaker 3: When we look at software, we look at it the same way that we look at a bridge or a government. Our lives and our societies rely so heavily on software And we're the people that build it. And so we have a really good and possibly a unique perspective on how important it is that it be secure. Which means that we need to act before necessarily anyone else is telling us that we need to, to try and make our software as secure as we can. And Bruce Schneier has a quote that puts it really well And he says, this is bigger than computer security. Technology now permeates society in a way it didn't just a couple of decades ago. That means that technologists now are relevant to all sorts of areas that they had no traditional connection to.
Speaker 3: Climate change, food safety, future of work, public health, bioengineering. And there are more.
Speaker 2: So what does it look like? Hopefully you're convinced that you want to go do it, but what does it actually look like to use pen testing tools with a Django app? So it can be using something manually and there's a lot of tools. You can increase integrate it with your BDD test, it's just what we do. Or you can even integrate it with CICD if you've got that going on So for us, we are using Zap, which I'll explain in a second, integrated with BDD tests. And to show you what it looks like, we've actually built an intentionally vulnerable Django app, which we'll show you at the end that you can use to test it. that includes the BDD tests and the integration tools that you need to get Zap working. Okay, so introducing ZAP or ZATAC proxy
Speaker 2: So it's a free open source tool from OWASP, which is the Open Web Application Security Project. We like it because it fits nicely with automated BDD tests. It gives clear, actionable alerts. It's quite easy to see what it is that's gone wrong. And we're busy and it saves us time from learning a full set of manual red teaming skills So we'll get to how it works in a second, but what does it actually do? So it scans your app, it does a spider, it finds all the URLs, it checks the code over for vulnerabilities, and then it attacks your code. So it it pretends to be a user, it puts in all sorts of weird input, and you get alerts. So the alerts look like this. You probably can't read it, that's fine.
Speaker 2: But it has color coding for the severity of each alert. And if you were to click on one of those, it shows you what the issue is, the request and response where the issue was generated, the HTML that was generated when it happened, so you can check that it really did happen. And it also has links back to OAPRI-OWASP resources so you can understand how to remedy the problem And if you get to the end of a scan, it also puts all of these alerts together in one document so that you've got a report of all of the problems. So that's pretty useful in a team if you need to share it. And so how does it work? So it's an intercepting proxy. So for those who aren't always across it, when someone's using the internet, it looks a bit like this. So there's a user using a browser, the browser's communicating with the server, the server's serving the app's content.
Speaker 2: And Zap goes in between as a proxy between the browser and the server. So it can see and analyze all of the traffic between the browser and the server. And when it's doing that, it's looking for vulnerabilities and it's called a passive scan. But it can also run active scans or attacks. And that looks like this. So when it's running active scans, it's impersonating a user and it's cutting the browser out of the picture. Okay, and again, you can't read this, you're not supposed to. This is just to explain it's really powerful and it's fairly complex. It has a lot of options. It has menus, sub-menus, sub-submenus It's extremely configurable. But to their credit, they've also made it really easy to use as a person with no prior experience. So you can use it through the GUI
Speaker 2: And that's as simple as giving it a URL, pressing the attack button, and waiting for your report. It's really very simple. Which is great. And if you want to go further than that, further than a manual, you can do what we've done. And it has Python bindings, so you can script it pretty easily. And a quick note for this section, we're going to be talking about testing. If you don't know anything about testing, don't stress, we'll get back to more beginner content at the end. Okay, so for those who do know, this is a pretty ordinary testing workflow. So we use Behave , it starts the test, it runs the BDD tests. Selenium is running our web driver, it's our web driver, sorry, running Firefox. And we're using GUnicorn. And so we just slip
Speaker 2: zap in between Firefox and GUnicorn. We start it with Behave. And we start it in as a proxy. It's really important to know you need to start it before you run the BDD tests. That's a important tip. Because Zap learns about your app while it watches the traffic. So you want to show it what your app does and where all the pages are. It will spider, but you get a lot better results if you let it watch your tests. And the last thing is we serve it over HTTPS. So that's one of the reasons we're using GUnicorn here. Because you want to test your app as close as it is to production. So that's one reason. But also because you get a lot of false positives in your zap alerts if you are testing on HTTP. Okay, so it's not trivial to get it set up, but it's not too difficult either.
Speaker 2: It's mostly about connecting things up. So this is the part where we're reaching for those developer tools, the string, the duct tape, the copy-paste.
Speaker 3: So I'm going to talk about how you bring zap into an existing BDD test suite like the one we've just shown you. The Django Go app that Kira mentioned. Has Zap coming in in a single commit. So what I mean by that is that we built it so that we had a Django app with a set of BDD tests. And then in a single commit on top of that, we brought in everything that brings Zap into your app. So we're essentially trying to sort of give people something that is a bit of a template for the projects that you might have To show you exactly how to bring Zap in in one sort of easy movement. And we're about to show you some code snippets, which are based on the Django Goat app, but they're simplified down quite a bit so that they fit on the projector screen and so that we don't have to explain them. in too much detail.
Speaker 3: Behave has an environment. py file which gives it instructions for how to run BDD tests and what to do before and after. And in that environment. py file you'll find a before all function. If you're familiar with behave at all, then you're probably already using this to start up your browser automation. And you can see on the last line there that's what we're doing with starting Firefox. But we also slot zapping just before that. You can see the start zap function. So that's the first thing we need to do. We need to start zap up and here's how we do it. It's really simple. Two lines. So we use Python's subprocess module to kick zap off. That's the Zaproxy command that you can see there. You can pass it in with or without the daemon flag that you can see second in that list.
Speaker 3: To start with, it's probably a good idea to leave that off because then you can see the zap window running and you can see exactly what it's doing. But once you've got everything tuned up and working well, then you might as well take that out so that it gives you a it gives you a clearer screen The second line there you can see a sleep statement because this isn't uh this uh zap doesn't block when it um when it starts running, so we just need to give it a few seconds to get started before we kick off the next process. which is our browser automation. So this is a start Firefox function and it's probably similar to one that you've got in your BDD test already if you're doing that. But there's a difference, and that's that's the um the comment in the middle that you can see there that says set proxy config here. So because Firefox has to proxy through zap.
Speaker 3: We need to add in the proxy settings the way we've done there. There's a bit to that, so we've cut it out from this slide. But if you go to the Django Goat app, you'll see exactly how we do it And so that's all we need to do to get uh to get things running before the BDD test. So we've got Zap running, uh we've got Firefox started. Actually I should mention there's um there's A lot of instructions on the web for the old way to set up proxying with Selenium. And a lot of those won't work now with Firefox. So you need to do it the way that we do it in Django Go. Just check out the code there and you can see some functioning code So once this all starts up, the Zap runs the behave tests, uh the BDD test rather. And then once they finish, it goes looking uh behave
Speaker 3: goes looking for the after all function And this is where we kick off the zap scan. This is much oversimplified, but it shows you the key points of what we're doing when we start Zap up. So the first couple of lines there you can see we're just connecting to Zap using the Python bindings and giving it the URL of our app. And then we kick off Zap's Spider. So Our BDD tests have run and Zap's been watching them go, so it's got a pretty good idea of what the URLs are for our app. But our BDD tests may not have had every single URL in the app. And so we get Zap to run the spider, and the spider just picks up any loose ends, any URLs that it didn't see as the BDD tests were running. And then we run the active scan, the Zap
Speaker 3: Active Scan. And this is kind of the heart of of um of Zap's of Zap 's functionality. So It's essentially impersonating a malicious user and trying to break your app. And the active scan will run for anywhere between a few minutes and a few hours, depending on the size of your app. and depending on how aggressive the settings are for the scan. So then you'll see the last couple of lines. We're just writing out a report once the active scan finishes. And that's it. And that's the test finished. So let's have a quick look now at your unicorn because as Kira mentioned we set that up to run over HTTPS and luckily it's a pretty simple thing to do. So you can do it in two lines. The first line there generates a self-signed SSL cert and key and then the second line passes it into the Unicorn.
Speaker 3: Once that's done you'll have your up up you'll have your app up and running over HTTPS Now looking at Zap. So Zap is not built specifically for Django or for any framework. And that means that to use it with Django, we need to sort of tune it a little bit with a couple of customization scripts. And we've written these and saved them into the DjangoGoat project where you can look at them. There's essentially two things that we need to customize. One is the way that Zap handles authentication So the first script does that for Django. And the second is the way that it handles CSRF and interaction with forms. And that's what the second script does. We don't have time to go into exactly how those scripts work at the moment, but they're there in the Django Goat project for you to look at.
Speaker 3: And that brings us to the next point. Which is that you don't need to reinvent the wheel to bring Zap into your projects. It's taken us a fair bit of time and research and trial and error To get all this to work properly. But we've distilled down everything that we've learned into the Django GOAT test suite. And so everything there is connected together and working well. And it's there on GitHub for you to use as an example or sort of a template. um so that you can know how to bring Zap into your existing test suite.
Speaker 2: Okay. Woo, wrong way. So where do you get started? First we want to talk about when you want to get started. If you plan to do this, the time to get started is now or as soon to now as possible. The last thing you want to do is have to do something like this and learn all of the extras just after a breach because somebody has tasked you with finding what happened. So do it now when it's just a normal level of dysfunction. It's true. So and how? How do you should you start? So if you haven't already seen them before, we highly recommend reading the OWASP Top Ten. So for anyone who hasn't heard of it, it comes out every few years. The most recent one was 2017.
Speaker 2: And they do a review of the web and they tell you the top ten most common vulnerabilities in web applications. includes things like SQL injection and cross-site scripting, a whole bunch of others. Eight others. What's useful is it goes into detail about what that looks like. How to work out whether your application might be vulnerable to it and how you might fix it. It's all pretty great. Obviously, we also recommend OWASP. ZATAG Proxy. If you are going to start that on your own, we also suggest that you use the video tutorials. They are a lot easier to follow than some of the written documentation. It's good, but the videos are easier. And in particular, you should look up Simon Bennett's. He's are the clearest.
Speaker 2: And the testing guide So anyone in charge of tests, if you plan on integrating uh any type of penetration testing into your existing CICD, we definitely suggest reading the testing guide. It's 224 pages, it's not exactly a quick read. But it does go through all of the different uh testing methodologies that you might use and why you would integrate tests into certain parts of your life cycle. So it's worth doing. Okay, and you can try our app. So, Django Goat. So it is at our uh GitHub. We'll put the link on at the end. It has a broken branch and a fixed branch so you can see what we've done and we've added each vulnerability in a single commit so you can actually see what we broke. And it has all the integration tests.
Speaker 2: So we invite you to Have a look at it, run scans on it, see what you're doing, mine it for code, whatever you like. And something to note, it explains each vulnerability. In a amount of detail, it tells you where in the code we broke something and it links itself back to the OSP Top 10 documentation and sometimes to the Django documentation where it's relevant so you can see what we've done. And it has instructions. We think it's beginner-friendly and junior friendly. If you have any trouble though, just get in contact. We're available. And come to our workshop. So we're running a workshop that teaches you how to do this hands-on on Sunday. Right here. And just as a coincidence, our next two slides are almost exactly the same as Carlton's from yesterday. Uh we didn't rip them off, it's just great minds thinking alike.
Speaker 2: So you are good enough. We really do think so. We are self-taught, we are not special. We're not even special as developers, we're not gifted. And we've managed to learn how to do this, you are good enough, you can learn how to do this. You can do it. So pen testing, that is, although probably you're good at lots of other things. So that's it. So you can contact us via Twitter. We're Red and Black Tech. This is our GitHub. We only have two projects. You will find Django Goat and also the conference slides if you'd like them. And so that's it, we'd like to say thank you.
Speaker 1: Thank you very much, Kira and Skye. We have time for a little a few a couple of questions. So if you do have questions, find your way to the microphone. Or if there are any any on the internet you don't want to ask the question yourself, you can jump on the the Slack channel or you can jump on uh on Twitter but it looks like we're gonna have someone at the microphone so here we go Yep.
Speaker 4: Yeah. Thanks for the talk. I wanted to ask uh how do you run it on iterative manner like in continuous integration because uh it could uh took a lot of time to perform all this check-ins scanning etc so some points about this So
Speaker 3: she heard sorry.
Speaker 2: One second.
Speaker 3: Thought I left that on. That's up now, isn't it? Okay. Um if you've already got we sort of we make the assumption that there's already an existing BDD test suite uh that you have. And so presumably that runs through your CI and you just integrate it into that. It just bolts directly into your existing BDD tests.
Speaker 2: That's it. So we don't use Jenkins, but we understand that there are Jenkins, there's a Jenkins integration toolbox somewhere. So sorry.
Speaker 3: Does that answer your question?
Speaker 4: Uh no.
Speaker 3: Okay.
Speaker 2: Sorry. Hi
Speaker 5: there. Um I would like to know the following. I would of course want to do the penetration test to my real system because I want to know if the real system, the production system, is secure. But on the other hand, penetration testing is about like uh penetrating the system. So how can you solve this contradiction and perform the tests without breaking your site?
Speaker 2: So our answer to that is if you need a penetration test on your real production database, leave that to the experts. uh we would not recommend using an automated tool because among other things it does attack, it might drop tables, it might inject all sorts of stuff, it will create users, it makes a huge mess. So And I actually, if you come to the workshop, we'll go into it. But two things to note just briefly, yes, don't use it on a production server. Don't use it on anyone else's server. So we run it locally, we run it on localhost, that's what we suggest you do If you have a test server, feel free, but even then. And the most important thing is you need to use a proxy if you set it up manually. If you set it up with our scripts, it's fine. If you use it manually Make sure you're using a proxy on your browser or your IP will be banned from your servers
Speaker 2: and potentially from all of Cloudflare. So be careful. So yeah, don't don't do it on your direct production database.
Speaker 5: Yes, but then how far Or is this a valid test if you do it locally? Is that really comparable to the life situation? I mean can I then really be sure that this is enough? Uh
Speaker 2: no. No. No. So it's not it's no it's not comparable, no. And I think if you if you're really worried that's where we need to pay, it's a stop gap for people who don't have any budget.
Speaker 5: Thank you so much.
Speaker 2: That's okay.
Speaker 6: I thank you for the excellent presentation. This model of presentation as four hands is really wonderful. My question is uh obviously in a small team, a small startup, a single project, the programmers have to be the one-man band and do everything. In a more structured companies where we have a QA team, in which side should land the responsibility responsibility for the pen tests. Programmers should do it and deliver it to the K18 like they have nothing to do in the ideal world. Or programmers should be doing the unit tests and leave the rest for the QA
Speaker 6: team.
Speaker 2: So I'm not sure we think it should be developers' responsibility I think if you're in a big enough place where you've got a QA team, I think this is fairly clearly in their wheelhouse. And if you've got a security team, it's obviously theirs. But I think part of our argument is that it's worse learning anyway, just for your own skill development. Because you see things that you Uh maybe only hear about theoretically otherwise, but it's and it's also quite fun. You actually get to conduct yourself a SQL injection attack, see if it works. It's pretty good.
Speaker 1: Out of time now, so uh thank you very much and uh thank you Kieran Skype. Thank
Speaker 2: you.
It involves scanning an application for vulnerabilities, attacking those vulnerabilities to verify they are real, and doing so with the application owner’s permission to improve security. It is useful but not a guarantee that an application has no serious security problems.
Discussed at 1:59Understanding vulnerabilities helps developers avoid introducing them, especially as applications become more complex than Django’s default protections cover. Pen testing can also improve code quality by exposing ordinary bugs, reduce the risk of breaches, and provide security improvements when budgets are limited.
Discussed at 4:08ZAP acts as an intercepting proxy, observes application traffic, spiders the application to find URLs, checks for vulnerabilities, and performs active attacks using unexpected input. It reports issues with their severity, the relevant request and response, evidence of the problem, and links to remediation guidance.
Discussed at 10:35Start ZAP before the Behave tests, configure Selenium/Firefox to proxy through it, and let it observe the test traffic. After the tests finish, connect through ZAP’s Python bindings, run its spider and active scan, and write a report; the speakers recommend using HTTPS and provide working examples in the Django Goat project.
Discussed at 13:43Start with the OWASP Top Ten to learn common vulnerabilities, then use OWASP ZAP and its video tutorials. The speakers also recommend the OWASP testing guide, their Django Goat vulnerable application, and a hands-on workshop.
Discussed at 20:45No: automated scans can create users, inject data, drop tables, and otherwise make a mess, so production testing should be left to security professionals. Run the tool locally or against a test server instead, and use a proxy when configuring it manually.
Discussed at 26:25No. Local testing is not comparable to a live production assessment; the speakers describe it as a stopgap for teams that do not have the budget for professional testing.
Discussed at 27:30If a company has a QA team, penetration testing fits naturally within its responsibilities, and a dedicated security team would clearly own it. Developers should still learn the skills because it improves their development abilities and gives them practical experience with vulnerabilities.
Discussed at 28:29Note: 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 June 13, 2025
Published June 13, 2025
Published June 13, 2025
Published June 13, 2025
Published June 13, 2025
Published June 13, 2025