Cross-site scripting
Objective 4.4 in this course covers web application attacks — SQL injection, cross-site scripting and directory traversal. This is the second. Runs against your own deliberately-weak application, in the lab from lesson 2.
Why this matters
Cross-site scripting is the injection flaw that targets other users of an application rather than its server or database. It is examined by name, it is extremely common, and it is frequently under-rated by developers because "it only runs in the browser" — which misunderstands what an attacker gains from running in a victim's browser as the application.
The lesson
Reflected, stored and DOM-based
The three types differ in where the malicious content lives, and the exam distinguishes them:
- Reflected. The payload is in the request — a URL parameter, usually — and the application includes it in the immediate response without neutralising it. It affects whoever follows a crafted link, so exploitation needs the victim to click something.
- Stored. The payload is saved by the application — in a comment, a profile field, a message — and served to everyone who views that content later. The most serious type, because it needs no per-victim action and can hit many users, including administrators viewing the content in a privileged context.
- DOM-based. The flaw is in the client-side code itself: the browser's own scripts take something attacker-influenced and write it into the page unsafely. The server may never see the payload at all, which is why server-side inspection can miss it entirely.
The distinction that matters: stored is worst because it is persistent and indiscriminate, reflected needs a lure, and DOM-based can be invisible to the server.
What an attacker actually gains from execution in the page
The point developers under-rate. Code running in the victim's browser runs as the application, with everything the user's session has:
- Session theft. Stealing the session identifier logs the attacker in as the victim.
- Acting as the user. The script can make any request the user could — change settings, move money, post content — from inside their authenticated session.
- Credential capture. Rendering a fake login prompt, or logging keystrokes on the page.
- Pivoting to the administrator. Stored payload in content an administrator views executes in the administrator's session, which is often full control of the application.
So "it only runs in the browser" is precisely the problem: the browser is where the user's trust and authenticated session live.
Proving impact without a payload that harms a real user
Lesson 18's caution, applied to a vulnerability whose natural demonstration involves other people:
- Prove execution harmlessly. A payload that shows a marker, or reads a non-sensitive value and displays it, demonstrates that script executes without doing anything to anyone.
- Never deploy a working session-stealer against real users. On a live application with real users, a stored payload that exfiltrates sessions is attacking the client's customers. Demonstrate the capability on your replica or against your own test account.
- Use your own accounts. Store the payload where only your test account views it, or demonstrate reflected execution against yourself.
- Characterise the reach. "This field is stored-XSS injectable and is viewed by administrators" is the finding; you do not need to actually compromise an administrator to report the exposure.
The finding is the injectable point and who is exposed to it, proved with a harmless marker — not a captured session belonging to a real person.
Exploiting your own weak application
The applied lab for this half of objective 4.4, on the deliberately-weak application from lesson 2.
- Find an input that is reflected into a page and try a harmless marker to see whether it executes.
- Find a stored input — a comment or profile field — and confirm it executes for a viewer.
- Look for DOM-based cases, where client-side script writes input into the page unsafely, which server inspection would miss.
- Demonstrate impact harmlessly — read your own session marker, or make a benign request as your test user.
- Read what the server logged, noticing that DOM-based cases may leave nothing server-side at all.
Then apply the fixes below and confirm the payload stops executing.
Output encoding, CSP, and the limits of both
Remediation at the cause, and its boundaries:
- Context-aware output encoding is the primary fix. When the application writes data into a page, it encodes it for the context it is written into — HTML body, attribute, script, URL — so the data renders as text rather than executing. The context-awareness matters: encoding correct for one context is wrong for another.
- A content security policy limits what scripts a page may run, which reduces the impact of a payload that does slip through. It is defence in depth, not the fix — a strong CSP can neutralise many payloads, but a policy with unsafe allowances (or DOM-based flaws that operate within policy) leaves gaps.
- Framework auto-escaping handles most cases, and developers defeat it by reaching for the "render this as raw HTML" feature, which is the single most common way stored XSS is reintroduced.
- Validate input as well, but as defence in depth — the reliable fix is encoding on output, because the same data may be safe in one context and dangerous in another, and only the output side knows the context.
The message to the client mirrors SQL injection: encode on output for the context, and the class closes; rely on filtering input, and it returns wherever data is rendered somewhere the filter did not anticipate.
What to take into the exam
- Reflected needs a lure, stored is persistent and indiscriminate (and worst), DOM-based lives in client code and can be invisible to the server.
- Execution in the victim's browser runs as the application with their session: session theft, acting as the user, and pivoting to an administrator who views stored content.
- Prove with a harmless marker against your own accounts; never deploy a real session-stealer against real users.
- Context-aware output encoding is the fix; CSP and input validation are defence in depth, and raw-HTML rendering is how stored XSS returns.
Practise what you just read
1. Who does cross-site scripting target, unlike SQL injection?
Select one
Show answer
A. Cross-site scripting is the injection flaw that targets other users of an application rather than its server or database. It runs in a victim's browser as the application, which is why it under-rates poorly despite only running in the browser.
2. What characterises a reflected cross-site scripting attack?
Select one
Show answer
B. Reflected XSS has the payload in the request, usually a URL parameter, and the application includes it in the immediate response without neutralising it. It affects whoever follows a crafted link, so exploitation needs the victim to click something.
3. Why is stored cross-site scripting the most serious type?
Select one
Show answer
C. Stored XSS is saved by the application and served to everyone who views that content later, so it needs no per-victim action and can hit many users, including administrators viewing the content in a privileged context. That persistence and reach make it the worst type.
9 more questions on this objective are part of the full course.
Hands-on labs
Part of the free CompTIA PenTest+ PT0-003 course — 41 lessons and 62 hands-on labs.
This is an independent study companion for CompTIA PenTest+ PT0-003 and is not produced by or endorsed by CompTIA.