Cross-site Scripting (or XSS for short) is a type of attack in which the attacker tries to inject or run malicious code on your website. These attacks happen when we do not validate the input entered by the user to the website either through text fields, query params, text areas, or in any other format. We can understand this with the help of an example outlining the consequences of this attack.
Suppose you have a form that has text fields, text areas, and many other types of input format, and there is also a submit button present. By clicking on the submit button data gets saved on the webservers. Suppose, there are no validations present for these inputs. The user can submit a malicious script. For example, the user can submit this script in place of any valid text:
<script>alert (“you are hacked”) </script>
When such data is retrieved from the server the malicious script may be executed and show you the alert box saying you are hacked.
There are three types of Cross-Site Scripting attacks:
1. Reflected XSS
2. Stored XSS
3. DOM-based XSS
1) Reflected XSS attack
Reflected XSS is a type of XSS attack where the malicious script can be executed by the web application, by immediately returning the user input. The script does not get saved in the database.
Suppose there is search functionality in our website which receives the search criteria in the form of query parameters, such as:
And your website provides its output as:
Searched for name
In place of “name”, the attacker can enter any malicious script. If that script gets executed inside the browser of the user then it could potentially perform many dangerous actions such as stealing of data, stealing session information, viewing user information, or performing actions that the user would have the ability to perform.
2) Stored XSS attack
Stored XSS is a type of XSS attack where the attacker’s malicious script gets saved inside a database, such as that for a message forum, visitor log, comment field, etc. For example, consider a website that has a comments section in which end users can enter comments.
Suppose one user has entered a malicious script in the comments, and the website saves that comment inside the database without using proper techniques used for preventing XSS attacks. Then whenever another user tries to retrieve comments, this malicious script is likely to be executed.
3) DOM-based XSS attack
DOM-based XSS is a type of cross-scripting attack in which the malicious script is being executed by taking the input from an attacker-controllable source and passes it to a dynamic code execution sink such as the eval() function or innerHTML.
For example, suppose you are taking parameters directly from the URL and passing it to the eval function. The URL and script will be as follows:
const num = document.URL.split(“value=”);
document.getElementById(“displayValue”).innerHTML = eval(num);
If the attacker passes a malicious script in the URL parameters, it will be executed using eval. If the user passes alert(“Hacked”) instead of 2, the browser will display the alert box saying “Hacked” when the page is displayed.
How to prevent cross-site scripting
> Filter Input: At the point where the user enters input in your system, filter it as strictly as possible such that it can only contain valid, expected input. In other words, never trust input provided by a user; always implement a proper system of validations.
> Encoding: In a scenario where user input is directly outputted in HTTP responses, we should always do encoding to prevent the response from being treated as active content. Imagine you have a text area, and a user enters a malicious script, such as:
alert ("You are hacked");
During data retrieval, it should be returned to the browser with characters appropriately “escaped”, preventing execution by the browser.
<script>alert("You are hacked");</script>
> Use Proper HTTP Response Headers: We should use the headers Content-Type and X-Content-Type-Options headers to ensure that the browser interprets the response in the way it was originally intended.
Suppose you send response data back to the browser without including a content-type. The browser can interpret the response as being any type it wishes, which might lead to the malicious scripts being executed. For example, if you returned data in the form of simple text, the browser might interpret it as HTML data. This could result in the execution of malicious code.
> Safely Disabling Scripts: We can selectively disable scripts using the header Content-Security-Policy. It allows us to disable some scripts while leaving others active. Using this header, we can allow scripts from a selected source to be executed, while disabling scripts from others.
> Cookie Security: We should specify the httpOnly flag of cookies to be true so that they cannot be accessed on the client-side. This method can also be helpful in preventing XSS attacks.
> Same Site Attribute: We should use the same site attributes for cookies as it can be helpful in preventing XSS attacks. When a cookie’s same site attribute is set to “strict”, it is stripped from all the cross-origin requests and when it is set to “lax” it is stripped from all cross-origin requests other than GET, OPTIONS and TRACE requests.
We must use the above steps to protect our web application from these Cross-Site Scripting attacks. Fortunately, there are many packages available for various languages to prevent XSS attacks. For example, Node.js® has a package available called XSS which can be used for sanitizing HTML inputs.
Node.js is a registered trademark of Joyent, Inc. DLT Labs is a trademark of DLT Global, Inc.
Author — Shobhit Singhal, DLT Labs™
About the Author: Shobhit is a Node.js developer at DLT Labs, currently exploring and gaining knowledge about OpenID Connect and OAuth 2.0 standards.
Disclaimer: This article was originally published on the DLT Labs Blog page: