Don’t Get Hacked: 10 Essential Django Security Checks for All Web Apps

PRESS RELEASE
Published January 11, 2024

Web application security has become important in this era of rising cyber crimes. Django’s robust security features make it preferable for secure backend development. Its built-in security features protect applications from clickjacking, cross-site scripting (XSS), and other vulnerabilities. To ensure the optimal safety of your application, you must implement these security features accurately. This article delves into the best practices to implement these features and safeguard your Django application from critical cyber threats and risks.

1. Validating media or user-uploaded content

Applications that allow users to upload documents, images, videos, and other forms of content must take added precautions to validate user-uploaded content for optimal security. For Django applications, you can follow these measures to user-uploaded content:

  • Limiting user uploads: Bulk file uploads can lead to denial of service (DOS) attacks. To prevent these attacks, you must specify the number of files a user can upload. For example, in Apache, you can easily use the “LimitRequestBody” directive to set a practical limit.
  • Disabling handlers: You must turn off handlers that execute static files as code while serving static files. For example, you must turn off the “mod_php” in Apache. Turning off these handlers will prevent users from uploading harmless-looking files comprising destructive code. If the server executes these malicious coded files, it can lead to various security issues.
  • Hosting on top-level domains and selecting allowable file extensions: A file with a proper image header and malicious code can easily bypass the Pillow library’s “ImageField” (Djano’s standard image verification process). When this file gets executed, it leads to a series of security issues for your web application. To prevent such files from execution, you can follow these two ways. You must ensure that your application serves user-uploaded content from top-level domains. You can also create a list of extensions for user-uploaded content and configure the server to only upload files with those extensions.

2. Using clickjacking protection

Clickjacking refers to a cybercriminal technique where a malicious application wraps a false interface on another application. It can result in performing unexpected actions on the original application. You can use Django’s “X-Frame-Options middleware” to safeguard your application from clickjacking attacks. This middleware prevents rendering your application within a frame in a supporting browser. You can configure the exact header value sent and even change the protection from a “per-view basis” to “all responses”.

3. Safeguarding your application against Cross-site Request Forgery (CSRF)

Cross-site Request Forgery (CSRF) attacks involve a malicious user executing actions on an application using another person’s login without their knowledge. Django uses a token in “POST requests” as its built-in defense to safeguard your web application from various CSRF attacks. You can enable and use this built-in protection effectively in the following ways:

  • Activating CSRF Middleware: If you want to implement CSRF headers to your responses, add the “django.middleware.csrf.CsrfViewMiddleware” module to the in the “MIDDLEWARE” setting under “setting.py” of your project.
  • Rendering with RequestContext: To make “{% csrf_token %}” work effectively, you must use “RequestContext” like “contrib” apps, “render()” function, and generic views for rendering responses in view functions.
  • Using CSRF Tokens in Templates: For forms using the POST method in a template, add “{% csrf_token %}” inside “<form>” elements. This method only works for forms targeting internal URLs.

You can also use CSRF protection in AJAX, Jinja2 templates, and more. The Django documentation on CSRF protection best practices will provide a detailed overview of the additional methods.

4. Taking precautions against Cross-site Scripting (XSS)

Cross-site scripting (XSS) refers to injecting client-side scripts in trusted web applications (especially in their databases) to access the application’s cookies, session tokens, or additional sensitive information retained in the browser.

Even though Django can protect your application against most XSS attacks, it has some limitations. To overcome them, you must ensure the following:

  • Using is_safe carefully: You must use “is_safe” with custom template tags, mark_safe, and a safe template tag carefully. Furthermore, you must also take precautions while using “is_safe” and ensure “autoescape” is turned off.
  • Escaping output characters and words: Django’s template system can generate outputs other than HTML. These outputs can include CSV, XML, and plain text. Therefore, you must escape or convert certain characters like <, >, and & into a format such that the browser does not interpret them as special or control characters.
  • Sanitizing HTML codes: You must take precautions while storing HTML in the database. HTML content may contain malicious scripts, which can be retrieved on the application after being displayed. These scripts can access sensitive information once a user executes it on the browser. Therefore, you must properly sanitize HTML content from harmful scripts and elements that can result in XSS attacks.

5. Ensuring the right practices for SQL injection protection

SQL injection refers to a code injection technique for inserting malicious SQL code into data-heavy web applications, enabling access to sensitive data. Therefore, SQL injection can lead to data leakage. Django uses query parameterization that defines the query’s SQL code separately from the query’s parameters. This ensures two things. It offers protection from unsafe user-provided queries by escaping the queries using the underlying database driver. This also protects its querysets from SQL injection attacks. However, you must adhere to the following best practices for end-to-end security of your application from SQL injection attacks:

  • Using ‘raw queries’ and ‘custom SQL ’ sparingly: Although the framework allows Django programmers to code raw queries and execute “custom sql”, you must use them sparingly.
  • Escaping parameters: Escape any parameters that users can control using the database driver.
  • Utilizing extra() and RawSQL cautiously: You must also use “extra()” and “RawSQL” carefully.

6. Ensuring session security

You can prevent untrusted users from handling session cookies of an web application’s sub-domain and ensure end-to-end protection session fixation in the following ways:

  • Carefully managing SESSION_COOKIE_DOMAIN: If your application does not have fully controlled or trusted subdomains, avoid setting “SESSION_COOKIE_DOMAIN” to your application’s top-level domain. Setting this to the top domain will send cookies to all the subdomains, including the insecure ones. Therefore, you can set it to the main page to restrict the availability of cookie sessions for other subdomains.
  • Using secure and HttpOnly cookies: You must set the “SESSION_COOKIE_SECURE” and “SESSION_COOKIE_HTTPONLY” settings to “True” for sending cookies over HTTPS. Furthermore, it prevents accessing stored data from JavaScript, averting cookie theft via cross-site scripting (XSS).

7. Implementing cross-origin opener policy (COOP)

The COOP header keeps the web application safe from cross-origin attacks like Spectre. You can use “SecurityMiddleware” to set the Cross-Origin-Opener-Policy header based on the “SECURE_CROSS_ORIGIN_OPENER_POLICY” setting.

8.  Validating host headers

Django uses client-provided, thoroughly sanitized “Host” headers to construct URLs and prevent cross-site scripting attacks. However, fake “Host” values can lead to cache-poisoning attacks, cross-site request forgery, and more. Further, fake “Host” headers can affect even the secure server configurations. Therefore, you must ensure the “Host” header undergoes validation using the “ALLOWED_HOSTS” setting.

You can only apply this validation via “get_host()”, but you must ensure your code does not access it directly from “request.META”. Furthermore, if your configuration demands, you must enable the support “X-Forwarded-Host” header through the “USE_X_FORWARDED_HOST” setting.

9. Generating a unique SECRET_KEY

The “SECRET_KEY” refers to a string used for cryptographic signing. It is automatically generated when you run the “django-admin startproject” command. However, if someone makes a Git commit and has access to your web application’s source code, they can see your application’s “SECRET_KEY”. Furthermore, it can lead to remote code execution and privilege escalation issues. Hence, before the first deployment, you must generate a new “SECRET_KEY” with a unique and unpredictable value.

10. Deploying the application on SSL/HTTPS

Deploy your web application behind HTTPS to protect users’ passwords from being tracked and tampered with when transferred between the client and the server. To implement HTTPS protection in your application, you must follow these additional steps:

  • Setting SECURE_PROXY_SSL_HEADER: You must thoroughly understand the warnings in “SECURE_PROXY_SSL_HEADER” before setting it to prevent CSRF vulnerabilities.
  • Setting SECURE_SSL_REDIRECT to True: You must set “SECURE_SSL_REDIRECT” to “True” for redirecting HTTP requests to HTTPS. However, in the case of reverse proxies, it will be simpler and safer to configure from the main server for ensuring redirects go to HTTPS.
  • Implementing HSTS: HSTS or HTTP Strict Transport Security refers to an HTTP header that instructs browsers to connect to your application using HTTPS connections in the future. This header will redirect connections to HTTPS and provide SSL’s powerful security for secure connections. You can configure HSTS with “SECURE_HSTS_PRELOAD”, “SECURE_HSTS_SECONDS”, and “SECURE_HSTS_INCLUDE_SUBDOMAINS”. Furthermore, you can directly configure HSTS on the server.

Additional Django Security Best Practices to Consider

Django also suggests the following best practices to securely deploy your web application and benefit from the protection offered by operating system, web servers, and other components in the following ways:

  • Adhering to Open Web Application Security Project (OWASP) security practices: Adhere to OWASP’s Django Application Security cheat sheet to ensure optimal application security.
  • Implementing Mozilla’s web security principles and topics: Mozilla discusses web security principles and topics that can safeguard various applications from cybercriminal attacks.
  • Keeping your Django and dependencies updated: It is recommended to keep Django and your application’s dependencies updated to the latest version to stay up-to-date with modern security measures.
  • Placing Python code outside the web server’s root: You must set your Python code outside the root of the server to prevent the code from being accidentally executed or served as plain text.
  • Protecting authentication system against brute force attacks: We suggest deploying Django plugins or web server modules to make requests for user authentication, protecting your application from brute force attacks. You can also use Django packages like “django_ratelimit” to prevent these attacks.
  • Turning off DEBUG in production: Ensure “DEBUG” is turned “False” when you deploy your application in a production environment. When “DEBUG” is set to “True”, Django generates a comprehensive traceback comprising your application’s metadata (like all currently defined Django settings). Although this traceback can help you debug the application locally, any hacker can use this information to affect your application during production.
  • Using firewalls: We also suggest using firewalls to limit unauthorized user access to the application’s caching system and database.

Conclusion

Prioritizing security is a necessity today. Although Django provides robust security tools and measures, you must ensure they are implemented properly during web application development. With the right blend of technical knowledge and expertise, you can easily integrate these practices into your application for optimal security. Furthermore, you must follow Django’s latest security trends in its comprehensive documentation to keep your application well-secured in this digital era.

CDN Newswire