iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Quiz

Six XSS questions that surface in code review. Pick the right defence for the context. Answers explain why each works.

Six XSS design questions

EXAMPLE
# ============================================================
# Q1) Server-side template echoing a query parameter
# ============================================================
# QUESTION: which encoder for <h1>Results for <?= ... ?></h1>?
#
# ANSWER: htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8')
# The context is HTML BODY; the right encoder for HTML body is htmlspecialchars.

# ============================================================
# Q2) Same value, but inside <a title='...'>
# ============================================================
# QUESTION: same encoder?
#
# ANSWER: yes, htmlspecialchars — BUT the attribute MUST be quoted (single or
# double). Unquoted attributes are XSS-vulnerable regardless of encoding.

# ============================================================
# Q3) Inserting a server value into a <script> tag
# ============================================================
# QUESTION: <script>const user = '<?= ... ?>';</script>
#
# ANSWER: htmlspecialchars is WRONG here — JS string literal context.
# Use json_encode with safe flags:
#   <script>const user = <?= json_encode($user,
#     JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?>;</script>
# Better: avoid mixing data into script tags; use data-* attributes + JS read.

# ============================================================
# Q4) React's dangerouslySetInnerHTML — when to use it?
# ============================================================
# ANSWER: almost never.
# - User-supplied content -> sanitise with DOMPurify FIRST
# - Server-supplied trusted HTML (eg server-rendered Markdown) -> ok
# Even then, attach a code comment with the justification so reviewers know it
# is deliberate.

# ============================================================
# Q5) DOM-based XSS in 'document.title = location.hash.slice(1)'
# ============================================================
# QUESTION: is this XSS?
#
# ANSWER: setting document.title to a string does NOT render HTML — that
# specific line is safe. Bug would be:
#   document.getElementById('out').innerHTML = location.hash.slice(1);
# Use textContent (or .innerText) instead.

# ============================================================
# Q6) Content-Security-Policy — minimum useful?
# ============================================================
# ANSWER:
#   Content-Security-Policy:
#     default-src 'self';
#     script-src 'self' 'nonce-r4nd0m';
#     style-src 'self' 'nonce-r4nd0m';
#     object-src 'none';
#     base-uri 'self';
#     frame-ancestors 'self';
#     require-trusted-types-for 'script';
# Combined with HttpOnly+Secure+SameSite cookies, this turns most XSS bugs
# into 'attempted exploit found in CSP report' rather than 'breach'.

# ============================================================
# Bonus — what is the most common false fix?
# ============================================================
# ANSWER: 'I'll strip <script> tags with a regex.'
# Browsers parse HTML in many ways (img onerror, svg onload, javascript: URIs,
# data: URIs, encoded entities). Use a real sanitiser (DOMPurify, HTMLPurifier)
# or, better, escape the output for the context you are in.

# ============================================================
# Scoring
# ============================================================
# 6 / 6 -> can lead an XSS code review
# 4 / 6 -> revisit xss/cheatsheet
# < 4   -> read OWASP XSS Prevention Cheat Sheet

Why it matters

Pick the encoder by CONTEXT, not by habit. HTML body, attribute, JS string, URL parameter — each has its own correct encoder. A nonce-based CSP + Trusted Types is the safety net; correct contextual encoding everywhere is the primary defence. Together they make XSS bugs rare enough that the rest of your security work matters.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
// 3 questions per lesson.
Try it Yourself »

Discussion

Loading…