Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.21.2
hooks:
- id: gitleaks
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: detect-private-key
- id: check-added-large-files
12 changes: 6 additions & 6 deletions labs/lab1.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ Open `http://127.0.0.1:3000` in your browser. Note what you see:

Create `submissions/lab1.md` and **fill in the template below** with your real observations. Don't paraphrase — record what you actually saw.

```markdown
````markdown
# Lab 1 — Submission

## Triage Report: OWASP Juice Shop
Expand All @@ -115,7 +115,7 @@ Create `submissions/lab1.md` and **fill in the template below** with your real o

### Health Check
- HTTP code on `/`: <should be 200>
- API check (first 200 chars of `/rest/products`):
- API check (first 200 chars of `/api/Products`):
```
<paste output>
```
Expand Down Expand Up @@ -143,7 +143,7 @@ Which of these are MISSING? (cross-reference Lecture 1 OWASP Top 10:2025 — A06
1. **<risk name>** — <why it matters; map to one OWASP Top 10:2025 category>
2. **<risk name>** — <why; map to OWASP>
3. **<risk name>** — <why; map to OWASP>
```
````

### 1.4: Cleanup (when done)

Expand Down Expand Up @@ -274,7 +274,7 @@ A "GitHub Community" section with 1-2 sentences explaining:

### B.3: Document in `submissions/lab1.md`

```markdown
````markdown
## Bonus: CI Smoke Test

- Workflow file: `.github/workflows/lab1-smoke.yml`
Expand All @@ -285,7 +285,7 @@ A "GitHub Community" section with 1-2 sentences explaining:
```
<paste your "HTTP/1.1 200 OK ..." block>
```
```
````

---

Expand Down Expand Up @@ -316,7 +316,7 @@ PR checklist (paste this into your PR body):

### Task 1 (6 pts)
- ✅ Juice Shop v20.0.0 container running on `127.0.0.1:3000` (proof: `docker ps` output in submission)
- ✅ Homepage returns HTTP 200; `/rest/products` returns a JSON list
- ✅ Homepage returns HTTP 200; `/api/Products` returns a JSON list
- ✅ Triage report has all six sections filled in with **real** values (no template placeholders left)
- ✅ At least three security headers are correctly identified as present or missing
- ✅ Top 3 risks each mapped to an OWASP Top 10:2025 category (A01–A10)
Expand Down
12 changes: 6 additions & 6 deletions labs/lab11.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ curl -skI https://localhost | tee labs/lab11/results/headers.txt

### 11.4: Document in `submissions/lab11.md`

```markdown
````markdown
# Lab 11 — BONUS — Submission

## Task 1: TLS + Security Headers
Expand Down Expand Up @@ -155,7 +155,7 @@ curl -skI https://localhost | tee labs/lab11/results/headers.txt
- Referrer-Policy: ...
- Permissions-Policy: ...
- Content-Security-Policy: ...
```
````

---

Expand Down Expand Up @@ -212,7 +212,7 @@ Write the 7-step runbook described in Reading 11 (Detect expiry → Order → Va

### 11.8: Document in `submissions/lab11.md`

```markdown
````markdown
## Task 2: Production Posture

### Rate limit proof
Expand Down Expand Up @@ -243,7 +243,7 @@ Write the 7-step runbook described in Reading 11 (Detect expiry → Order → Va

### What OCSP stapling buys you (2-3 sentences, reference Reading 11)
Why is OCSP stapling useful for production but not for a self-signed lab cert?
```
````

---

Expand Down Expand Up @@ -313,7 +313,7 @@ docker compose exec waf cat /var/log/modsec/audit.log | tail -50 \

### B.5: Document in `submissions/lab11.md`

```markdown
````markdown
## Bonus: WAF Sidecar with OWASP CRS

### Setup choice
Expand Down Expand Up @@ -344,7 +344,7 @@ Rule ID: **<e.g. 942100>** — OWASP CRS rule name: **<e.g. SQL Injection Attack
What does the WAF buy you that Lecture 5's SAST + DAST + the L7 Conftest gate didn't already?
What does it COST you? (FP risk at higher paranoia levels; ops overhead; cert/config sprawl.)
When would you NOT deploy a WAF in front of a service?
```
````

---

Expand Down
12 changes: 6 additions & 6 deletions labs/lab12.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ cat labs/lab12/results/kata-kernel.txt

### 12.3: Document in `submissions/lab12.md`

```markdown
````markdown
# Lab 12 — BONUS — Submission

## Task 1: Install + Hello-World
Expand Down Expand Up @@ -137,7 +137,7 @@ cat labs/lab12/results/kata-kernel.txt
### Why the kernel differs (Reading 12)
Reading 12 explains the model. Reference Lecture 7 slide 14 — runc CVE-2024-21626 ("Leaky Vessels").
What does the kernel difference imply for that attack class? (2-3 sentences.)
```
````

---

Expand Down Expand Up @@ -193,7 +193,7 @@ done | tee labs/lab12/results/io-bench.txt

### 12.6: Document in `submissions/lab12.md`

```markdown
````markdown
## Task 2: Isolation + Performance

### Isolation: /dev diff
Expand Down Expand Up @@ -229,7 +229,7 @@ kata:
When is the security gain (separate kernel, runc-CVE class blocked) worth the cost?
When isn't it? Give one example each (e.g., "multi-tenant SaaS workloads = yes;
single-tenant batch jobs = no").
```
````

---

Expand Down Expand Up @@ -286,7 +286,7 @@ sudo cat /tmp/lab12-target

### B.4: Document in `submissions/lab12.md`

```markdown
````markdown
## Bonus: Container-Escape PoC

### Vector chosen
Expand Down Expand Up @@ -329,7 +329,7 @@ Host verification:
- Why does Kata block what runc allows? (Reference: Kata's micro-VM filesystem IS NOT the host filesystem — bind mounts are virtualized via virtio-fs/9p inside the VM.)
- What real-world threat does this map to? (Multi-tenant CI runners running `--privileged` containers; misconfigured Kubernetes pods.)
- What does this NOT block? (Pure side-channel attacks on the kernel itself, cross-tenant timing attacks. Reading 12's "Confidential Containers" section is where THOSE get defenses.)
```
````

---

Expand Down
1 change: 1 addition & 0 deletions labs/lab2.md
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ PR checklist body:
- 🚨 **`docker: invalid reference format`** — make sure you wrote `threagile/threagile:0.9.1` not `threagile:v0.9.1` (no namespace).
- 🚨 **Output directory empty after run** — Threagile needs write access. Verify the volume mount `-v "$(pwd)/labs/lab2":/app/work` and that `output/` exists with write perms before running.
- 🚨 **`undefined protocol: xyz`** — Threagile validates protocol enums. Common typo: `JDBC-encrypted` (capitalized) — use lowercase `jdbc-encrypted`.
- 🚨 **`the sheet name length exceeds the 31 characters limit`** — Threagile uses your model's `title:` as the Excel sheet name in `risks.xlsx`; Excel caps sheet names at 31 characters. Keep `title:` short (≤ 31 chars). The run dies at the Excel step, so you get JSONs and diagrams but no `risks.xlsx`/`report.pdf`. (The `Fontconfig error` lines are harmless noise — ignore them.)
- 🚨 **PDF is huge / slow to open** — that's normal. Use `risks.json` + `jq` for fast iteration; open the PDF only for the final report.
- 🚨 **Secure variant has MORE risks than baseline** — usually means you added a new asset without declaring its security requirements. Threagile rules can fire on new assets you accidentally introduced; review your diff carefully.
- 🚨 **"My auth-flow model has 50 risks!"** — that's usually because you copied the baseline model and trimmed it. Build the auth model **from scratch** — minimum viable assets + links + data. Threagile rules multiply on under-specified models.
Expand Down
2 changes: 1 addition & 1 deletion labs/lab2/threagile-model.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
threagile_version: 1.0.0

title: OWASP Juice Shop — Local Lab Threat Model
title: OWASP Juice Shop Threat Model
date: 2025-09-18

author:
Expand Down
4 changes: 2 additions & 2 deletions labs/lab6.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ jq '.results.failed_checks[] | select(.check_id | startswith("CKV2_CUSTOM_"))' \

### B.5: Document in `submissions/lab6.md`

```markdown
````markdown
## Bonus: Custom Checkov Policy

### Policy file (paste full contents of labs/lab6/policies/my-custom-policy.yaml)
Expand All @@ -271,7 +271,7 @@ Output of `jq '.results.failed_checks[] | select(.check_id | startswith("CKV2_CU
### Why this rule matters
2-3 sentences: what real-world incident or compliance requirement does your custom policy address?
(References to specific incidents or NIST/CIS controls strengthen the answer.)
```
````

---

Expand Down
8 changes: 4 additions & 4 deletions labs/lab7.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ trivy k8s --namespace juice-shop \

### 7.8: Document in `submissions/lab7.md`

```markdown
````markdown
## Task 2: Kubernetes Hardening

### Manifests (paste relevant snippets)
Expand Down Expand Up @@ -258,7 +258,7 @@ Output of `kubectl get pod -n juice-shop -l app=juice-shop`:
### What broke and how you fixed it (2-3 sentences)
`readOnlyRootFilesystem: true` likely broke Juice Shop. What paths did it need to write?
How did you fix it (which emptyDir mounts)?
```
````

---

Expand Down Expand Up @@ -316,7 +316,7 @@ conftest test /tmp/bad-pod.yaml --policy labs/lab7/policies

### B.3: Document in `submissions/lab7.md`

```markdown
````markdown
## Bonus: Conftest Policy

### Policy (paste labs/lab7/policies/pod-hardening.rego)
Expand All @@ -337,7 +337,7 @@ conftest test /tmp/bad-pod.yaml --policy labs/lab7/policies
### What this prevents at CI time (2-3 sentences)
Reference Lecture 7 slide 16 (admission control diagram). What Class of bug does this
policy catch BEFORE `kubectl apply` runs? Why is catching at CI-time better than at admission-time?
```
````

---

Expand Down
12 changes: 6 additions & 6 deletions labs/lab8.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ cosign verify \

### 8.6: Document in `submissions/lab8.md`

```markdown
````markdown
# Lab 8 — Submission

## Task 1: Sign + Tamper Demo
Expand Down Expand Up @@ -196,7 +196,7 @@ Output of `cosign verify` on tampered digest:
### Why digest binding matters (Lecture 8 slide 6)
2-3 sentences. The tampered re-tag pointed to a DIFFERENT digest; your signature was bound to the
ORIGINAL digest. What would have broken if Cosign had signed the tag instead?
```
````

---

Expand Down Expand Up @@ -271,7 +271,7 @@ cosign verify-attestation \

### 8.9: Document in `submissions/lab8.md`

```markdown
````markdown
## Task 2: SBOM + Provenance Attestations

### SBOM attestation
Expand All @@ -292,7 +292,7 @@ cosign verify-attestation \
Lecture 8 slide 12 + Lecture 9 slide 4 — at K8s admission time, a Kyverno verify-images policy
can require BOTH signatures AND specific attestation predicates. What's the operational difference
between a "signed but no SBOM" image and a "signed with SBOM" image when the next Log4Shell hits?
```
````

---

Expand Down Expand Up @@ -374,7 +374,7 @@ cat /tmp/blob-tamper.txt # paste this into submission

### B.5: Document in `submissions/lab8.md`

```markdown
````markdown
## Bonus: Blob Signing (Codecov 2021 mitigation)

### Sign + verify
Expand All @@ -394,7 +394,7 @@ Codecov's bash uploader was distributed via `curl | bash` without signature veri
If their CI consumers had been running `cosign verify-blob` before `bash`-ing the script,
how would the attack have failed? Reference Lecture 8 slide 14 + the specific cosign command
that would have caught it.
```
````

---

Expand Down
12 changes: 6 additions & 6 deletions labs/lab9.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ grep "Write to /tmp by container" labs/lab9/falco/logs/falco.log | head -5

### 9.6: Document in `submissions/lab9.md`

```markdown
````markdown
# Lab 9 — Submission

## Task 1: Runtime Detection with Falco
Expand Down Expand Up @@ -175,7 +175,7 @@ Falco log line showing your custom rule:
Your custom "write to /tmp" rule will fire on legitimate uses too (logging frameworks
often write to /tmp). What's your tuning approach? (2-3 sentences referencing the
`exceptions:` block vs `and not proc.name=...` patterns from Lecture 9.)
```
````

---

Expand Down Expand Up @@ -237,7 +237,7 @@ conftest test labs/lab9/manifests/bad-pod-no-resources.yaml \

### 9.10: Document in `submissions/lab9.md`

```markdown
````markdown
## Task 2: Conftest Policy-as-Code

### My policy file (paste labs/lab9/policies/extra/hardening.rego)
Expand All @@ -263,7 +263,7 @@ conftest test labs/lab9/manifests/bad-pod-no-resources.yaml \
### Why CI-time vs admission-time (Lecture 9 slide 9)
2-3 sentences. CI-time Conftest happens during PR review; admission-time Conftest happens at
`kubectl apply`. What's the operational benefit of running BOTH (defense in depth)?
```
````

---

Expand Down Expand Up @@ -311,7 +311,7 @@ grep "Cryptominer" labs/lab9/falco/logs/falco.log

### B.4: Document in `submissions/lab9.md`

```markdown
````markdown
## Bonus: Cryptominer Detection Rule

### Rule (paste)
Expand All @@ -328,7 +328,7 @@ grep "Cryptominer" labs/lab9/falco/logs/falco.log
- Which 2 indicators did you use and why?
- What does this miss? (i.e., the false-negative case — e.g., obfuscated mining over HTTPS)
- How would you combine this with the Lecture 9 SLA matrix?
```
````

---

Expand Down
8 changes: 4 additions & 4 deletions lectures/lec1.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ graph LR

```mermaid
flowchart LR
Dev[👩‍💻 Dev] -.--> Build[🏗️]
Ops[🖥️ Ops] -.--> Build
Sec[🛡️ Sec] -.--> Build
Build --> DevSecOps[🚀 DevSecOps<br/>Continuous, automated security<br/>at every stage]
Dev["👩‍💻 Dev"] -.-> Build["🏗️ Build"]
Ops["🖥️ Ops"] -.-> Build
Sec["🛡️ Sec"] -.-> Build
Build --> DevSecOps["🚀 DevSecOps<br/>Continuous, automated security<br/>at every stage"]

style DevSecOps fill:#FF9800,color:#fff
```
Expand Down
Loading