Module 4 · Authentication and security

Lesson 22 — OWASP Top 10

SQL injection, XSS, CSRF, SSRF and broken access control — with real examples.

Published
In this lesson
  1. Exercise 1 — SQLi: the f-string that burns
  2. Exercise 2 — XSS: from JSON to the DOM
  3. Exercise 3 — SSRF: the guard
  4. Exercise 4 — check --deploy and the browseable API
  5. Exercise 5 — Components and dependencies
  6. Exercise 11 — The three from §11, hunted
  7. Exercise 12 — security.txt and the runbook
  8. Submit

Local environment, attacks against YOUR app. Don't look at solutions.md before submitting.

Exercise 1 — SQLi: the f-string that burns

  1. Write (only on a throwaway branch, to learn) a view that filters events with a cursor + f-string: f"... WHERE title LIKE '%{q}%'". Run it with q = "x' OR '1'='1". What did it return? And with q = "x'; DROP TABLE events_reservation; --" (on a disposable test DB).
  2. Rewrite it with %s parameters: repeat the payloads. What comes out now?
  3. Your available_seats uses the ORM: demonstrate with a payload-like input ("'; DROP -- as the seat row) that nothing explodes — the ORM parameterized.

Exercise 2 — XSS: from JSON to the DOM

  1. Create an event whose title is <img src=x onerror=alert('xss')>. Consume it from a mini HTML page with fetch + innerHTML: does it execute? (that is the FRONTEND's risk, not your API's).
  2. Switch to textContent (or the framework's escape): does it execute? Record the rule for your frontend team: "user HTML never goes through innerHTML; if there is legitimate rich HTML: sanitize with DOMPurify server-side or at render".
  3. Basic CSP headers on your response (or Nginx): Content-Security-Policy: default-src 'self' — what does that block from the previous scenario as a second layer?

Exercise 3 — SSRF: the guard

  1. Add (on a test branch) an endpoint POST /api/tools/fetch/ {"url":...} that returns the URL's title. Attack it: http://localhost:6379/ and http://169.254.169.254/latest/meta-data/ (locally there is no real metadata, but the technique is the cloud attack's).
  2. Implement the guard: http/https schemes only, resolve with socket.getaddrinfo and reject private/loopback/link-local IPs (block the ranges 169.254.0.0/16, 127.0.0.0/8, 10/8, 172.16/12, 192.168/16), and a domain whitelist if the case allows it.
  3. Why must DNS resolution happen BEFORE the fetch and against the IP you will connect to (DNS rebinding)?

Exercise 4 — check --deploy and the browseable API

  1. Run python manage.py check --deploy: list the warnings it gives you today.
  2. Configure the lesson's secure settings block (HSTS, secure cookies, nosniff, referrer, X-Frame-Options DENY) and run it again: does it go green?
  3. Turn off the browseable API in production (DEFAULT_RENDERER_CLASSES JSON only) and justify what it exposed.

Exercise 5 — Components and dependencies

  1. pip install pip-audit and run pip-audit over your requirements: how many known vulnerabilities are in your versions? Note the 2 most severe.
  2. Pin exact versions (==) in requirements and add pip-audit to your "local pipeline" (a script). Why is pinning + audit A06's minimum pair?

Exercise 11 — The three from §11, hunted

  1. Mass assignment: deliberately create the vulnerable endpoint (fields = "__all__" on the profile serializer) and demonstrate it: PATCH the profile with "is_staff": true → did the user self-escalate? Fix: explicit serializer + a regression test that sends the field and verifies it didn't land.
  2. Timing: compare secret == guess vs hmac.compare_digest with 1000 measurements (37's timeit): does the time difference reveal correct characters in the first? Paste the numbers.
  3. Dependencies: introduce a typo in a test dependency (pip install requets in a lab venv): what does it install? Afterwards: pin your dependencies with hashes (pip-compile --generate-hashes) and run pip-audit — 41's report.

Exercise 12 — security.txt and the runbook

  1. Write your /.well-known/security.txt (contact, expiry, disclosure policy, encryption for reports) and the test that verifies it exists and expires in the future.
  2. The finding's runbook (§12) applied to a simulated vulnerability ("external report: the events endpoint leaks emails in the reservation listing"): the 5 steps with real commands (how do you contain? which regression test? do you notify?). Max 1 page (48).
  3. The postmortem's root question: which PIECE of the course (50's review, 41's pipeline, 34's tests) would have caught that leak? If the answer is "none": that is the P1 action.

Submit

Paste the outputs of the attacks (on your environment!) and the implemented guards. Next: Lesson 23 — Secrets, rate limiting and GDPR.