XSS (Cross Site Scripting)
Note: This blog is completely based on OWASP guide for prevention of Cross Site Scripting (XSS), but it is put in my own words so it can be understood in a simpler way.
Cross Site Scripting is a common vulnerability involving a scenario where the attacker can inject malicious scripts as input to web applications to force the application to perform unintended tasks. There is no single technique or rule to prevent or reduce the impact of XSS. It is required to use the right combination of techniques and rules that can protect the application from XSS.
Using modern web frameworks(React, Vue, Angular etc..), developers cover majority of the cases, but specific to the frameworks used, there are still minute gaps that can lead to serious damage. Output Encoding and Input Sanitization can act as critical defenses against XSS.
Output Encoding
Output Encoding can be helpful when the application wants to safely display the data as the user as typed. Similar to SQL injections, here the input obtained from the user should be interpreted as text and not the part of the code.
How to implement it?
Most frameworks perform output encoding by default, however, if you are not using a framework, then every variable in the user interface should be passed through an Output Encoding function.
Since different browsers parse HTML, CSS and JS differently, it is important to use appropriate encoding method, else it may introduce weaknesses as well as disturb the functionality of your application.
Output encoding prevents these attacks by converting the special characters that can trigger XSS, such as <, >, ", ' and & into harmless HTML entities, such as <, >, ", ', and &. This way, the browser will treat the data as plain text and not as code.
Some popular Output Encoding Methods include: OWASP’s ESAPI PHP’s htmlspecialchars() .NET’s HtmlEncode() Python’s html.escape
HTML Context
This refers to inserting variable between two basic HTML tags like a <div> or a <p>.
For eg.
1
<div> $unsafVar </div>
An attacker could modify this $unsafeVar variable, which could lead to an attack.
1
<div> <script> alert('XSS') </script> </div>
To add a variable to a HTML context safely, HTML entity encoding can be used. When using JavaScript, .textContent attribute can be a safe way to add a variable.
HTML Attribute Contexts
This refers to when a variable is placed in a HTML attribute value.
1
2
<div attr='$unsafeVar'>
<div attr=”*x” onblur=”alert(1)*”>
It is important to surround the variable names with ' or ", as it makes it difficult for the attacker to change the context.
When using JavaScript, .setAttribute methods can prove as a defensive technique against XSS. These are relatively safe when attribute names are hard-coded such as id or class.
Attributes such as onmouseover, onclick etc are NOT safe to use with untrusted attribute values.
JavaScript Contexts
This refers to when variables are placed into inline JavaScript and then embedded into HTML document. The only secure way to place this way is to quote them. All other contexts are unsafe and not recommended.
1
2
3
<script>alert('$variable')</script>
<script>x='$variable'</script>
<div onclick="'$variable'"></div>
This way XSS can be prevented securely.
For JSON, the Content-Type should be application/json and not text/html to prevent XSS.
CSS Contexts
When variables are placed into inline CSS, the variables should only be placed in CSS property value. Other CSS contexts are unsafe and variable data should not be placed in them.
1
2
3
<style>selector {property : $variable;} </style>
<style>selector {property : '$variable';} </style>
<span style="property:$variable">oh god</span>
It is recommended to use style.property = x.
URL Contexts
URL Contexts refer to places where the developers add a parameter to a URL. This is an unsafe way to add parameter to a URL.
1
<a href="http://example.com?u_id=$variable">Link</a>
To implement this safely, you should perform URL encoding followed by HTML attribute encoding:
1
2
url = "http://example.com?u_id=" + urlencode(parameter)
<a href = "attributeEncode(url)">Link</a>
Thank You for reading. See you in the next blog!
