Fix the code
Detections catch an attacker; they don't fix the hole. Here your coding agent closes five real bugs — one commit, one test, one proof at a time.
What you'll learn
- ✓Why a detection is containment, not a fix
- ✓Turn each threat-model finding into a prompt for your agent
- ✓Close five real auth bugs with a test for each
- ✓Prove every fix live against the running app
Fix the code
A block stops one address. It never closes the bug that let them in. This episode does the real repair — in the code — and the twist that ties the series together: you don't write the fixes, your coding agent does. The threat model already wrote the exact change for every gap, plus a prompt you paste straight into the agent.
We close five real holes in the lab's auth, one at a time, each with a test, each proven live.
The DO-NOW board
From the Code Findings report, the five highest-leverage fixes:
| ID | The gap | The fix |
|---|---|---|
| F1 | anonymous requests write a database session row | a signed double-submit cookie — no session row |
| F2 | rejected requests flood the audit log | cap audit writes per window, make them searchable |
| F6 | /API/AUTH/LOGIN sidesteps the firewall | strict, case-sensitive routing |
| F3 | a flood can lock a real member out of their account | the OWASP device-cookie pattern |
| F5 | a stolen admin session can mint new admins | step-up re-authentication before role changes |
The loop for every fix
Each finding becomes a prompt. Paste the finding into your agent and let it implement the described change, then:
npm test # a new test for this fix must pass
git commit # one commit per fix, with the finding referenced
Fix F1 — stop anonymous session rows (proven live)
Anonymous visitors were each creating a DB session row — millions an hour under load. The fix issues a signed cookie instead of persisting a session:
// anonymous: a signed double-submit cookie, never a session row
let value = readCsrf(req);
if (!value) {
value = signCsrf(csrf());
res.cookie("__Host-lab_csrf", value, { httpOnly: true, sameSite: "strict" });
}
Proof, against the fixed app:
for i in $(seq 1 65); do curl -s :3000/api/me; done # cookieless
psql -tAc "SELECT count(*) FROM sessions" # → 0
65 requests, zero rows. The attack now writes nothing.
Fix F6 — close the routing bypass (proven live)
A mixed-case path slipped past a firewall rule written for the lowercase route. Strict, case-sensitive routing closes it:
curl -i :3000/API/AUTH/LOGIN # → 404, no longer an alias for the real route
F2, F3, F5 — in brief
- F2 caps audit writes to one rejection per
(category, client)per window, so a flood can't bury the real evidence, and makes the log filterable by type. - F3 adopts the OWASP device-cookie pattern: a returning owner with a valid device cookie is exempt from the per-account lockout, so an attacker can't lock a real member out of their own account.
- F5 requires a fresh password check (step-up) in the last five minutes before any admin role change, so a stolen session that holds the cookie but not the password can't grant admin.
The receipts
git log --oneline # five commits, one per fix
npm test # all green
And the detections change too: with the code fixed, the noisy rule goes quiet, and you can tighten it to exact-match mode — because the bug it watched for is gone.
What you just did
You closed five real bugs for good — your agent writing each change, a test guarding it, a live proof confirming it — while your SecureNow events kept flowing untouched. In Episode 5 we tackle the hardest category of all: authorization.
Try it on your own app
Start the threat model, then plug SecureNow in — the whole series works on your project today.