Expert · Web attacks and their fixes · topic 22 of 35 · 22 min
Cross-site scripting (XSS)
Explanation
The flaw
Cross-site scripting (XSS) is when a site displays data from a user without properly neutralising it, so that script written by an attacker runs in a victim's browser. The browser cannot tell the difference between the site's own script and an injected one, so it runs both. The attacker's script then acts as the victim: it can read their session, change the page, or send their data away.
| Type | How the script arrives |
|---|---|
| Stored XSS | Saved on the server (e.g. a comment) and shown to every viewer |
| Reflected XSS | Bounced off the server from a link or form in one request |
| DOM-based XSS | The page's own JavaScript inserts unsafe input into the page |
How a tester shows it (in a lab)
A harmless proof is to enter something like a small snippet that would pop up a message box or simply change text on the page, into a field, and see whether it runs when the page is shown. If it does, the input was not made safe. The point is to prove the flaw, not to attack real users; you record it and move on.
The fix: treat output as text
- Output encoding/escaping: when you put user data into a page, encode it for that context (HTML, attribute, JavaScript, URL) so it is shown as text, not run as code. Modern frameworks (React, Angular, etc.) do this by default.
- Content Security Policy (CSP): an HTTP header that tells the browser which scripts are allowed, so injected inline scripts are blocked even if they slip in.
- Mark session cookies HttpOnly so scripts cannot read them, limiting the damage if XSS occurs.
- Validate and sanitise rich input (like HTML comments) with a trusted library.
Detection and defence summary
Detection: unusual markup in stored data, CSP violation reports, and a WAF flagging script-like input. Defence (primary): context-aware output encoding, plus a strong CSP as a safety net. The key mental model: user input should always arrive on the page as text to be displayed, never as code to be executed.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Cross-site scripting (XSS) · 1/7
XSS: a page shows user input unsafely, so an attacker's script runs in a victim's browser.
Prefer a video by a teacher? Find free videos on “cross site scripting xss explained and prevention” on YouTube ↗
In real life: A comment that runs
In a lab blog app, a learner posts a comment containing a tiny script. When anyone opens the post, a message box pops up — proof of stored XSS. She records it, then applies the fix in the app's template: the comment is HTML-encoded on output, so the same comment now shows as plain text. She adds a CSP header as a safety net and marks the session cookie HttpOnly. The flaw is closed with layers, each written up for the developer.
Practice (0/3 done)
XSS lets an attacker…
The primary fix for XSS is…
Output encoding replaces dangerous characters. Write html_escape(text) that replaces & with &, < with <, and > with >, in that order.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- CSRF and IDORWeb attacks and their fixes · same module
- SSRF and authentication flawsWeb attacks and their fixes · same module
- XSS and CSRF: attacks through the browserBackend Development · Backend security
- Front-end security: HTTPS, XSS, CSP and secretsFrontend Web Development · Fast, accessible, findable and safe: quality for real sites
- The OWASP Top 10 with fixesCyber Security: from zero to SOC analyst · Malware and web security
- A full-stack security reviewFull-Stack Development · Performance, security and testing
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
Stored XSS differs from reflected XSS because it…
Answer: Is saved on the server and shown to many viewers
Stored XSS persists and affects every viewer of the page.
A Content Security Policy helps by…
Answer: Telling the browser which scripts are allowed
CSP restricts which scripts can run, blocking injected ones.
Marking a cookie HttpOnly means…
Answer: Scripts cannot read it, limiting XSS damage
HttpOnly keeps JavaScript from reading the cookie.
Modern frameworks like React reduce XSS because they…
Answer: Encode output by default
They escape interpolated values by default.
What is XSS?Related
Answer: An attacker's script running on your website in other users' browsers
Cross-site scripting means attacker JavaScript runs inside your page, usually because user text was shown as HTML.
What is a good first step when adding a Content Security Policy to an existing site?Related
Answer: Use Content-Security-Policy-Report-Only to see what would be blocked
Report-only mode shows violations without breaking anything, so you can tune the policy safely.
What does output encoding prevent?Related
Answer: Cross-site scripting: the browser shows the text instead of running it
Encoding < and > stops injected HTML/script from executing.
Showing raw database errors to users is risky because…Related
Answer: It hands attackers clues about the query and schema
Detailed errors help an attacker refine the injection.
From SQL injection (SQLi)
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 2 more topics in “Web attacks and their fixes” before its exam: CSRF and IDOR, SSRF and authentication flaws.
- Module 7 exam: web attacks and fixes · 13 questions · 22 min, without help. 4 topics of this module still to finish first.
- Then the next module, Deeper lab skills: passwords, privilege, Metasploit, wireless. 35 topics left in the course before the final exam.