How To Guard Django Application Against Cross-Site Scripting

Guard Django Application against Cross-Site Scripting

Cross-site scripting (XSS) is a security vulnerability that is mostly found in web applications. If your application is not built properly, keeping XSS vulnerabilities in mind, attackers will be able to type in malicious client-side scripts to execute unauthorized instructions that harm your application. An attacker can use an XSS vulnerability to execute remote code, view user account details, etc.

When it comes to XSS vulnerabilities, you must remember one thing: Never trust any user input. All user input must be properly validated, and there should be some checks on the form to reject any unexpected input.

Django has built-in security protocols against XSS attacks, but there are more things you need to know to make sure your Django application is adequately secure.

In this article, I will be talking about how you can guard your application against XSS when building applications with Django.

Prerequisites

In order to follow this article, the following is required:

  • Basic understanding of the Django framework
the process of cross-site scripting (XSS) attacks

Source

Types of XSS Attacks

  1. Reflected XSS (Non-persistent):

This is a type of XSS vulnerability that shows up when the data provided by a web client is used to parse and display a page of unsanitized content to that user.

An example of a way this can happen is through a blog form. If one submits a text, the article will be displayed in the blog exactly the way it was written. If this response is not sanitized or HTML control characters are not rejected, it exposes your application to XSS attacks.

  1. Stored XSS (Persistent):

This occurs when the malicious HTML is actually stored permanently in the server, and it is rendered permanently to the user if the data is not escaped properly. An example of this type of XSS attack is in the case of online message platforms. If users are allowed to use HTML to format their text for other users to read, an executable script can be sent through that messaging system.

Since <script> can not be seen by the user, they wouldn’t suspect a thing and would execute such malicious code unknowingly. 

  1. Document Object Model (DOM)-Based XSS: 

A DOM-based XSS attack can be executed when unsanitized data is inputted into the DOM of your application. This is typically initiated from the client’s side. Here, the malicious script is executed as a result of modifying the DOM; there is no need for interaction with the server. 

If the eval() function is used to accept input in your code, the attacker can use that as a means to insert the harmful script.

Ways to Guard your Django Application against XSS

1. Avoid using mark_safe unless Necessary

By default, Django templates escape specific characters that are considered dangerous to HTML.

Django is built in such a way that templates automatically escape the output of every variable tag.

< is converted to &lt;

> is converted to &gt;

(single quote) is converted to &#x27;

(double quote) is converted to &quot;

& is converted to &amp;

But when you are building the application, Django gives you the option of turning off this functionality with  {{ foo|safe }} or {% autoescape off %}{{ foo }}{% endautoescape %}. It is used when you need to display HTML in your project or if you want to indicate that the text is not coming from user input. 

Since this gives room for your Django application to accept HTML, harmful JavaScript can be attached to it, and you don’t want that. So, it is advised that you avoid using it unless you really know what you are doing and you are able to use it smartly.

2. Avoid Storing HTML in the Database

Storing HTML in the database is ill-advised, especially when that HTML is retrieved and displayed to the user.

If other people are permitted to send in HTML to your application, a malicious JavaScript code can be attached to it. This harmful code can be executed when stored in the database or when it is displayed to the user. HTML must always be managed as a file not stored in the database; this is really helpful for guarding against stored XSS.

3. Avoid Writing Responses using HttpResponse

Displaying views directly using HttpResponse will expose your Django application to XSS attacks because it bypasses the Django templating system. The templating system is where the HTML escaping property is. So, if something like a form is displayed to accept user input, the attacker can use that opportunity to insert harmful HTML.

A better option for displaying stuff is through render(), where you can specify the template_name, content_type, etc.

Instead of this:

Use this:

Then you input your html code in index.html.

4. Avoid Disabling autoescape Globally

Auto-escaping can be globally disabled in Django settings like this:

This should always be avoided when displaying HTML. It is an invitation for XSS attacks. The consequence of doing this is that every response returned to the user will not be audited for XSS vulnerabilities.

If you really need to use the autoescape functionality, a good alternative is to use the autoescape tag. This built-in tag handles the auto-escaping behavior of the Django template.

Conclusion

This article covers what you need to know about XSS and how you can potentially secure your Django application from such attacks. The tips given above can protect your Django application from various types of XSS attacks.

Going through all the types, I will say that stored XSS attacks are the most dangerous because the script is stored in the server and can be displayed to the user constantly. This should really be taken into consideration when developing any application.

XSS is a very serious issue in current web apps, and it is even part of the OWASP Top 10 list.

Hopefully, with the instructions provided in this article, you will be able to start creating a more secure Django application.