How to protect against cross-site scripting (XSS) in Django?

Web applications that fail to appropriately escape user-submitted text before rendering it into HTML are vulnerable to cross-site scripting (XSS). An attacker can use this to inject arbitrary HTML into your Web page, commonly in the form of a <script> element.

XSS attacks are frequently used by attackers to steal cookie and session information, as well as to fool users into providing personal information to the wrong person. Phishing is another term for this. We will look at a common case because this type of attack can take many different shapes and has nearly unlimited variations.

Let us consider simple welcome person page.
def welcome(request):
   name= request.GET(‘name’,’person’)
   return   render_to_response(“welcome.html”,{“name”:name}}

The code above present in simply reads a name using a GET parameter and passes the name to the welcome.html template.

Here when a person enters their name, say, tutorialspoint, the output of the above line of code when the html page is rendered on the web will be as follows.

<h1>Welcome, tutorialspoint!</h1>

The attacker may send malicious content along with the name when entering. For example, data sent by the attacker may be of the form.

<h1> Welcome, <b>tutorialspoint</b></h1>

Here the <b>,</b> tag is not malicious but other content could harm the site and the data. The attacker could include a whole set of HTML that hijacked your page with arbitrary content. This type of attack has been used to trick users into entering data into what looks like their bank’s Web site or an ecommerce site, but in fact is an XSS-hijacked form that submits their back account information to an attacker.

Solution to prevent XSS attacks

The solution to this attack is to simple escape any content that might have come from the user.

The code above in the html page can be rewritten as below and it can provide some security against XSS attacks.

<h1>Welcome, {{ name|escape }} !</h1>

No matter what changes are made to the code, even if the solution to avoid XSS attacks is to escape the content given by user. No automatic solution will ever protect your site from XSS attacks 100% of the time.

Modifying Django to automatically escape all variables displayed in templates has been in the works although, it has never been fully accomplished until now.

Django's templates have so far avoided this behaviour since it alters the simple method of showing variables in a subtle way. It's a hard situation. Although it goes against Django's core values to add hidden implicit behaviour, security is also vital. In the future, there's a good probability Django will develop auto-escaping (or virtual auto-escaping) behaviour.