| id | course-secure-code-l01 | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| type | course | |||||||||||||||
| title | Lesson 1: Plausible is not safe | |||||||||||||||
| summary | Fetch the course through the FlyPython Skill, read a notes service that looks fine, then replay nine attacks against it and watch every one succeed. | |||||||||||||||
| lang | en-US | |||||||||||||||
| content_version | 1 | |||||||||||||||
| status | reviewed | |||||||||||||||
| reviewed_on | 2026-10-11 | |||||||||||||||
| hints |
|
The course files are in your working folder, fetched by your agent. You have read the starter without running it, written down what you think is wrong, and then replayed the attacks — and you can say what an attacker gets from each of the five functions. No code is changed in this lesson.
Open your coding agent in an empty working folder and paste this one sentence:
Read https://flypython.com/skills/flypython/SKILL.md and start the FlyPython course
secure-ai-generated-code.
The agent gives you an authorization link with a short code. Open it, log
in, make sure the code matches what the agent showed you, and click
Allow — then tell the agent "done". It writes this course's files to
courses/secure-ai-generated-code/.
Prerequisite: these courses need a coding agent that can run commands and reach the network. A chat-only web AI cannot do them.
Safety note: the attacks in this course touch only the course's own files and temporary folders. One test deliberately unpickles a harmless payload that creates a directory in a temporary folder — that is the evidence, not an accident.
AI-written code is usually readable, consistent, and documented. Those are the signals reviewers use to decide code is fine — and none of them say anything about what a hostile input can make it do. The starter works for every friendly input. That is exactly why it is dangerous.
Open starter/notes_app.py and read the five functions after init_db.
For each one, write one line: what input does it trust, and what could
go wrong? Do not run anything yet.
Ask the agent to survey without changing anything:
"Read COURSE.md — it is the teaching contract for this folder. Then read TASK.md and starter/notes_app.py. Do not change any file. For each function, tell me which input it trusts that it should not."
Then run the learner's command and the attack replay:
python verify.py
python starter/attack_replay.py scenario/team-notesThe replay prints blocked=0/9. Read the [OPEN] lines — each is a real
consequence:
| Attack | What the attacker got |
|---|---|
t01, t02 (sql) |
Bob's and Carol's notes, including "Salary review", from a search as Alice |
t03, t04 (path) |
the contents of secrets.txt, a file outside attachments/ |
t05, t06 (secret-key) |
a service that started with a key everyone can read in the source |
t07 (fast-hash) |
a stored hash that one MD5 call reproduces — and a leaked MD5 that still logs in |
t08 (forged-session) |
an admin session the attacker signed with their own key |
t09 (pickle-session) |
code execution: the payload created a directory on load |
The suite has eleven failing tests that pin these behaviors. The maintainer command prints them:
python verify.py starter --expect-failureFive tests already pass: a normal search works and is owner-scoped, a normal attachment reads, a password verifies against its own hash, a session round-trips, and the replay prints usage. Every friendly path works.
Compare your warm-up notes with the replay. Which flaws did you spot by reading, and which did you miss? Then pick the flaw you missed and ask the agent to explain the attack in two sentences — not to fix it.
Run python verify.py. When you can answer these without looking, claim
the checkpoint with python verify.py --attest l01:
- How does query
%' OR owner != 'turn Alice's search into everyone's notes? Write out the SQL the starter actually runs. - Why does
t09count as code execution and not just "bad data"? - Which flaw did you miss in the warm-up, and what about the code made it look fine?
Your warm-up notes, the replay output, and your three answers.