Skip to content

Latest commit

 

History

History
84 lines (69 loc) · 3.7 KB

L05.md

File metadata and controls

84 lines (69 loc) · 3.7 KB
id course-secure-code-l05
type course
title Lesson 5: Review your own AI-written code
summary Take the five questions and the scanner pass to a repository you own: find where input crosses a trust boundary, check each crossing for a mechanism, and write down what you did not review.
lang en-US
content_version 1
status reviewed
reviewed_on 2026-10-11
hints
title body
What this checkpoint tests
Self-attested: you confirm you reviewed code you own with this method. The evidence is your findings list and your evidence record — not a code we can check.
title body
Start where input enters
Request handlers, CLI arguments, file uploads, message consumers, anything that reads an environment variable. Each is a trust boundary.
title body
Fix with a test first
For each real finding, write the attack as a failing test before the fix — exactly as this course's suite did.

Lesson 5: Review your own AI-written code

Objective

You review a repository you own — ideally code an assistant wrote — with the same method, fix at least one finding with a test that proves it, and record what you did not review.

Why this lesson exists

The notes service was a sandbox with planted flaws and known answers. Your code has neither. What transfers is the method: find each place input crosses a trust boundary, ask who controls it and what they want, and check that the code uses a mechanism rather than a hope.

The lesson

  1. List the trust boundaries. Search for where input enters: web routes, CLI arguments, uploaded files, queue consumers, os.environ reads. Write the list before reading any of them closely.
  2. Run the scanner. ruff check --select S (or the scanner your team already uses) gives you the pattern-level findings in seconds. Triage each one: real, false positive, or accepted risk — and write down why.
  3. Ask the five questions the scanner cannot. For each boundary:
    • Does any input reach SQL, a shell, or a template other than as a bound parameter or argument list?
    • Does any input become part of a filesystem path, and is containment checked after resolving?
    • Is there any default, fallback, or example secret in the code path that runs in production?
    • Are passwords or tokens hashed with a slow, salted function and compared with hmac.compare_digest?
    • Does anything deserialize client data with pickle, marshal, shelve, or an unsafe YAML loader?
  4. Fix one finding with a test first. Write the attack as a failing test, fix it with a mechanism, watch the test pass. Ask your agent for the fix after the test exists, and review its diff against the mechanism, not just the test.
  5. Record. Verified / not verified / known limits. "Not verified" includes every boundary you listed but did not read.

If you find something serious in code other people depend on, follow your organization's or the project's security disclosure process before you open a public issue.

Exercise

Ask your coding agent to list the trust boundaries in your repository, then compare its list with yours. Note what each of you missed.

Checkpoint

This checkpoint is self-attested. When you can answer the questions below, claim it with python verify.py --attest l05:

  1. How many trust boundaries did you list, and how many did you actually read?
  2. Which finding did you fix, and what test proves it?
  3. Which scanner finding did you mark as a false positive or accepted risk, and why?

Expected evidence

Your boundary list, the scanner triage, the failing-then-passing test, and the three-line record. Keep findings about unfixed vulnerabilities out of public places until they are fixed.