Search Tech Journey

Find topics, journeys and posts

6-month learning plan83 / 130
back to blog
systemsintermediate 15m read

S083 · OWASP Top 10, Secrets Mgmt & Threat Modelling

The 10 ways your app will get hacked, and how to stop it.

Module M10: Security · Session 83 of 130 · Track: SYS 🛡️

What you'll be able to do after this session

  • Explain OWASP Top 10, Secrets Mgmt & Threat Modelling to a friend in one minute, out loud, no notes.
  • Recognise it when you see it in real code / systems / papers.
  • Complete the hands-on exercise at the end without looking up help.

Prerequisites

If you can't answer these in 30 seconds each, redo the linked session first:


Pre-read (skim before the session)


(a) Intuition · 5 min

The one-paragraph mental model. Why this concept exists, what problem it solves, and the analogy that makes it stick.

In one sentence: The 10 ways your app will get hacked, and how to stop it.

The OWASP Top 10 is exactly what it sounds like: the ten most common categories of web-app security failure, curated every few years by the Open Web Application Security Project from a survey of thousands of real breaches. Think of it as the checklist every code review, every pen test, every SOC 2 audit implicitly runs against.

Reading it once won't make you secure — but not reading it is professional malpractice. Almost every breach you've heard of (Equifax, Capital One, Target, LinkedIn, Uber, Optus) maps to one of these categories. The 2021 edition, in rough priority order: A01 Broken Access Control, A02 Cryptographic Failures, A03 Injection, A04 Insecure Design, A05 Security Misconfiguration, A06 Vulnerable Components, A07 Identification/Authentication Failures, A08 Software & Data Integrity, A09 Logging/Monitoring Failures, A10 SSRF.

Secrets management is the operational side. Every production system has API keys, DB passwords, signing keys, TLS certs. Where do they live? Not in git. Not in env files checked into the repo. Not in Slack. The industry answer is a vault: HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager, Azure Key Vault. Fetched at runtime, rotated automatically, never touched by a human.

Threat modelling is the proactive discipline. Before you ship a feature, you sit down with the design and ask, methodically, "who might attack this, how, and what's the blast radius?". The industry framework is STRIDE: Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, Elevation of privilege. Ten minutes of STRIDE per feature would have prevented most breaches on the front page.

Gotcha to carry forever: All ten of these categories are design and process failures, not "we forgot to install a library". You cannot bolt security on at the end — it has to be baked into how you design, code, review, deploy, and monitor.


(b) Visual walkthrough · 15 min

Diagrams, worked examples, step-by-step visuals.

The 2021 Top 10, ordered by frequency of appearance in real incidents:

#CategoryOne-line meaningReal breach
A01Broken Access ControlUser A can read User B's data via URL tamperingFacebook 2019 (50 M tokens)
A02Cryptographic FailuresData in transit/rest not properly encryptedEquifax 2017 partially
A03InjectionUntrusted input becomes code (SQLi, XSS, cmd)TalkTalk 2015 SQLi
A04Insecure DesignBusiness logic itself is flawedCoinbase 2022
A05Security MisconfigurationDefault creds, verbose errors, open S3 bucketsCapital One 2019 (S3 + SSRF)
A06Vulnerable/Outdated ComponentsOld lib with known CVEEquifax 2017 (Struts CVE)
A07Auth FailuresWeak passwords, no MFA, session mgmt bugsColonial Pipeline 2021
A08Software/Data IntegrityUnsigned updates, insecure deserialisationSolarWinds 2020
A09Logging/Monitoring FailuresBreach detected 200 days lateTarget 2013
A10SSRFServer-side request forgery to internal metadataCapital One 2019

Here's the STRIDE threat-model loop you should run on every new feature:

Worked example — Capital One 2019 breach mapped:

  • A10 SSRF: the WAF (Web Application Firewall) had an SSRF bug an attacker used to call http://169.254.169.254/ (AWS instance metadata).
  • A05 Misconfig: the IAM role attached to that instance had s3:* on 700+ buckets — over-privileged.
  • A01 Broken Access Control: the attacker used those creds to enumerate and download 100 M records.
  • A09 Logging Failure: exfil happened over months; no alert fired on the massive S3 GET volume.

Four categories, one incident, 100 M records leaked.


(c) Hands-on · 20 min

Code you type and run. Not pseudo-code — real, runnable, copy-pasteable.

Do the before and after on the two most common failures: SQL injection and hard-coded secrets.

# ---------- SQL Injection: BAD vs GOOD ----------
import sqlite3
db = sqlite3.connect(":memory:")
db.executescript('''
    CREATE TABLE users(id INT, name TEXT, email TEXT);
    INSERT INTO users VALUES (1,"alice","a@x.com"),(2,"bob","b@x.com");
''')
 
# BAD: string concatenation — attacker input is executed as SQL
def bad_lookup(name):
    q = f"SELECT * FROM users WHERE name = '{name}'"
    print("QUERY:", q)
    return db.execute(q).fetchall()
 
# GOOD: parameterised query — driver escapes for us
def good_lookup(name):
    return db.execute("SELECT * FROM users WHERE name = ?", (name,)).fetchall()
 
# Normal input works for both
print("bad ok :", bad_lookup("alice"))
print("good ok:", good_lookup("alice"))
 
# Malicious input
payload = "alice' OR '1'='1"
print("BAD returns EVERYTHING:", bad_lookup(payload))
print("GOOD returns nothing:  ", good_lookup(payload))
 
# ---------- Secrets: BAD vs GOOD ----------
# BAD: hard-coded in source, ends up in git history forever
API_KEY = "sk-live-abcdef1234567890"  # never do this
 
# GOOD: fetch at runtime from environment (12-factor) or a vault
import os
API_KEY = os.environ.get("STRIPE_KEY")
if not API_KEY:
    raise RuntimeError("STRIPE_KEY missing — refuse to start")
 
# ---------- Tiny threat model in code comments ----------
# Feature: /api/download?report_id=42
# STRIDE:
#   Spoofing:          require session cookie (S081)
#   Tampering:         URL is server-authoritative; server picks path
#   Repudiation:       audit log user_id + report_id + timestamp
#   Info disclosure:   AuthZ check: does user own report 42?  <-- often forgotten
#   DoS:               rate limit 60/min per user
#   Elevation of priv: report path must stay inside /reports/, no ../

Observe when you run it:

  1. The BAD query with alice' OR '1'='1 returns every user — the whole table.
  2. The GOOD query returns [] — the driver treats the payload as a literal string.
  3. Printing the raw query in BAD makes the attack obvious. In prod, you'd never see the query.
  4. The os.environ.get() pattern is the minimum bar; a real vault is one step further.
  5. The STRIDE comment block is the deliverable of a threat model — six categories, six mitigations, per feature.

Try this modification: add a /report HTTP endpoint that accepts a filename. First write it insecurely (open(user_input)). Then fix it by (a) whitelisting to /reports/, (b) calling os.path.realpath and checking it starts with /reports/. That's the "path traversal" fix — a subclass of A01.


(d) Production reality · 10 min

How this shows up in real systems, gotchas, war stories, common bugs.

Equifax 2017 (148 M records, USD ~1.4 B in costs). A known Apache Struts CVE, patched 2 months prior. Nobody in the org owned "patch the framework". A06 + A09 (no log alert on the anomalous outbound traffic). Fix: SBOM (software bill of materials) + auto-scanning (Dependabot, Snyk, Trivy) as blocking CI checks.

SolarWinds 2020. Attackers compromised the build system and inserted a backdoor into signed updates. Every customer that auto-updated (~18,000 orgs, including US federal agencies) got the backdoor. A08 — Software and Data Integrity Failures. Fix: SLSA framework, reproducible builds, signed provenance (Sigstore).

Log4Shell (Dec 2021, CVE-2021-44228). One-line JNDI lookup in a logging library let attackers RCE any Java app that logged a user-controlled string. Every ops team on Earth spent Christmas patching. Lesson: transitive deps you didn't know you had can end your career.

The AWS SSRF pattern. The instance metadata endpoint http://169.254.169.254 gives IAM creds. Any SSRF bug in your app becomes credential theft in seconds. Fix: IMDSv2 (requires a token, blocks trivial GET), and least-privilege IAM roles.

How top teams operate:

  • Security paved road: one blessed way to do auth, secrets, TLS. Deviations require security review.
  • Bug bounty: HackerOne / Bugcrowd — pay researchers instead of getting extorted.
  • Red team / purple team exercises.
  • Blameless postmortems on every incident, published internally.
  • Secrets scanning in CI: GitHub Secret Scanning, TruffleHog, gitleaks — reject the PR if a key is committed.
  • Automated dependency updates: Renovate/Dependabot with auto-merge for green PRs.

The mindset shift. Security isn't a team you throw problems at; it's a property of the whole software delivery pipeline — code, review, build, deploy, run, monitor. If security is a bottleneck team, you've built it wrong.


(e) Quiz + exercise · 10 min

  1. Name three of the OWASP Top 10 categories from memory and give a one-line real-world example of each.
  2. What is STRIDE and why do you run it before writing code, not after?
  3. Why is hard-coding an API key in source (even in a private repo) considered a critical failure?
  4. Explain how the Capital One 2019 breach chained A10 (SSRF) with A05 (misconfig) and A01 (broken access control).
  5. What is an SBOM and why did Log4Shell push the industry to adopt them?

Stretch (connects to S082 — TLS/PKI): Design the certificate + secrets story for a new microservice: how does it get (a) its TLS cert, (b) its database password, (c) its API key for a third-party service — such that no human ever sees any of them and rotation is automatic? Sketch the components involved.


Explain-out-loud test

If you can't teach these 3 things to a friend without notes, redo the session:

  1. What is OWASP Top 10, Secrets Mgmt & Threat Modelling? (one sentence, no jargon)
  2. When would you use it? (one concrete example)
  3. When would you NOT use it? (one anti-pattern)

What comes next


Part of a 130-session evergreen learning series. Session structure: (a) intuition · (b) visual walkthrough · (c) hands-on · (d) production reality · (e) quiz + exercise. Duration: 60 minutes.

More from M10 · Security

all modules →
  1. 081AuthN vs AuthZ, Sessions & Password Storage
  2. 082TLS 1.3, PKI & Cert Lifecycle