OWASP Top 10: audit and harden a vulnerable service
Hands-on project — audit a deliberately vulnerable web service against the OWASP Top 10 (2021), exploit and then remediate the findings, and prove each fix with a before/after test.
Reading the Top 10 is not the same as finding and closing the holes it names. Take a small, deliberately vulnerable service, audit it category by category, prove each vulnerability with a working request, then remediate at the root cause and prove the fix — the loop a senior runs in a real security review.
Turn the unit’s mental model into a repeatable audit: map findings to OWASP categories, exploit them to confirm impact, fix at the root cause (deny-by-default authorization, allowlists, hardened config, patched dependencies), and verify each fix with a before/after test.
Audit a small web service (your own, OWASP Juice Shop, or the starter below) against the OWASP Top 10 (2021): find at least five findings across distinct categories, exploit each to confirm it, remediate at the root cause, and prove every fix with a repeatable before/after test.
- A findings table: each row names the OWASP 2021 category, the exploit request that proved it, the root-cause fix applied, and the test that now blocks it.
- The five-plus findings span distinct categories (not five variants of the same bug), with A01 covered by both an IDOR and a missing-function-level-authz example.
- Every fix has a repeatable test: the exact exploit request that worked before now returns 403/404 (authz), is rejected by the allowlist (SSRF/CORS), or is closed by the dependency upgrade — run live, not asserted.
- A one-paragraph write-up explaining, for at least one finding, why you fixed the root cause server-side rather than adding a WAF rule, an unguessable id, or a hidden UI element.
- Threat-model one feature for Insecure Design (A04): write abuse cases (e.g. price tampering, rate-limit bypass) alongside the user story and bake a server-side control in, showing the abuse case now fails.
- Add a CI security gate: dependency/CVE scan plus a small set of the before/after exploit tests, so the build fails if any remediated hole regresses or a new critical CVE appears.
- Add detection for A09 Security Logging & Monitoring Failures: structured auth-failure logs, a rate-limit on repeated failures, and an alert rule for credential-stuffing — verified by replaying a brute-force burst.
- Repeat the SSRF defense against DNS-rebinding and redirect-based bypasses, proving the IP re-check after redirect blocks an attacker host that resolves to a private range on the second lookup.
This is the loop you will run in every real security review: audit against the Top 10 as a prioritization map, prove each finding with a working exploit, fix at the root cause — deny-by-default authorization, allowlists with private-range rejection, hardened CORS and configs, patched dependencies — and lock each fix behind a before/after test so it cannot regress. Doing it once on a small vulnerable service makes the production version muscle memory, with access control earning the most rigor because it is the most common and among the most damaging. Now when you walk into a security review, your first move is not a scanner — it is opening a handler and asking whether the query proves ownership or merely proves the caller is logged in.
Something unclear?
Ask a question about this lesson. Questions are anonymous and go straight to the author to make the lesson better.