Django Security — XSS

3 years ago 185
BOOK THIS SPACE FOR AD
ARTICLE AD

Santhosh

Cross-Site Scripting (XSS) attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted websites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end-user.

Unlike most web development frameworks, the developers of the Django framework have considered the security aspects. As a result, Django comes with built-in security features against XSS attacks. XSS attacks happen through injections — injection of scripts that contain HTML tags. Django sure provides a layer of security by escaping HTML characters. But malicious actors would already know that. Attackers are getting more creative day by day and come up with ways to get over default security features.

Unsafe Use of “Safe”.Bypassing the template engine.unescaped variables.Variable in a dangerous location.Base64 Encoding.Unquoted Payload.Template Literals.

mark_safe() marks the returned content as “safe to render.” This instructs the template engine to bypass HTML escaping, creating the possibility of an XSS vulnerability.

Example:

mark_safe(html_content)

Writing results directly to HttpResponse or similar classes bypasses the Django template engine. This also bypasses the HTML escaping built into the template engine and creates the possibility of an XSS vulnerability. Use render() with a template instead.

Example:

return HttpResponse("Hello, " + name)

The | safe filter marks the content as “safe for rendering.” This has the same effect as mark_safe() in Python code. This will permit direct rendering of HTML and create a possible XSS vulnerability.

Example:

{{ name | safe }}

Template variables in a href value could still accept the javascript: URI. This could be an XSS vulnerability. HTML escaping will not prevent this. Use url_for to generate links.

Example:

<a href="{{ link }}"></a>

Django by default uses Unicode and UTF-8 encoding. When you give input, Django forcefully encodes it and then escapes dangerous characters. But this doesn’t work for base64 encoded strings. In the above example, where we saw that some characters are replaced with the HTML code, the input is considered as UTF-8. But if you can change this default, you can bypass escaping.

Django by default sanitizes quoted data. But if you see the application using unquoted data — for example, JavaScript integers — then the application could be vulnerable to XSS attack.

Djangos escape function escapes single quotes and double quotes. Wouldn’t it be better if there was something that had the same function as these characters but wasn’t escaped? Well, there is the backtick (`).

For a browser, ‘Hello World!’ is the same as Hello World!

A backtick is a template literal that acts as quotes but isn’t escaped by Django’s escape function. So, you can craft your injection with backticks to bypass escaping.

Django provides several ways to protect from XSS they are,

Safe FilterInput SanitizationHttpOnly

This flag tells Django that if a “safe” string is passed into your filter, the result will still be “safe” and if a non-safe string is passed in, Django will automatically escape it, if necessary. Misuse of the safe filter can be dangerous, as depicted in the example above. Hence, it’s very important to be smart and careful in using it. Don’t use this filter if it’s not necessary.

Input Sanitization includes the elimination of unwanted characters from the input by means of removing, replacing, encoding, or escaping the characters. Django by default uses HTML escaping. One can extend this to JavaScript as well using Python libraries. JavaScript escaping escapes special characters except @*_+-./. It also encodes blank spaces to its equivalent code. This would make more payloads useless.

Example:

import urlliba = 'Example for escaping.php?name=alert("XSS")'
print(urllib.parse.quote(a))

Output:

Example%20for%20escaping.php%3Fname%3D%3Cscript%3Ealert%28%22XSS%22%29%3C/script%3E

HttpOnly is an additional flag included in a Set-Cookie HTTP response header. Using the HttpOnly flag when generating a cookie helps mitigate the risk of the client-side script accessing the protected cookie. One can enable this feature in Django by adding the following line in settings.py file of your Django project:

SESSION_COOKIE_HTTPONLY = True
Read Entire Article