1 year

A Handy Security Checklist


-Don't trust data from a browser, API, or any outside sources: This is a fundamental rule. Make sure that you validate and sanitize any outside data.

-Don't keep SECRET_KEY in version control: As a best practice, pick SECRET_KEY from the environment. Check out the django-environ package.

-Don't store passwords in plain text: Store your application password hashes instead. Add a random salt as well.

-Don't log any sensitive data: Filter out the confidential data, such as credit card details or API keys, before recording them in your log files.

-Any secure transaction or login should use SSL: Be aware that eavesdroppers in the same network as you could listen to your web traffic if it is not in HTTPS. Ideally, you ought to use HTTPS for the entire site.

Avoid using redirects to user-supplied URLs: If you have redirects such as http://example.com/r?url=http://evil.com, then always check against whitelisted domains. 

-Check authorization even for authenticated users: Before performing any change with side effects, check whether the logged-in user is allowed to perform it. 

-Use the strictest possible regular expressions: Be it your URLconf or form validators, you must avoid lazy and generic regular expressions.

-Don't keep your Python code in web root: This can lead to an accidental leak of source code if it gets served as plain text. 

-Use Django templates instead of building strings by hand: Templates have protection against XSS attacks.

-Use Django ORM rather than SQL commands: The ORM offers protection against SQL injection.

-Use Django forms with POST input for any action with side effects: It might seem like overkill to use forms for a simple vote button, but do it.

-CSRF should be enabled and used: Be very careful if you are exempting certain views using the @csrf_exempt decorator. 

-Ensure that Django and all packages are the latest versions: Plan for updates. They might need some changes to be made to your source code. However, they bring shiny new features and security fixes too.

-Limit the size and type of user-uploaded files: Allowing large file uploads can cause denial-of-service attacks. Deny uploading of executables or scripts. 

-Have a backup and recovery plan: Thanks to Murphy, you can plan for an inevitable attack, catastrophe, or any other kind of downtime. Make sure that you take frequent backups to minimize data loss.

-Some of these can be checked automatically using Erik's Pony Checkup at http://ponycheckup.com/.

-Quote all HTML attributes, for example, replace <a href={{link}}> with <a href="{{link}}">


Clickjacking is a means of misleading a user to click on a hidden link or button in the browser when they were intending to click on something else.

Shell injection
As the name suggests, shell injection or command injection allows an attacker to inject malicious code into a system shell such as bash. Even web applications use command-line programs for convenience and their functionality. Such processes are typically run within a shell.

An attacker can enter the filename as manage.py; rm -rf * and delete all the files in your directory. In general, it is not advisable to use os.system.
The subprocess module is a safer alternative (or even better, you can use os.stat() to get the file's attributes).

Since a shell will interpret the command-line arguments and environment variables, setting malicious values in them can allow the attacker to execute arbitrary system commands.

Why are your cookies valuable?
HTTP is stateless. Be it an anonymous or an authenticated user, Django keeps track of their activities for a certain duration of time by managing sessions.

A session consists of a session ID at the client end, that is, the browser and a dictionary-like object stored at the server end. The session ID is a random 32-character string that is stored as a cookie in the browser. Each time a user makes a request to a website, all their cookies, including this session ID, are sent along with the request. At the server end, Django maintains a session store that maps this session ID to the session data. By default, Django stores the session data in the django_session database table. 

Once a user successfully logs in, the session will note that the authentication was successful and will keep track of the user. Therefore, the cookie becomes a temporary user authentication for subsequent transactions. Anyone who acquires this cookie can use this web application as that user, which is called session hijacking.

Django's official blog (https://www.djangoproject.com/weblog/) is a great place to find out about the latest exploits that have been discovered. Django maintainers proactively try to resolve them by releasing security releases. It is highly recommended that you install them as quickly as possible since they usually need very little or no changes to your source code.