Lion Cipher Lab
Turn a threat model into security test cases that run in CI (so the model cannot silently rot)
- AppSec / DevSecOps
- Intermediate
- ~90 min
- Free · no account required
Why it matters
Most threat models are written once, in a workshop, and then quietly drift away from the code. Six months later someone refactors a route, the ownership check falls out, and the threat model still says 'mitigated' because nobody re-reads a document. The fix is to give the model an executable half: every threat that can be checked by a machine becomes a test, the tests carry the threat's id, and a small script fails the build whenever the model and the tests disagree. Then the model cannot rot silently. In this lab you build a small document-sharing service, model it with STRIDE (16 threats),…
What you'll learn
- writing a data-flow diagram in plain text: external entities, processes, data stores, data flows and trust boundaries
- walking STRIDE per element of a real service and recording each threat with an id in a machine-readable threats.json
- rewriting each threat as an abuse case with one concrete, testable expectation (404 not 403, 410 at the exact expiry instant, 413 before the body is read)
- implementing abuse cases as a Python unittest suite that starts the service and talks real HTTP to it, each test tagged with its threat id
- building a traceability gate that fails CI when a threat has no test or a test points at a threat that no longer exists
- measuring a suite by breaking the service on purpose and recording which tests catch each regression
- marking threats that tests cannot cover as mitigated-elsewhere or accepted, with a rationale, an owner and a review date
- explaining why a green suite proves only the threats you wrote down
Steps in this lab
- What you are building, and why a threat model needs an executable half
- Set up a folder and check Python
- Build the service: docshare.py
- Smoke test it by hand (optional, two minutes)
- Question 1, what are we working on: write the data-flow diagram as text
- Question 2, what can go wrong: STRIDE per element into threats.json
- Question 3, what are we going to do about it: rewrite each threat as an abuse case
- Implement the abuse cases as a unittest suite tagged with threat ids
- The traceability gate: trace.py fails the build when model and tests drift
- Run both checks in CI on every push
- Question 4, did we do a good job: break the service on purpose and measure
- Close the gap the suite missed: add T17 and watch the gate enforce it
- What not to automate, and say so in the model
- Judgment: when this pays off, where it does not, and how a pro does it better