Lab 01 — Crash Triage, Minimization, Patch, and Regression

Difficulty: 4/5 | Runs locally: yes

Pairs with the Phase 08 WARMUP Chapters 5–9 (sanitizers, crash-to-impact, minimization, root cause, patching) and the HITCHHIKERS-GUIDE ("Triage Procedure", "The Triage Record"). This is the core workflow lab of vulnerability research.

Why This Lab Exists (Purpose & Goal)

A fuzzer is easy to run; the hard, valuable, employable skill is what you do with the crashes. A real campaign produces thousands of crashing inputs that, after deduplication, are a handful of bugs — and each must be understood to root cause, fixed properly, and locked down with a regression test. The goal of this lab is to build that full triage workflow — dedup → minimize → root-cause → patch → regress — which is the day-to-day loop of a vulnerability researcher and a product-security engineer.

The Concept, In the Weeds

The lab uses a toy image-header parser with three safe crash signatures (truncation, invalid dimensions, checksum mismatch). The workflow embeds several deep ideas:

  • Dedup by root-cause signature, not by input. A fuzzer finds the same bug through countless inputs; "I found 4,000 crashes" is 4,000 inputs, which after dedup are 3 bugs. Counting crashes as bugs (a flagged mistake) wildly overstates findings.
  • Minimize while preserving the signature. Delta-debugging reduces a noisy crash to the smallest input that still triggers the same root cause. The minimized input is what becomes a crisp regression test.
  • Crash ≠ exploitable. The discipline you must internalize is the chain crash → reachability → controllability → boundary → impact — and stating what you proved versus what you infer. Overclaiming exploitability is a reputation-killer.
  • Patch the class, not the input. Comparing vulnerable_parse with patched_parse shows the fix restoring the invariant (bounds, exact consumption), not special-casing the crashing sample — then every minimized case becomes a regression so the bug can never silently return.

Why This Matters for Protecting the Company

Memory-corruption and parser bugs are the highest-severity vulnerabilities, and the company's ability to respond to them — whether in its own code or in a dependency — depends on engineers who can take a crash from a fuzzer or a bug report and drive it to a correct, regression-tested fix without overstating or understating the risk. This triage workflow is exactly what turns "the fuzzer found something" into "the bug class is closed and can't come back." It is also the skill behind credible vulnerability reports and responsible disclosure (you report root cause and impact accurately, with a minimized reproducer), which is how the company contributes to and benefits from the broader security ecosystem.

Build It

Build the triager: deduplicate crashes by signature; minimize an input while preserving the root-cause signature; compare vulnerable_parse with patched_parse; convert every minimized case into a regression test.

LAB_MODULE=solution pytest -q

Validation — What You Should Be Able to Do Now

  • Deduplicate crashes by root-cause signature and report bugs, not crash counts.
  • Minimize a crash and explain why the minimized input is the right basis for a regression test.
  • Walk crash → reachability → controllability → boundary → impact, separating proven from inferred, without overclaiming.
  • Patch the invariant (not the crashing input) and prove the regression fails before / passes after.

The Broader Perspective

This lab installs the calibrated honesty that defines a credible vulnerability researcher: you can distinguish a controllable heap write across a trust boundary from a null-deref that needs a local malicious input, and you say which is which. That precision — proven vs. inferred, bug vs. crash, class vs. instance — is the difference between a report a vendor acts on and one they dismiss, and between a researcher who is trusted and one who cries wolf. The fix-plus-regression discipline (never patch a symptom; always close the class and lock it with a test) is the same one you applied to the C memory lab (Phase 01) and will apply to every bug you ever fix. Honesty about uncertainty is a professional virtue, not a weakness.

Interview Angle

  • "Is this crash security-relevant?" — Walk crash → boundary → reachability → controllability → demonstrated impact; local-only or fixed null-deref with no boundary crossed is low; attacker-reachable across a trust boundary with a controllable value is serious; state proven vs inferred.
  • "You found 4,000 crashes — how many bugs?" — Unknown until deduplicated by root cause; likely a handful; 4,000 is crashing inputs.

Extension (Stretch)

Run the native libFuzzer/AFL++ version of the target with sanitizers, and reproduce the same dedup/minimize/patch/regress loop on real crashes (build the coverage-guided fuzzer to generate them).

References

  • Phase 08 WARMUP Chapters 5–9; Andreas Zeller, "Delta Debugging".
  • libFuzzer / AFL++ / sanitizer documentation; Google Project Zero triage writeups.