Cross Site Scripting (XSS) Complete Guide with Easy Example

Cross Site Scripting (XSS) is one of the most common web application security vulnerabilities. It occurs when an attacker manages to inject malicious JavaScript or other browser-executable content into a trusted website, causing that code to run in another user’s browser.

XSS can affect websites, web applications, dashboards, forums, comment systems, search pages, and online stores. Depending on the vulnerability, an attacker may be able to steal sensitive information, perform actions as another user, modify webpage content, or redirect victims to malicious websites.

This guide explains what XSS is, how it works, its main types, a realistic example, its impact, and how developers can prevent it.

Cross Site Scripting

What Is Cross Site Scripting (XSS)?

Cross Site Scripting is a client-side injection vulnerability.

The basic problem occurs when a website accepts user-controlled data and places that data into a web page without properly handling or encoding it.

For example, imagine a website has a comment box:

User comment:
Welcome to my website!

The application stores the comment and displays it to other visitors.

If the application incorrectly treats user input as HTML instead of ordinary text, an attacker could submit something such as:

<script>alert(‘XSS’)</script>

If the website inserts this input into the page without appropriate protection, the browser may interpret it as JavaScript and execute it.

The important point is that the malicious code runs in the victim’s browser, but it is delivered through a website the victim trusts.

How Does XSS Work?

A typical XSS attack involves three components:

  1. Attacker
  2. Vulnerable website
  3. Victim’s browser

The general process looks like this:

Attacker

   ↓

Injects malicious input

   ↓

Vulnerable Website

   ↓

Returns unsafe content

   ↓

Victim’s Browser

   ↓

Browser executes the injected script

The vulnerability usually exists because the application does not properly distinguish between:

  • Data supplied by a user
  • HTML markup
  • JavaScript code

Example of XSS

Consider a fictional shopping website called:

ExampleShop.com

The website allows customers to leave product reviews.

A normal customer submits:

This product is excellent!

The application stores the review and later displays:

<div class=”review”>

    This product is excellent!

</div>

Everything works correctly.

The Security Problem

Suppose the application does not properly encode review content.

An attacker submits malicious HTML/JavaScript instead of a normal review.

For example, in a controlled security test, the payload could be:

<script>alert(‘XSS’)</script>

If the website stores this input and later inserts it directly into the page, the resulting HTML could effectively become:

<div class=”review”>

    <script>alert(‘XSS’)</script>

</div>

When another user opens the product page, their browser interprets the <script> element as JavaScript.

The browser executes it.

This simple alert is only a demonstration of the vulnerability. A real attacker could attempt more harmful actions, depending on the application’s security controls.

Why Is This Dangerous?

A successful XSS vulnerability can potentially allow attackers to:

  • Modify webpage content
  • Display fake login forms
  • Redirect users to malicious websites
  • Perform actions using a victim’s authenticated session
  • Capture sensitive information exposed to page scripts
  • Manipulate forms
  • Conduct phishing attacks
  • Deface parts of a webpage
  • Target administrators through vulnerable management interfaces

The actual impact depends on the application’s architecture, browser protections, authentication mechanisms, cookie configuration, and other security controls.

Types of Cross Site Scripting

XSS is commonly divided into three major categories:

1. Stored XSS

Stored XSS occurs when malicious input is saved by the application and later displayed to other users.

Common locations include:

  • Comments
  • Product reviews
  • Forum posts
  • User profiles
  • Messages
  • Support tickets

Example

An attacker submits malicious content through a comment form.

Attacker → Website Database → Victim

The website stores the content in its database.

Every time another user views the affected page, the malicious content may be rendered.

Why Stored XSS Is Serious

Stored XSS can affect many users because the malicious content remains on the server until it is removed or neutralized.

2. Reflected XSS

Reflected XSS occurs when malicious input is immediately returned by the server in a response.

A common example involves search functionality.

Imagine a website displays:

Search results for: laptop

The application takes the search term from a URL and places it into the page without proper output encoding.

For example:

https://example.com/search?q=laptop

If the application does not safely handle the q parameter, an attacker could construct a malicious URL.

The attacker then attempts to trick a victim into opening that URL.

The malicious input is reflected from the request into the response and interpreted by the victim’s browser.

Typical Flow

Attacker

   ↓

Malicious URL

   ↓

Victim clicks link

   ↓

Website reflects input

   ↓

Browser processes unsafe content

Reflected XSS commonly requires some form of victim interaction, such as clicking a malicious link.

3. DOM-Based XSS

DOM-based XSS occurs primarily because client-side JavaScript processes untrusted data in an unsafe way.

For example, a JavaScript application might read information from the URL and insert it into the page using an unsafe DOM operation.

Conceptually:

element.innerHTML = userInput;

If userInput contains attacker-controlled HTML, the browser may interpret it as markup.

DOM-based XSS can therefore occur even when the server itself does not generate the vulnerable HTML.

Stored vs Reflected vs DOM-Based XSS

TypeWhere the malicious input existsTypical trigger
Stored XSSStored on the server/databaseVictim views affected content
Reflected XSSRequest/responseVictim opens a crafted URL
DOM-Based XSSBrowser-side DOM processingClient-side JavaScript processes unsafe data

XSS vs SQL Injection

XSS and SQL Injection are both injection vulnerabilities, but they target different environments.

XSS

Targets the:

User’s browser

Attacker → Web Application → Victim Browser

SQL Injection

Targets the:

Database query

Attacker → Web Application → Database

For example:

  • XSS attempts to cause unwanted browser-side behavior.
  • SQL Injection attempts to manipulate database queries.

Both vulnerabilities commonly arise when applications fail to safely handle untrusted input.

How Developers Prevent XSS

Preventing XSS requires a defense-in-depth approach.

1. Use Context-Aware Output Encoding

One of the most important defenses is output encoding.

User-controlled text should be encoded according to the context in which it is being inserted.

For HTML text, for example:

&lt;script&gt;alert(‘XSS’)&lt;/script&gt;

The browser displays it as text rather than interpreting it as a script element.

The exact encoding strategy depends on whether data is being inserted into:

  • HTML
  • HTML attributes
  • JavaScript
  • CSS
  • URLs

There is no single encoding function that is safe for every context.

2. Sanitize HTML When HTML Is Actually Required

Sometimes applications intentionally allow users to submit formatted HTML, such as:

  • Blog editors
  • Documentation systems
  • Rich-text comments

In those situations, simply removing all HTML may not be practical.

Instead, use a well-maintained HTML sanitization library with an appropriate allowlist.

The sanitizer should remove dangerous elements and attributes while preserving permitted formatting.

3. Avoid Dangerous DOM APIs

Developers should be careful with APIs such as:

element.innerHTML = userInput;

Prefer safer approaches when HTML is not required:

element.textContent = userInput;

textContent treats the supplied value as text rather than HTML.

For example:

const message = “<script>alert(‘XSS’)</script>”;

element.textContent = message;

The browser displays the characters instead of executing the script.

4. Use Content Security Policy

A Content Security Policy (CSP) provides an additional layer of browser-side protection.

A carefully configured CSP can restrict where scripts are allowed to load from and can significantly reduce the impact of some XSS vulnerabilities.

For example, a policy might restrict scripts to trusted origins.

CSP should be treated as defense in depth, not as a replacement for proper input handling and output encoding.

5. Configure Cookies Securely

Authentication cookies should be configured with appropriate security attributes, including:

HttpOnly

Secure

SameSite

HttpOnly

Helps prevent JavaScript from directly reading the cookie.

Secure

Ensures the cookie is sent over HTTPS.

SameSite

Helps control when cookies are sent in cross-site requests.

These settings can reduce the impact of certain attacks, but they do not fix the underlying XSS vulnerability.

6. Validate Input

Applications should validate user input according to expected business rules.

For example, if a field should contain an email address, validate it as an email address.

If a field should contain a numeric ID, do not accept arbitrary HTML.

However, input validation should not be the only XSS defense.

A secure application normally combines:

Input Validation

       +

Output Encoding

       +

Safe DOM APIs

       +

HTML Sanitization (when required)

       +

Content Security Policy

       +

Secure Cookies

XSS Prevention Example in PHP

Consider this unsafe PHP code:

echo $_GET[‘name’];

If the value comes from an untrusted URL parameter, directly printing it into an HTML page can create an XSS risk.

A safer approach for HTML text output is:

echo htmlspecialchars(

    $_GET[‘name’],

    ENT_QUOTES | ENT_SUBSTITUTE,

    ‘UTF-8’

);

This encodes characters that have special meaning in HTML.

For production applications, developers should still consider the specific output context and use appropriate security controls rather than assuming htmlspecialchars() is universally sufficient.

How to Test for XSS Safely

XSS testing should only be performed on:

  • Your own websites
  • Applications you are authorized to test
  • Dedicated security labs
  • CTF environments
  • Training platforms

A basic harmless test in a controlled environment is:

<script>alert(‘XSS’)</script>

If the application displays the input as text rather than executing it, that particular test indicates that the relevant output context is handling the payload safely.

For professional security testing, tools such as OWASP ZAP and Burp Suite can help identify and analyze XSS vulnerabilities in authorized environments.

Scenario

Imagine an organization’s employee portal has a support-ticket system.

An employee submits:

My VPN is not working.

The administrator later opens the ticket.

Unfortunately, the ticket system stores user input without proper output encoding.

An attacker could attempt to inject malicious content into a ticket.

When an administrator views the ticket, the browser processes the unsafe content.

This is particularly dangerous because administrators often have higher privileges than ordinary users.

The general attack chain could look like:

Attacker

   ↓

Malicious ticket content

   ↓

Support system stores content

   ↓

Administrator opens ticket

   ↓

Browser renders unsafe content

   ↓

XSS executes in administrator’s browser

This demonstrates why XSS is not merely a “popup problem.” In a vulnerable application, the consequences can be much more serious.

How to Remember XSS Easily

A simple way to remember XSS is:

XSS = Untrusted data becomes executable browser content.

Think of the process as:

Untrusted Input

       ↓

Unsafe Processing

       ↓

Web Page

       ↓

Browser

       ↓

Unexpected Code Execution

The security goal is to ensure that data remains data and is never accidentally interpreted as executable code.

OWASP and XSS

XSS has historically been one of the most important web application security risks tracked by OWASP.

Modern web frameworks often provide automatic output escaping, but developers can still introduce XSS by:

  • Disabling escaping
  • Using unsafe HTML rendering
  • Directly manipulating the DOM
  • Trusting third-party content
  • Misconfiguring sanitization
  • Dynamically generating JavaScript
  • Using unsafe template features

Therefore, developers should understand the underlying security principles rather than relying entirely on a framework.

Conclusion

Cross Site Scripting (XSS) is a web security vulnerability in which attacker-controlled content can be interpreted as executable content in a user’s browser.

The three major types are:

  1. Stored XSS
  2. Reflected XSS
  3. DOM-Based XSS

A real-world-style example is a vulnerable comment, review, or support-ticket system that stores attacker-controlled content and later displays it to another user.

The strongest defense is a layered approach that includes context-aware output encoding, secure DOM APIs, appropriate HTML sanitization, input validation, Content Security Policy, and secure cookie configuration.

For developers, the most important rule is simple:

Never trust user-controlled data, and never insert untrusted data into an executable context without appropriate protection.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top