Exercises: Web Application Security

These exercises move from recognizing web vulnerabilities to fixing and detecting them. Difficulty is marked ⭐ (recall/application), ⭐⭐ (analysis), and ⭐⭐⭐ (synthesis/design). A dagger (†) marks problems with a full worked solution in Appendix: Answers to Selected Exercises — attempt every problem before you read one.

Work in your own notebook, lab, or a private repository. For "fix-it" problems, the structural fix (parameterize, encode, tokenize) matters more than cosmetic cleanup; say why your fix removes the bug, not just that it does. Authorization note: every technique here is for code you own or are authorized to review — never test these against systems you do not control (Chapter 1's rule, and the law).


Part A — Core vocabulary and concepts ⭐

1.† In one sentence each, define SQL injection, cross-site scripting (XSS), cross-site request forgery (CSRF), and server-side request forgery (SSRF). Then write one sentence naming the single root cause that the first two share.

2. Match each fix to the attack it primarily addresses: (fixes) parameterized query · output encoding · anti-CSRF token · session ID rotation at login · destination allowlist + egress filtering · HttpOnly cookie flag. (attacks) SQL injection · stored XSS · CSRF · SSRF · session fixation · session cookie theft via XSS.

3. Distinguish stored, reflected, and DOM-based XSS by where the payload lives and how it reaches the victim's browser. Which one can be invisible in server-side access logs, and why?

4.† Explain why a web application firewall (WAF) is "defense in depth, not a fix." Give one thing a WAF does genuinely well and one argument a WAF must never be used to justify.

5. What is the same-origin policy (SOP), and how does it make anti-CSRF tokens effective? (One or two sentences.)

6. Define session fixation and state the one structural change that defeats it.


Part B — Find the vulnerability (secure-code review) ⭐⭐

7.† Find the vulnerability and name the fix. (Python; the parameter comes from an HTTP request.)

def get_balance(conn, account_id):
    q = f"SELECT balance FROM accounts WHERE id = {account_id}"
    return conn.execute(q).fetchone()

8. Find the vulnerability. (Server-side rendering; nickname comes from the user's profile.)

def profile_header(nickname):
    return "<h1>Welcome back, " + nickname + "!</h1>"

9.† Find the vulnerability. (Client-side JavaScript that runs on page load.)

// Show a friendly greeting based on the ?name= URL parameter
const name = new URLSearchParams(location.search).get("name");
document.getElementById("greeting").innerHTML = "Hi " + name;

10. Find the vulnerability. (A "fetch a logo from a URL" feature for white-labeling.)

def fetch_logo(url):
    # url is supplied by the customer in their branding settings
    return requests.get(url).content

11.† Find two vulnerabilities in this login flow and fix both.

def login(session, conn, username, password):
    row = conn.execute(
        "SELECT id, pw_hash FROM users WHERE username = '" + username + "'"
    ).fetchone()
    if row and verify(password, row["pw_hash"]):
        session.user_id = row["id"]      # session id is unchanged from before login
        return True
    return False

12. This endpoint changes a user's email and is authenticated by the session cookie alone. Identify the missing control and add it in words.

@app.post("/account/email")
def change_email(req):
    set_email(req.session.user_id, req.form["new_email"])
    return "Email updated"

Part C — Fix it / write the secure version ⭐⭐

13.† Rewrite Exercise 7's get_balance to be safe, and explain in one sentence why your version makes the value impossible to interpret as SQL.

14. Rewrite Exercise 8's profile_header to be safe against XSS. Then state what additional, browser-side control you would add so that an injection on some other, forgotten endpoint still fails.

15. An endpoint must let users sort a report by a column they choose (?sort=balance). You cannot parameterize a column name. Write the safe pattern in code or precise pseudocode.

16.† Rewrite Exercise 10's fetch_logo with an application-layer SSRF guard. List the two additional defenses (beyond your code) that a complete SSRF mitigation needs, and say why code alone is insufficient.

17. Write the cookie attributes you would set on Meridian's session cookie, and state in one phrase what each attribute defends against.


Part D — Write the CSP / write the policy / write the rule ⭐⭐

18.† Write the CSP. Write a strong Content-Security-Policy header for Meridian's customer-facing banking pages that: serves all scripts and styles from the site's own origin, forbids inline scripts, forbids plugins, prevents the page from being framed by other sites, and reports violations to /csp-report. Annotate what each directive does.

19. A developer proposes this CSP: Content-Security-Policy: script-src 'self' 'unsafe-inline'. Explain, in two sentences, why this provides almost no XSS protection and what single change fixes it.

20.† Write the detection. Write an illustrative SIEM/SQL-style query over web_access_logs (fields: src_ip, request_uri, status_code, event_time) that flags likely SQL-injection probing from a single source in the last 15 minutes. State one thing your rule will miss and why.

21. Write the policy snippet. Draft a three-bullet web-application security standard for Meridian's program covering injection, XSS, and CSRF — each bullet stating the required control, not just the goal.

22. Write the rule. Write an alert (in words or pseudocode) for SSRF: it should fire when an application's outbound fetch resolves to a private, loopback, or link-local address — including the cloud metadata IP 169.254.169.254. Which log source(s) feed it?


Part E — Analyze this (WAF & web logs) ⭐⭐

23.† Analyze this log. All source IPs are documentation range 198.51.100.0/24. Times are UTC.

14:22:01 src=198.51.100.7  "GET /search?q=loan+rates HTTP/1.1"                         200
14:22:03 src=198.51.100.7  "GET /search?q=loan'+rates HTTP/1.1"                        500
14:22:04 src=198.51.100.7  "GET /search?q=loan'+OR+'1'='1 HTTP/1.1"                    500
14:22:05 src=198.51.100.7  "GET /search?q=loan'+UNION+SELECT+null,null-- HTTP/1.1"     200
14:22:06 src=198.51.100.7  "GET /search?q=loan'+UNION+SELECT+null,null,null-- HTTP/1.1" 200

(a) What activity is this, and what is the attacker doing across these five requests? (b) Which two fields are the strongest indicators? (c) The /search endpoint is the vulnerability — what is the root cause and the fix? (d) Why is the 500 → 200 transition at 14:22:05 significant to a defender?

24. Analyze this WAF log. Your WAF is in alert-only mode.

ruleId=942100 msg="SQL Injection Detected" uri=/api/report param=filter action=ALERT  src=198.51.100.40
ruleId=942100 msg="SQL Injection Detected" uri=/api/report param=filter action=ALERT  src=198.51.100.40
ruleId=941100 msg="XSS Detected"           uri=/feedback   param=body   action=ALERT  src=198.51.100.41

(a) The first two lines repeat for /api/report. What does alert-only mean for whether these attacks reached the app? (b) A teammate says "the WAF caught it, we're fine." Respond. (c) What two actions should the SOC take based on these alerts?

25.† Analyze this application log.

session=8f3a... user=jlopez src=203.0.113.10 action=view_dashboard
session=8f3a... user=jlopez src=203.0.113.99 action=add_payee     payee=NEW
session=8f3a... user=jlopez src=203.0.113.99 action=transfer      to=NEW amount=9500

(a) What is the anomaly, and which web attack class from this chapter does it most suggest? (b) Name two controls that would have prevented or detected this. (c) Why might a WAF not catch this?

26. Analyze this. Over one hour, /transfer logs 240 requests that were rejected with reason csrf_token_invalid, all from varied source IPs, each tied to a different valid user session. What is likely happening, and is the rejection good news or bad news? What would you check next?


Part F — Respond to this incident (tabletop) ⭐⭐–⭐⭐⭐

27.† A penetration test reports stored XSS in the "transfer memo" field of Meridian's portal: a memo is rendered unescaped in the back-office admin console that staff use to review transfers. Walk through your response in ordered steps: immediate containment, the code fix, how you would find whether it was already exploited, and the defense-in-depth control that would have limited the blast radius.

28. Your SOC sees the §13.6 war-story pattern: weeks of unread WAF SQL-injection alerts against one endpoint. Write the first five actions you take in the hour after noticing, in priority order, and justify the ordering.


Part G — Design it ⭐⭐⭐

29.† Design the controls. Meridian is launching a new feature: customers can upload a profile photo and supply a "personal website" URL shown on their public profile, and support staff view both in an internal console. Enumerate every web vulnerability class from this chapter that this feature could introduce, and specify the control for each. (Hint: the URL field and the console rendering are each a trap.)

30. Design the layered defense. For a single state-changing endpoint (POST /transfer), draw or list the full stack of defenses across the three layers from §13.1 (code, browser, edge) that protect it, and for each layer name what it stops and what it does not.

31. ⭐⭐⭐ Design a code-review checklist. Produce a one-page web-security code-review checklist a Meridian engineer could apply to any pull request, organized by the chapter's attack classes. Each item should be a yes/no question whose "no" is a finding.


Part H — CTF-style challenge ⭐⭐⭐

32.† The clever bypass. A developer "fixed" SQL injection by rejecting any input containing a single quote ('). Explain, without writing a working exploit, two distinct reasons this defense is inadequate (consider: inputs that need no quote; encodings; second-order/stored injection; legitimate inputs it breaks). Then state the fix that makes the entire class of bypass irrelevant, and why it does.


Part I — Interleaved & forward-looking ⭐⭐

33. (Interleave Ch.9) Chapter 9 set Meridian's HTTP-security-header baseline including HSTS and CSP. For each of HSTS, X-Content-Type-Options: nosniff, and a strict script-src 'self' CSP, name the specific attack it blunts. Which of the three is the primary XSS control?

34. (Interleave Ch.12) Chapter 12 introduced SAST, DAST, and SCA. For each web attack in this chapter, say which of SAST or DAST is more likely to find it before deployment, and why. Which attack class is hardest for either to find automatically?

35. (Interleave Ch.6/7/10) SSRF defense relies partly on network controls. Using egress filtering (Chapters 6–7) and network monitoring (Chapter 10), describe the network-tier half of an SSRF defense and why the application-tier guard alone is insufficient.

36. ⭐⭐⭐ (Forward to Ch.21) The §13.6 detections each ran against a single log source. Write two sentences predicting how a SIEM (Chapter 21) improves web-attack detection by correlating across the web, network, and identity tiers — give one concrete multi-source attack story it could catch that no single log shows.


Solutions to daggered (†) problems are in the Answers appendix. The remaining problems are open by design — bring them to a study group, your instructor, or your own lab.