Back to path
AdvancedLedgerline · Project 11 of 12 ~6h· 5 milestones

See attacks in production and be ready to respond

Continues from the last build: The app is tested statically and dynamically, and its config is policy-gated.

Every request that hits it now passes through a real gate before it ships.

structured security logging without leaking secretsbrute-force, IDOR-probe, and injection detection heuristicsrate limiting and account lockout designOWASP A07 and A09 (auth failures, logging and monitoring failures)incident response runbook authoringsecret rotation and revocation proceduretabletop exercise facilitation and timinggenerating authorized attack traffic against your own instance

What you'll build

By the end, it logs auth events, access-control denials, and input-validation rejections as structured, secret-free JSON. A detection script turns that log stream into brute-force, IDOR-probe, and injection-attempt alerts, and you have proven each one fires by generating the traffic yourself. The login path throttles abusive clients and locks accounts out after repeated failures automatically. And you have a written, tabletop-tested incident runbook for a leaked-key or active-exploit scenario, with real rotation and revocation steps, not just a promise to be careful next time.

See how we teach, before you sign up

You don't just get code dumped on you. Every starter file and every solution is explained line-by-line, in plain English. Here's one real file from this project:

app/src/logging/logger.tstypescript
import pino from 'pino';

// TODO: configure redact paths so passwords, tokens, and cookies never reach disk
export const logger = pino({
  level: process.env.LOG_LEVEL || 'info'
});

export function logAuthEvent(event: string, ctx: Record<string, unknown>) {
  // TODO: emit a structured auth_success or auth_failure event
}

Reading this file

  • level: process.env.LOG_LEVEL || 'info'Log level is configurable per environment, verbose in dev, quieter in production.
  • export function logAuthEvent(event: string, ctx: Record<string, unknown>)A loose starter signature the learner will tighten into the typed version in the solution.

Starting point for milestone one, deliberately missing the redact config so the learner has to add it, not just copy it.

That's 1 of 8 explained code blocks in this single project.

The build, milestone by milestone

  1. 1

    Security logging that means something

    6 guided steps

    You cannot detect, investigate, or prove an attack happened if the only record is an unstructured console.log or nothing at all. But logging is also how secrets leak a second time, so redaction has to be structural, not a habit you might forget.

  2. 2

    Detect the obvious attacks

    6 guided steps

    A SAST or DAST scan finds a class of bug before release. It tells you nothing about whether someone is exploiting a bug in production right now. Detection is the other half of the job, turning a pile of JSON lines into a decision-worthy signal.

  3. 3

    Rate limiting and lockout as response

    5 guided steps

    Detection tells you an attack is happening. Rate limiting and lockout are the automatic reflex that blunts it while a human is still reading the alert. Two separate mechanisms matter here, one throttles by network origin, the other protects one account regardless of which ip is used.

  4. 4

    The incident runbook

    6 guided steps

    The first time you rotate a production credential under pressure should not be the first time you have ever done it. A runbook turns a panicked scramble into a checklist you already rehearsed, and it is the artifact an interviewer or a real employer will actually ask to see.

  5. 5

    Tabletop it

    6 guided steps

    A runbook nobody has rehearsed is a guess. Running the drill once, with a stopwatch, is what turns it from a document into muscle memory, and it is exactly how real security teams find the gaps before an actual incident does.

What's inside when you start

3 starter files, ready to clone
5 guided milestones
5 full reference solutions
8 code blocks explained line-by-line
5 "is it working?" checks
6 interview questions it prepares you for

You'll walk away with

A shared logger module with structural redaction, instrumented for auth events, access denials, and validation rejections
security/detect.js, a working detection script proven against traffic you generated yourself, flagging brute_force, idor_probe, and injection_attempt
A rate limiter on the login route plus an account lockout mechanism backed by failed_attempts and locked_until columns
security/incident-runbook.md covering detect, contain, eradicate, recover, and a rotation/revocation checklist for a leaked-key or active-exploit scenario
security/tabletop-log.md, a timed drill against a simulated alert with at least one identified gap and its fix applied to the runbook
Verified proof, via curl and psql, that the rate limiter and lockout actually engage under generated attack traffic

This is portfolio-grade. Build it free.

Sign up to unlock every milestone step-by-step, the code skeletons, full reference solutions, and checkable tasks, with your progress saved as you build.

Start building