- 20 Ağu 2016
- 4,446
- 3
You know output encoding is most important thing when topic comes to XSS. Today Ive decided to write a article about how to secure your Django application against XSS vulnerabilities. Handing XSS cases with Django is more easy than other frameworks. Your Django app is approximately secure against XSS even if you developed it without security mind. Therefore Django is try to encode specific characters in order to prevent yourself from cross-site scripting. But Django going to be fail under the some circumstances.
PS : If you think any part of this article needs update or changes, feel free to leave comment.
Django Default Output Encoding Mechanism
Django try to encode some dangerous characters in order to prevent XSS vulnerability. Let see which characters are going to be encoded when you try to print it out at htmls.
PS : If you think any part of this article needs update or changes, feel free to leave comment.
Django Default Output Encoding Mechanism
Django try to encode some dangerous characters in order to prevent XSS vulnerability. Let see which characters are going to be encoded when you try to print it out at htmls.
Kod:
[CENTER]from django.shortcuts import render, render_to_response
# Create your views here.
def home(request):
foo = request.GET["param"]
return render_to_response('home.html', locals())[/CENTER]
And home.html file
We all know that most common XSS cases related to quotes, less-bigger than sign and brackets. Therefore we need to know which characters are going to be encoded. In order to understand that I create following URL
Result is here.
I've append dash after every single characters so we can easily understand which output belongs to which character.
As a result, we've learned that Django only cares following characters.
Single and double quote.
Less-bigger than signs.
Test Django Output against Different Context Based XSS Cases
We all know XSS vulnerabilities can be appear in different contexts which means that each context have individual payload / approach. I've create following html file in order to show differences to you.
Let's send same request again and analyze output context by context.
Html Context
As you can see < and > sings are encoded by Django. Therefore we are not able to initiate new html tag like <img or <script> . You Django application is secure against HTML Context Based XSS Vulnerabilities.
Attribute Context
Single and double quotes are encoded which is good for us. Attribute context based XSS vulnerabilities appears because lack of single/double output encoding. But this is not enough. We already know that Django doesnt encode back-tick ( ) which is cause XSS vulnerability in specific IE version.
Let send following request to Django application and analyze output.
Ive omitted other context and leave attribute context sample alone. As you can see are not encoded over there. This doesnt means anything to Firefox and Chromes but it does for old version of IE. Because old IE browsers treat it as a valid separator.
Javascript Context
Single, double and less-bigger than sings are encoded. Which means we cant reach out of variable values. Because we need single or double quotes but they are already encoded by Django. Also we are not able to end script tags because of > and < are encoded too.
All of these payload will be failed because of Django encode but there is some specials cases about Javascript context.
Keeping old things is bad
Let assume that developers comment out some part of JS codes. Ive seen this too many times during penetration test.
It just comment outed. This codes are vulnerability because of comment out
Boom. The trick is new line character. %0A is encoded new line character. When python see that it create new and continue to printing values . As an attacker we a**** comment out area and reach to javascript context. Last double slash is for prevention syntax error.
Style Context
Obviously Django can be vulnerable against stylish XSS. Because Django doesnt encodes ( and ) . Let me show you some payload that can successfully exploit XSS vulnerability. Please send following request to the django app.
Kod:
<!DOCTYPE html>
<html>
<head lang="en">
<**** charset="UTF-8">
<title></title>
</head>
<body>
My name is : {{ foo }}
</body>
</html>
We all know that most common XSS cases related to quotes, less-bigger than sign and brackets. Therefore we need to know which characters are going to be encoded. In order to understand that I create following URL
Kod:
http://127.0.0.1:8000/?param=--->-<-(-)-{-}-%26
Result is here.
Kod:
<!DOCTYPE html>
<html>
<head lang="en">
<**** charset="UTF-8">
<title></title>
</head>
<body>
My name is : '-"-`->-<-(-)-{-}-&
</body>
</html>
I've append dash after every single characters so we can easily understand which output belongs to which character.
As a result, we've learned that Django only cares following characters.
Single and double quote.
Less-bigger than signs.
Test Django Output against Different Context Based XSS Cases
We all know XSS vulnerabilities can be appear in different contexts which means that each context have individual payload / approach. I've create following html file in order to show differences to you.
Kod:
<!DOCTYPE html>
<html>
<head lang="en">
<**** charset="UTF-8">
<title></title>
</head>
<body>
<!-- HTML Context -->
My name is : {{ foo }}
<!-- Attribute Context -->
<input name="x" value="{{ foo }}"/>
<!-- Javascript Context -->
<script> var foo = "{{ foo }}"</script>
<!-- Style Context -->
<div style="{{ foo }}">Style Context</div>
</body>
</html>
Let's send same request again and analyze output context by context.
Kod:
<!DOCTYPE html>
<html>
<head lang="en">
<**** charset="UTF-8">
<title></title>
</head>
<body>
<!-- HTML Context -->
My name is : '-"-`->-<-(-)-{-}-&
<!-- Attribute Context -->
<input name="x" value="'-"-`->-<-(-)-{-}-&"/>
<!-- Javascript Context -->
<script> var foo = "'-"-`->-<-(-)-{-}-&"</script>
<!-- Style Context -->
<div style="'-"-`->-<-(-)-{-}-&">Style Context</div>
</body>
</html>
Html Context
As you can see < and > sings are encoded by Django. Therefore we are not able to initiate new html tag like <img or <script> . You Django application is secure against HTML Context Based XSS Vulnerabilities.
Attribute Context
Single and double quotes are encoded which is good for us. Attribute context based XSS vulnerabilities appears because lack of single/double output encoding. But this is not enough. We already know that Django doesnt encode back-tick ( ) which is cause XSS vulnerability in specific IE version.
Let send following request to Django application and analyze output.
Kod:
// Request : http://127.0.0.1:8000/?param=``onmouseover=prompt(1)
// Output
<!DOCTYPE html>
<html>
<head lang="en">
<**** charset="UTF-8">
<title></title>
</head>
<body>
<!-- Attribute Context -->
<input name="x" value="``onmouseover=prompt(1)"/>
</body>
</html>
Ive omitted other context and leave attribute context sample alone. As you can see are not encoded over there. This doesnt means anything to Firefox and Chromes but it does for old version of IE. Because old IE browsers treat it as a valid separator.
Javascript Context
Single, double and less-bigger than sings are encoded. Which means we cant reach out of variable values. Because we need single or double quotes but they are already encoded by Django. Also we are not able to end script tags because of > and < are encoded too.
Kod:
Payload = "; alert(1);f="
OR
Payload = '; alert(1);f='
OR
</script><script>alert(1)</script>
All of these payload will be failed because of Django encode but there is some specials cases about Javascript context.
Keeping old things is bad
Let assume that developers comment out some part of JS codes. Ive seen this too many times during penetration test.
Kod:
<!DOCTYPE html>
<html>
<head lang="en">
<**** charset="UTF-8">
<title></title>
</head>
<body>
<script>
//var f = callSomeFunction('{{ foo }}')
</script>
</html>
It just comment outed. This codes are vulnerability because of comment out
Kod:
// URL : http://127.0.0.1/?param=TEST%0Aalert%281%29%3B//
// Result
<!DOCTYPE html>
<html>
<head lang="en">
<**** charset="UTF-8">
<title></title>
</head>
<body>
<script>
//var f = callSomeFunction('TEST
alert(1);//')
</script>
</html>
Boom. The trick is new line character. %0A is encoded new line character. When python see that it create new and continue to printing values . As an attacker we a**** comment out area and reach to javascript context. Last double slash is for prevention syntax error.
Style Context
Obviously Django can be vulnerable against stylish XSS. Because Django doesnt encodes ( and ) . Let me show you some payload that can successfully exploit XSS vulnerability. Please send following request to the django app.
Son düzenleme: