Security Best Practices for Django Applications - Gajendra Deshpande
Published April 11, 2023
This video features Gajendra Deshpande at DjangoCon US 2021 in Online.
In this talk, we will focus on two aspects. First, performing penetration testing on Django web applications to identify vulnerabilities and scanning for OWASP Top 10 risks. Second, strategies and configuration settings for making the source code and Django applications secure.
This talk was presented at: https://2021.djangocon.us/talks/securing-django-applications/
LINKS:
Follow Gajendra Deshpande 👇
On Twitter: https://twitter.com/gcdeshpande
On GitHub: https://github.com/gcdeshpande
Website: https://gcdeshpande.github.io
Follow DjangCon US 👇
https://twitter.com/djangocon
Follow DEFNA 👇
https://twitter.com/defnado
https://www.defna.org/
Video production by the speaker and DjangoCon US 2021 Volunteers.
Gajendra Deshpande explains how to secure Django applications by applying production settings, validating input, protecting authentication and sessions, encrypting sensitive data, enforcing access controls, and maintaining strong logging and monitoring. He relates Django security practices to the OWASP Top 10, covering injection, broken authentication, sensitive data exposure, XXE, broken access control, misconfiguration, XSS, insecure deserialization, vulnerable dependencies, and insufficient monitoring. He also introduces tools and resources including DJ Checkup, Django Hunter, Django Goat, Shodan, and Django’s security documentation, while stressing that users share responsibility for protecting accounts and data.
Summarised automatically from the transcript.
Automatically transcribed, so expect mistakes in names and technical terms.
Hello everyone, my name is Gajindradesh Pandey and today I will be presenting a talk on securing Django applications. So in my talk I will be discussing about security aspects of Django applications, then overview of OAS top 10 risks, then Django Hunter and Django Code projects. the strategies and configuration settings to make Django applications secure. Now let us first look at a website called as djcheckup. com It's a website basically which will help you to identify the security risks in a Django web application. So it's a very simple application. Very simple to use. You can just specify the website's URL here and you can click on run checkup on my site
button. Now we have tested it on some uh Django web application and you can see here that it shows uh some of the uh issues. Uh right now there are no issues present on this uh site so uh everything is in um uh green color but if there are any issues then it will highlight it in uh uh red color Now there is a file called as settings. py where you need to make some settings. So basically when you are going for a production of the application, you need to disable the debug parameter to false. So what happens if you set it to true is
uh hacker can get the error message and through that error message he can or she can get the additional information which can be used to carry out the further attacks Then second important thing here is that you need to keep the secret key secret. You should not share the secret key with anyone else or any application Now there are 10 vulnerabilities which OASP project highlights. So OASP stands for Open Web Application Security Project. So first one is this injection, then broken authentication, then sensitive data exposure, XML internal, XML external entities. Then broken access control, security misconfigurations, cross-site scripting, insecure
deserialization , then using components with known vulnerabilities, and finally insufficient logging and monitoring. So if you look at these top 10 vulnerabilities, some are related or some are present in the source code, some are related to the configuration settings, and some are related to the logging and monitoring. So we will discuss these issues one by one First one is the injection attack. It is the most common type of attack where the malicious user is able to execute arbitrary SQL code on a database. So this can result in records being deleted or the data leakage.
So injection vulnerabilities are often found in SQL, in LDAP, in XPath, or even in No SQL queries In XML parsers, in SMTP headers, and also in expression language and ORM queries So injection can result in data loss, corruption or disclosure to unauthorized parties. So loss of accountability or denial of access. Injection can sometimes lead to complete host takeover. Now you can see here an example where a SQL query has been written. So the first uh query is a genuine uh query. Now you can see the second line.
So what we are doing here is after ID, we are adding additional So we are using a Boolean operator called as R and we are saying one equal to one. So that means whatever may be the left hand side query, always this query is going to return the records from the database. Of course this is not so simple. Attackers usually use advanced attack vectors to get the information. So the solution here is to validate the user input. Now there are two functions in Django, one is extant, second one is RAW SQL Uh these enable developers to write custom queries in Django.
Now the protection from SQL injection is possible. The first solution is that query parameter you need to parameterize the SQL queries and it is By default available in Django. Then whenever you are using extra and raw SQL, you need to use it with caution because it allows you to write custom SQL queries. Then use positive or Server side input validation. It may not be a complete defense, but it will help you to mitigate the risks of injection attacks. Then second one is the broken authentication. So here as we know that attackers have access to the hundreds of millions of valid username and password combinations for credential staffing, default administrative
account lists and automated brute force and dictionary attack tools and We are aware that most of the data is available in the dark web. So they may get the data from dark web. And also session management attacks result in broken authentication. Now one important thing here is that attackers don't need to Have access to hundreds of accounts. So they just need to gain access to one account that is the administrative account. So if they get the access to the administrative account, then they can do whatever with respect to other accounts. So usually attackers focus on gaining access to the administrative accounts or super user accounts.
Then one more problem for broken authentication will be application session timeouts are not set properly. Say for example if you are browsing in a public place then you may leave that session uh maybe accidentally so in that case if application session timeouts are not set properly then uh any third person can Start using your application for some other purposes. May not be for legitimate purpose. Then most authentication attacks occur due to the continued use of passwords as a sole factor So the solution here is that you can go for multi-factor authentication. So we know that now most of the email service providers
or many applications they provide two-factor authentication and sometimes they also provide single sign on option so you need to deploy uh these features in your application then you can also check your application against Weak password checks such as testing new or changed passwords against the list of top 10,000 worst passwords. Then ensure registration, credential recovery, and API pathways are hardened against account enumeration attacks by using the same message for all outcomes. Now in Django you can use the uh packages such as Django
OTP for two-factor authentication. So you can also use Django 2 factor or package. Then for sessions management you can use Django User Sessions package. So basically Django OTP and Django 2 factor authentication packages they send an SMS or they may send a code to either to your mobile phone or to your email ID So that you need to enter in your application. So once you enter then only your application will be validated and it will all it will give you the further access The next is the sensitive data exposure. So in this case what happens is
uh that rather than directly attacking the crypto attackers steal keys execute and in the middle attacks Or steal clear text data of the server while in transit or from the user's client, say for example the browser. So here a manual attack is generally required So here an application encrypts credit card numbers in a database using automatic database encryption. So some databases when you Select these options so they automatically encrypt the data and store the um data in the encrypted form and some allows and also the programming language allows the encrypt functions which can be used to store the data in an encrypted format in the database
So the data is automatically decrypted when it is retrieved, allowing as SQL injection flow to retrieve the credit card numbers in the clear text. So this is the problem when you are working on a compromise system, but Scientists are working on this problem and they have come up with a solution called the homomorphic encryption, which allows you to perform computations on encrypted data. So even to perform computations computations you need not have to uh decrypt the information but uh Still this area is in its infancy, so a lot of research work is going on, but the present methods are highly computation intensive
Now, a site doesn't use or enforce TLS for all pages or supports weak encryption. Then a password database uses unsorted or simple hashes to store everyone's passwords. So these are some of the use cases. Then the solution is that classify data processed stored or transmitted by an application, then identify which data is sensitive according to privacy laws, regulatory requirements. or business needs. Then apply controls as per the classification. Then don't store sensitive data unnecessarily. So discard it as soon as possible. Then make sure to encrypt all sensitive data at rest. Then ensure up-to-date and strong standard algorithms, protocols, and keys are in place. Use proper key management.
Then encrypt all data in transit with secure protocols such as TLS. With preferred uh forward secrecy ciphers and cipher prioritization by the uh server Then disable caching for response that contains sensitive data. Then store passwords using strong adaptive and sorted hashing functions. Now these are the some of the settings which you can make in your production. py file. Say for example you have to set most of the features to prove because they are all related to the uh security then you need to enable https instead of http
Then to protect against sensitive data exposure attacks, you can use these again Django modules such as Django encrypted model fields. Then you can go for Django cryptography and also Django Furnet fields The next one is the XML external entities. So if you have worked with HTML, you know that to print the special symbols usually the entities are used. Now one advantage of using XML is that it allows you to create your own tags, it allows you to create your own attributes and also it allows you to create your own entities. So this flexibility itself
can be used by the attackers to perform this XML external entity attack. So you can see here what attacker does is that he is trying to create an entity called as XXE which is map to a file called slash etc slash password. So here the attacker is basically trying to extract the data from the server. So how it is done is whenever he says ampersand access is semicolon So it tries to print the information from data file or it tries to extract the data from slash ctc slash password file. Then an attacker can also link the entity to a server's private network
So here you can see here here you can see that the XXE entity is linked to IP address and slash a private directory. Then an attacker can also perform denial of service attack by including the URL of a potentially endless file. So here random file is just a random file which is endless. Now to protect against XML, uh use the less complicated data formats such as JSON. So JSON has got lots of advantages over XML in terms of space and in terms of also processing. Then disable XML external entity and
DTD processing in all XML parsers in the application. So basically you can use validators here. You can use XML validators, you can use DTD validators Then implement a positive server side input validation for filtering or sanitization to prevent hostile data within XML documents. Headers or nodes. Then also verify that XML or XL XSL file upload functionality validates incoming XML using XSD validation or similar. So basically You need to use the different validation tools available in your editors. Say for example XML validators, XSD validators, XSL validators And also DTD validators. So which will
check the structure of a file, structure of XML content with the rules defined Maybe rules maybe with the rules of the language or maybe against the rules of the XD schema or even the DTD file. Then you can also go for a software called as Shadow Demon, which is nothing but the collection of tools to detect record and block attacks on the web applications So it's a free software. It supports Python language and its frameworks such as Django and Flask. And it also supports other languages such as PHP and Perl. The next attack or next was
brisk is broken access control. So here the application uses unverified data in a SQL. Call that is accessing the account information. Say for example here the parameter is account But it is not verified. So any account can be specified here. In the URL, you can see our account is equal to not my account specified. So not my account is the unverified account So it is possible that if the accounts are not verified, then attackers will simply gain access to these accounts, legitimate accounts, and they can cause the damage. So basically here the unauthenticated user can access the
account of a legitimate user So this is the flaw. Now to protect against broken access control , it is enforced in a trusted Server-side code or in a serverless API where the attacker cannot modify the access control check or metadata. Now disable web server directory listing and ensure file metadata and backup files are not present within the web roots. So basically don't store the files in their default root directory. So you can customize it and you can configure it in your web server That some other directory is a web route. Then log access control failures, alert admins when appropriate.
So you can put all these uh different alert mechanisms then you can go for Django user management so based on the user's role you can assign the different features for managing the accounts. Then security misconfiguration. So this is Again, an important factor. Your application may be secure, but if it is configured But if it is if it is not configured properly, then it becomes vulnerable. So basically attackers will often attempt to exploit unpatched flaws. Or access default accounts, unused pages, unprotected files and directories to gain unauthorized access or knowledge of the system.
So generally, what happens is people who are not from technical background, people who don't have a uh background of computer science and those who are not aware of security features. So when the accounts are given to them, they basically use default username and passwords So since these are default username and passwords, this information is available publicly. So anybody can simply guess and perform, they can use these credentials. for uh illegal activities. Application server comes up with the sample applications so that are not removed from the production server Then direct listing is not disabled. So these are some of the cases for security misconfigurations.
Then the solution is that you need to harden the Django so harden the Django means don't use the default settings customize it customize the settings to the maximum to the maximum extent. Then disable directory listing. Then use automated scanners to identify the vulnerabilities And once you get the vulnerability list, you can try to resolve them. Then customize error messages to height sensitive information. This is important because error messages also Reveal the information about the system. For example, operating system, its version, browser version, and so on. So it is better to customize their messages to highly sensitive information
The next one is the cross-site scripting. So here the application uses the untrusted data in the construction of the Now you might have visited some websites where you might have seen that the that website has a search um Box and when you write a simple JavaScript code such as alert of hello and it gets executed instead of searching. So if it displays the alert dialog box, then that means that There is a cross-site scripting vulnerability present. Okay. So now the attacker modifies here in this example, the attacker modifies the CC parameter in the browser
with uh say document dot uh cookie parameter so here basically the attacker is causing the victim session id to be sent to the attackers website allowing the attacker to hijack the users current session. Basically here the attacker is performing session hijacking attack. So they use XSS, that is cross-site scripting, to defeat any automated cross-site request forgery defense the application might employ. Now, to protect against cross-site scripting, if you are using Django, then Django templates by default protect you against the majority of access
attacks, but there are some exceptions Say for example in this case here is a valid syntax in HTML, but this also This is also a vulnerability because this approach is not entirely foolproof. So it will not protect you against cross-site. scripting so this particular uh syntax so it is also important to be particularly careful when you are using ease with the custom template tags, the save template tag and the marksave and when auto scope escape is turned off. Then you should also be very careful when storing HTML in the database, especially when that HTML is retrieved
and displayed. Then the next attack is insecure deserialization. So applications and APIs will be vulnerable if they deserialize hostile or tampered objects supplied by an attacker. So this can result in Two primary types of attacks. One is object and data structure data attacks where the attacker modifies the application logic. and achieves arbitrary remote code execution. So if there are classes available to the application that can change behavior during or after the deserialization. Then second one is that the data tampering attack such as access control deleted attacks where existing data structures are used but the content is changed So serialization may be used in the applications such as RPC or inter-process
communication in case of databases, caching. Servers and file systems, and also HTTP cookies and HTTP form parameters and API authentication tokens. Now to protect against insecure deserialization attacks. is not to accept serialized objects from the untrusted sources or to use serialization mediums that only permit primitive data types So implementing integrity checks such as digital signatures on any serialized objects to prevent hostal object creation or data tampering. So for that you can use Django J Signature module Then enforce strict type constraints during deserialization.
Then isolate and run the code that deserializes in a low privilege environment. When possible, then important thing is lock these serialization exceptions and failures. The next attack is the using compounds with known vulnerabilities Now note here that when we use open source software by default or most of the times the open source software and its frameworks are secure. Say for Django framework is secure by default. But the modules may not be secure because they are developed by the Third party, they are developed by the community members. So we are not sure that the community members are aware of the security standards.
So the solution uh so the problem is that these compromise components provide the backdoor entry. Uh to the attacker. So the solution is that there should be a patch management process in place. Then remove unused dependencies, unnecessary features. Compound files and documentation. Then continuously inventory the versions of both client side and server side components. So they must nice. Then you can also use dependency check tools then only obtain components from the official sources over the secure links this is very very important then you can also use the tools such as showdown and Django hunter which will basically help you to identify the vulnerable
code in your application. The next is insufficient logging and monitoring. So exploitation of insufficient logging and monitoring is the bedrock of nearly every major incident. So attackers rely on the lack of monitoring and timely response to achieve their goals without being detected. So one strategy for determining if you have sufficient monitoring is to examine the logs following penetration testing So the testers' actions should be recorded sufficiently to understand what damages they may have inflicted. Now to for this the solution is that use and deploy appropriate uh logging and monitoring tools
So this is very very important. It will help you to identify the problems and get the solution for the same Now Django Hunter is a tool designed to help identify incorrectly configured Django applications so that by exposing sensitive information. It's a open source you can Download the repository from GitHub and you can use Python 3 command and specify the Django Hunter. py file Then you need a key from the Shodan. So Shodan is not a free service, but you can pay some amount to get a limited access.
Then you can also use Google Docs uh to identify the incorrectly to identify the incorrect uh configurations The next is Django code. So it's a intentionally vulnerable Django application which will help Django developers to learn security testing. Again, the repository is available on GitHub. So those who are interested to learn more about penetration testing of Django applications, they can explore the Django goat project. Then apart from these two applications, the Django security resources are also very useful.
So You can just visit this URL. That is awesome. Django security. You can just Google it. It will take you to this URL and you can find the collection of Django Security resources then official Django security documentation is very nice. You can refer it uh frequently to identify or to keep track of any security issues so that you can handle it in your uh application And in summary, since Django is a web framework and it maps to OAS top 10 vulnerabilities, it has built-in modules to build secure Django applications. Then the important point here is the security of the application and the data is not only the responsibility of the developer, the user is also equally responsible for the security of the data and accounts.
Thank you everyone for listening to my talk.
Set `DEBUG` to `False`, keep the `SECRET_KEY` private, enable HTTPS, and customize security-related production settings rather than relying on defaults. Customize error messages so they do not reveal sensitive system information.
Discussed at 1:17Django parameterizes query parameters by default, but developers should use `extra()` and raw SQL cautiously. Validate input on the server and parameterize SQL queries rather than concatenating user input into them.
Discussed at 5:10Use multi-factor authentication, enforce strong-password checks, set appropriate session timeouts, and protect registration, credential recovery, and API paths from account enumeration. Packages such as Django OTP and Django Two-Factor can provide additional authentication factors.
Discussed at 6:47Classify sensitive data, avoid storing it unnecessarily, encrypt it at rest and in transit with current protocols such as TLS, use proper key management, disable caching for sensitive responses, and store passwords with strong adaptive salted hashing. Django encrypted model fields, Django Cryptography, and Fernet fields are suggested tools for protecting stored data.
Discussed at 10:40Prefer simpler formats such as JSON, disable external entities and DTD processing in XML parsers, and validate XML with server-side input validation and tools such as XSD or DTD validators.
Discussed at 13:44Perform access-control checks in trusted server-side code and never rely on user-modifiable account or authorization parameters. Disable directory listings, keep backup and metadata files out of web roots, log access-control failures, and assign permissions according to user roles.
Discussed at 16:49Common causes include default credentials, sample applications left on production servers, enabled directory listing, unpatched software, and unprotected files. Harden Django by replacing defaults, disabling directory listings, scanning for vulnerabilities, and customizing error messages to hide sensitive details.
Discussed at 19:09Django templates protect against most XSS by default, but exceptions remain, including unsafe custom template tags, `safe` or `mark_safe`, disabled auto-escaping, and HTML stored in and later rendered from the database. Those cases require especially careful handling and validation.
Discussed at 21:29Do not deserialize objects from untrusted sources, or use formats limited to primitive types; add integrity checks such as digital signatures and enforce strict type constraints. Deserialize in a low-privilege environment where possible and log serialization failures.
Discussed at 23:05Maintain a patch-management process, remove unused dependencies and features, inventory client- and server-side component versions, and use dependency-checking tools. Obtain components only from official sources over secure links, and use tools such as Shodan and Django Hunter to help identify vulnerable code or configurations.
Discussed at 24:40Attackers depend on weak monitoring and slow responses to remain undetected. Use appropriate logging and monitoring, and review logs after penetration testing to confirm that testers' actions and resulting damage can be understood.
Discussed at 25:27Django Hunter helps identify incorrectly configured Django applications and exposed sensitive information, while Django Goat is an intentionally vulnerable application for learning security testing. The speaker also recommends the Awesome Django Security collection and Django's official security documentation.
Discussed at 26:12Note: 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