©2019 Security Unleashed | New Delhi

  • Animesh Gupta

CROSS SITE SCRIPTING


Cross-site scripting (XSS) is a code injection attack that allows an attacker to execute malicious JavaScript in another user's browser.

The attacker does not directly target his victim. Instead, he exploits a vulnerability in a website that the victim visits, in order to get the website to deliver the malicious JavaScript for him. To the victim's browser, the malicious JavaScript appears to be a legitimate part of the website, and the website has thus acted as an unintentional accomplice to the attacker.


How the malicious JavaScript is injected ?


The only way for the attacker to run his malicious JavaScript in the victim's browser is to inject it into one of the pages that the victim downloads from the website. This can happen if the website directly includes user input in its pages, because the attacker can then insert a string that will be treated as code by the victim's browser.


In the example below, a simple server-side script is used to display the latest comment on a website


print "<html>"

print "Latest comment:"

print database.latestComment

print "</html>"


The script assumes that a comment consists only of text. However, since the user input is included directly, an attacker could submit this comment: "<script>...</script>". Any user visiting the page would now receive the following response:


<html>

Latest comment:

<script>...</script>

</html>

What is malicious JavaScript?


At first, the ability to execute JavaScript in the victim's browser might not seem particularly malicious. After all, JavaScript runs in a very restricted environment that has extremely limited access to the user's files and operating system. In fact, you could open your browser's JavaScript console right now and execute any JavaScript you want, and you would be very unlikely to cause any damage to your computer.


However, the possibility of JavaScript being malicious becomes more clear when you consider the following facts:


  • JavaScript has access to some of the user's sensitive information, such as cookies.

  • JavaScript can send HTTP requests with arbitrary content to arbitrary destinations by using XMLHttpRequest and other mechanisms.

  • JavaScript can make arbitrary modifications to the HTML of the current page by using DOM manipulation methods.

The consequences of malicious JavaScript


Among many other things, the ability to execute arbitrary JavaScript in another user's browser allows an attacker to perform the following types of attacks:


Cookie theft


The attacker can access the victim's cookies associated with the website using document.cookie, send them to his own server, and use them to extract sensitive information like session IDs.


Keylogging


The attacker can register a keyboard event listener using addEventListener and then send all of the user's keystrokes to his own server, potentially recording sensitive information such as passwords and credit card numbers.


Phishing


The attacker can insert a fake login form into the page using DOM manipulation, set the form's action attribute to target his own server, and then trick the user into submitting sensitive information.


Although these attacks differ significantly, they all have one crucial similarity: because the attacker has injected code into a page served by the website, the malicious JavaScript is executed in the context of that website. This means that it is treated like any other script from that website: it has access to the victim's data for that website (such as cookies) and the host name shown in the URL bar will be that of the website. For all intents and purposes, the script is considered a legitimate part of the website, allowing it to do anything that the actual website can.


This fact highlights a key issue:


If an attacker can use your website to execute arbitrary JavaScript in another user's browser, the security of your website and its users has been compromised.


To emphasize this point, some examples in this tutorial will leave out the details of a malicious script by only showing <script>...</script>. This indicates that the mere presence of a script injected by the attacker is the problem, regardless of which specific code the script actually executes.

Types of XSS


While the goal of an XSS attack is always to execute malicious JavaScript in the victim's browser, there are few fundamentally different ways of achieving that goal. XSS attacks are often divided into three types:

  • Persistent XSS, where the malicious string originates from the website's database.

  • Reflected XSS, where the malicious string originates from the victim's request.

  • DOM-based XSS, where the vulnerability is in the client-side code rather than the server-side code.'

Persistent XSS


Persistent XSS occurs when the data provided by the attacker is saved by the server, and then permanently displayed on "normal" pages returned to other users in the course of regular browsing, without proper HTML escaping. The diagram below illustrates this scenario:


  1. The attacker uses one of the website's forms to insert a malicious string into the website's database.

  2. The victim requests a page from the website.

  3. The website includes the malicious string from the database in the response and sends it to the victim.

  4. The victim's browser executes the malicious script inside the response, sending the victim's cookies to the attacker's server.

Reflected XSSReflected XSS attacks are also known as non-persistent XSS attacks and, since the attack payload is delivered and executed via a single request and response, they are also referred to as first-order or type 1 XSS .The diagram below illustrates this scenario:

  1. The attacker crafts a URL containing a malicious string and sends it to the victim.

  2. The victim is tricked by the attacker into requesting the URL from the website.

  3. The website includes the malicious string from the URL in the response.

  4. The victim's browser executes the malicious script inside the response, sending the victim's cookies to the attacker's server.

DOM-based XSS

DOM Based XSS (or as it is called in some texts, “type-0 XSS”) is an XSS attack wherein the attack payload is executed as a result of modifying the DOM“environment” in the victim's browser used by the original client side script, so that the client side code runs in an “unexpected” manner The diagram below illustrates this scenario for a reflected XSS attack:



  1. The attacker crafts a URL containing a malicious string and sends it to the victim.

  2. The victim is tricked by the attacker into requesting the URL from the website.

  3. The website receives the request, but does not include the malicious string in the response.

  4. The victim's browser executes the legitimate script inside the response, causing the malicious script to be inserted into the page.

  5. The victim's browser executes the malicious script inserted into the page, sending the victim's cookies to the attacker's server

Methods of preventing XSS


Recall that an XSS attack is a type of code injection: user input is mistakenly interpreted as malicious program code. In order to prevent this type of code injection, secure input handling is needed. For a web developer, there are two fundamentally different ways of performing secure input handling:


Encoding, which escapes the user input so that the browser interprets it only as data, not as code.


Validation, which filters the user input so that the browser interprets it as code without malicious commands.


While these are fundamentally different methods of preventing XSS, they share several common features that are important to understand when using either of them:


Context

Secure input handling needs to be performed differently depending on where in a page the user input is inserted.


Inbound/outbound

Secure input handling can be performed either when your website receives the input (inbound) or right before your website inserts the input into a page (outbound).


Client/server

Secure input handling can be performed either on the client-side or on the server-side, both of which are needed under different circumstances.