CMP-420 · Lesson 12 of 12 · 32 min
Capstone: threat modelling and hardening a web application, ethics and careers
This final lesson brings the course together in one project: securing an invented web application from design to release. You will build a threat model with STRIDE, choose controls from the earlier lessons, score the risk before and after, and run a release checklist. The lesson then turns to the professional side of security: the law around computer access and security research, responsible disclosure, ethics, and the careers open to graduates.
The application is Larch Clinic Booking, an invented online booking system for a small chain of physiotherapy clinics. Patients create accounts, book and cancel appointments, receive text-message reminders and leave notes for their therapist. Staff use an administration portal to manage schedules. The system is a Python web application with a relational database, deployed in containers, built by a continuous integration pipeline, with nightly backups to cloud storage.
Step 1: model the system
Threat modelling starts with a data flow diagram showing processes, data stores, external entities and data flows, with trust boundaries drawn wherever data crosses from a less trusted to a more trusted zone. For Larch Clinic Booking the main boundaries are between the internet and the web tier, between the web tier and the database, between staff devices and the administration portal, and between the build pipeline and production. Each boundary is a place where an attacker's input enters and where controls belong.
Step 2: enumerate threats with STRIDE
STRIDE, introduced in Lesson 1, prompts for six kinds of threat at each element: spoofing identity, tampering with data, repudiation, information disclosure, denial of service and elevation of privilege. Walking through the diagram element by element produces a list of concrete threats. Each is scored for likelihood and impact on a 1 to 5 scale, then matched with controls from the course, and scored again on the assumption that the controls work. The table in the program below summarizes the result.
# Threat model for "Larch Clinic Booking": STRIDE threats per component, scored before and after controls
threats = [
# component, STRIDE, threat, likelihood, impact, control, likelihood after
("Login", "S", "credential stuffing with reused passwords", 4, 4, "MFA + breached-password screening + rate limits", 1),
("Booking API", "E", "patient reads another patient's booking by id", 3, 5, "object-level authorization in data layer", 1),
("Booking API", "T", "price or slot altered in the request", 3, 3, "server-side recalculation and validation", 1),
("Web pages", "I", "script injection in appointment notes", 3, 4, "autoescaping templates + strict CSP", 1),
("Database", "I", "backup copied from storage bucket", 2, 5, "encrypted backups, private bucket, key in KMS", 1),
("Admin portal", "R", "staff deny changing a record", 3, 2, "append-only audit log with user and time", 1),
("Reminder SMS", "D", "SMS endpoint flooded, running up costs", 3, 2, "per-account quotas and anomaly alerts", 2),
("CI pipeline", "T", "compromised dependency in a build", 2, 5, "lock file hashes, SBOM, signed images", 1),
]
print(f"{'component':<13}{'S':<2}{'before':>7}{'after':>6} control")
before = after = 0
for comp, cat, t, l, imp, ctl, l2 in sorted(threats, key=lambda x: -x[3] * x[4]):
before += l * imp; after += l2 * imp
print(f"{comp:<13}{cat:<2}{l * imp:>7}{l2 * imp:>6} {ctl}")
print(f"total risk score: {before} before controls, {after} after ({100 * (before - after) / before:.0f}% lower)")component S before after control Login S 16 4 MFA + breached-password screening + rate limits Booking API E 15 5 object-level authorization in data layer Web pages I 12 4 autoescaping templates + strict CSP Database I 10 5 encrypted backups, private bucket, key in KMS CI pipeline T 10 5 lock file hashes, SBOM, signed images Booking API T 9 3 server-side recalculation and validation Admin portal R 6 2 append-only audit log with user and time Reminder SMS D 6 4 per-account quotas and anomaly alerts total risk score: 84 before controls, 32 after (62% lower)
Three observations matter. First, the highest-risk threats are the familiar ones: credential stuffing and broken object-level authorization, which is why Lessons 4, 7 and 9 spent so long on them. Second, controls reduce likelihood far more often than impact; a breach of health records is still severe, which justifies defence in depth rather than relying on any single control. Third, residual risk is never zero. The remaining scores are what the clinic's owners accept, and that decision belongs to them, informed by the analysis, not to the engineers alone.
Step 3: choose and map controls
Step 4: verify before release
A threat model is only useful if its controls are actually in place. Many teams turn the control list into an automated checklist that runs in the build pipeline against configuration and code, so a regression, such as debug mode switched on or a missing header, fails the build. The program below runs such a checklist against Larch Clinic's release configuration. One check fails: administration access is not yet restricted, so the release waits until the portal is placed behind the bastion and identity-aware proxy from Lesson 10.
# A pre-release security checklist evaluated against the project's configuration
config = {
"tls_min_version": "1.3", "hsts_max_age": 31536000, "csp": "default-src 'self'; object-src 'none'",
"cookie_flags": {"Secure", "HttpOnly", "SameSite=Lax"}, "password_hash": "argon2id",
"mfa_for_staff": True, "debug_mode": False, "db_user_privileges": {"SELECT", "INSERT", "UPDATE"},
"lockfile_hashes": True, "logs_contain_secrets": False, "backup_encrypted": True,
"container_user": "app", "admin_ip_allowlist": False,
}
checks = [
("TLS 1.2 or later", lambda c: c["tls_min_version"] in ("1.2", "1.3")),
("HSTS for at least a year", lambda c: c["hsts_max_age"] >= 31536000),
("CSP present", lambda c: bool(c["csp"])),
("Session cookie flags", lambda c: {"Secure", "HttpOnly"} <= c["cookie_flags"]),
("Memory-hard password hash", lambda c: c["password_hash"] in ("argon2id", "scrypt")),
("MFA for staff", lambda c: c["mfa_for_staff"]),
("Debug mode off", lambda c: not c["debug_mode"]),
("Least-privilege DB account", lambda c: "DROP" not in c["db_user_privileges"]),
("Pinned dependencies", lambda c: c["lockfile_hashes"]),
("No secrets in logs", lambda c: not c["logs_contain_secrets"]),
("Encrypted backups", lambda c: c["backup_encrypted"]),
("Non-root container", lambda c: c["container_user"] != "root"),
("Admin access restricted", lambda c: c["admin_ip_allowlist"]),
]
failed = [name for name, test in checks if not test(config)]
for name, test in checks:
print(f"[{'x' if test(config) else ' '}] {name}")
print(f"{len(checks) - len(failed)}/{len(checks)} passed; to fix before release: {failed}")[x] TLS 1.2 or later [x] HSTS for at least a year [x] CSP present [x] Session cookie flags [x] Memory-hard password hash [x] MFA for staff [x] Debug mode off [x] Least-privilege DB account [x] Pinned dependencies [x] No secrets in logs [x] Encrypted backups [x] Non-root container [ ] Admin access restricted 12/13 passed; to fix before release: ['Admin access restricted']
Automated checks complement, but do not replace, human review and testing. Before launch the clinic should commission an independent security assessment, including authorized penetration testing of the booking API and administration portal, as described in CISSP-115, and repeat it after major changes. A privacy impact assessment should accompany it, because the system handles health information.
Step 5: plan for incidents
Even a well-designed system can be breached, so the project ends with an incident response plan: who is on call, how to contain an incident (revoking sessions, rotating keys, disabling accounts), how evidence is preserved, when and how to notify patients and regulators, and how lessons learned feed back into the threat model. Regular exercises, even a one-hour tabletop walk-through of a scenario such as a leaked backup, reveal gaps cheaply.
The law and security work
Security professionals work close to legal lines, and good intentions are not a defence. Accessing a computer system without authorization is a crime in both countries, even to look for vulnerabilities, so testing must always rest on explicit written permission that sets the scope, timing and methods.
In Canada, section 342.1 of the Criminal Code makes it an offence to obtain a computer service or intercept a function of a computer fraudulently and without colour of right, and section 430(1.1) covers mischief in relation to computer data. PIPEDA and provincial laws require organizations to protect personal information and report serious breaches. There is no general statutory safe harbour for good-faith security research, so researchers rely on organizations' published vulnerability disclosure policies, and the Government of Canada operates its own disclosure program for federal systems.
Responsible disclosure
When someone finds a vulnerability in a product or service they do not own, coordinated vulnerability disclosure is the accepted practice: report it privately to the vendor, give them reasonable time to fix it, then publish details so that users can protect themselves and others can learn. ISO/IEC 29147 and 30111 describe how vendors should receive and handle reports. A common default is a 90-day deadline, popularized by Google's Project Zero, with extensions when a vendor is acting in good faith. Organizations should publish a vulnerability disclosure policy and a security.txt file (RFC 9116) saying how to report issues and promising not to pursue good-faith researchers; many also run bug bounty programs that pay for valid reports. Published vulnerabilities receive CVE identifiers so everyone can refer to them unambiguously.
from datetime import date, timedelta
# A coordinated vulnerability disclosure timeline with a 90-day default deadline
reported = date(2026, 7, 6)
plan = [("report received and acknowledged", 2), ("triage and severity agreed", 10),
("fix developed and tested", 45), ("fix released to customers", 60),
("advisory and CVE published", 90)]
for step, days in plan:
print(f"{(reported + timedelta(days=days)).isoformat()} day {days:>2}: {step}")
print("if no fix by day 90, the reporter may publish after notice, unless an extension is agreed")2026-07-08 day 2: report received and acknowledged 2026-07-16 day 10: triage and severity agreed 2026-08-20 day 45: fix developed and tested 2026-09-04 day 60: fix released to customers 2026-10-04 day 90: advisory and CVE published if no fix by day 90, the reporter may publish after notice, unless an extension is agreed
Ethics
Security skills can protect or harm, so the profession has explicit codes of conduct. The ACM Code of Ethics asks computing professionals to avoid harm, respect privacy, honour confidentiality and be honest about the limits of their systems. Security-specific codes, such as those of ISC2 and ISACA, add duties to protect society and act honourably. In practice, ethical security work means staying within authorized scope, minimizing access to personal data during testing, protecting what you find, reporting honestly rather than overstating or hiding risk, and refusing work intended to harm people or to break the law. When ethics and an employer's wishes conflict, professional codes, and in some cases whistleblower protections, support doing the right thing.
In Canada, professional engineering regulators protect the title engineer and require their members to hold paramount the safety and welfare of the public, which includes security failures that could cause harm. CIPS, the Canadian information technology professional association, offers the I.S.P. designation with its own code of ethics.
Careers in security
Security is one of the fastest-growing fields in computing, with persistent shortages of skilled people. Roles span the whole life cycle: security engineers and application security specialists build defences into products; security architects design systems; penetration testers and red teams assess them under authorization; analysts and incident responders in security operations centres detect and handle attacks; cryptographers and researchers study algorithms and vulnerabilities; and governance, risk and privacy specialists connect technology to law and business. Strong foundations in programming, operating systems, networks and cryptography, the subjects of this course and its prerequisites, matter more than any single tool. Many people build experience through capture-the-flag competitions, open-source contributions and bug bounty programs, and later add certifications such as the CISSP that this site's certification track covers.
Worked examples
Worked problem
Prioritizing threats
With limited time before launch, Larch Clinic can implement only three controls this week. Using the threat model, which three should come first?
Show solution
- Rank threats by risk score: credential stuffing (16), object-level authorization (15) and script injection in notes (12) are highest.
- Choose controls that remove the most risk per unit of effort: object-level authorization checks, MFA with rate limits for logins, and autoescaping templates with a CSP.
- Schedule the rest (encrypted backups, audit log, supply chain controls) for the following sprint, and record the accepted interim risk.
Answer: Object-level authorization, MFA with rate limiting, and output encoding with CSP address the three highest risks.
Worked problem
Finding a vulnerability by accident
While using a city recreation-booking website, a student notices that changing a number in the URL shows another family's booking details. What should the student do?
Show solution
- Stop immediately: do not try other numbers, download data or test further, because that could be unauthorized access.
- Look for the city's vulnerability disclosure policy or security.txt contact; if none exists, contact its privacy or IT office in writing.
- Report what was seen, how and when, without sharing anyone's personal data, and allow time for a fix before discussing it publicly.
Answer: Stop, report privately through the disclosure channel with minimal detail, and allow time for a fix.
Worked problem
Scoping an authorized test
A consulting firm is hired to test Larch Clinic Booking. What must the written authorization include?
Show solution
- The systems in scope (booking API, admin portal, test environment) and those out of scope (the SMS provider, third-party services, production patient data).
- Dates and times, permitted techniques, and limits such as no denial-of-service testing and no access to real patient records.
- Contacts for emergencies, how findings are reported and protected, and signatures from someone with authority over every system in scope.
Answer: Scope, exclusions, timing, permitted methods, data-handling rules, contacts and authorized signatures.
Common mistakes
MistakeSecurity can be added after the application is built.
InsteadThreat model during design and verify controls continuously; retrofitting costs far more.
MistakeIf controls are in place, residual risk is zero.
InsteadResidual risk always remains; owners must understand and accept it explicitly.
MistakeTesting a website for flaws is fine if you mean well.
InsteadUnauthorized access is illegal in Canada and the US; get written permission or use a disclosure program.
MistakePublishing a vulnerability immediately is the most responsible choice.
InsteadCoordinate disclosure: report privately and give the vendor reasonable time to fix it.
MistakeSecurity careers are only about hacking.
InsteadMost roles build, operate and govern secure systems; strong fundamentals matter most.
Summary and key terms
- Threat modelling starts with a data flow diagram and trust boundaries, then applies STRIDE to each element.
- Score threats before and after controls; residual risk is a decision for system owners.
- Map controls to threats and verify them with automated checks in the build pipeline.
- Independent testing, privacy impact assessments and incident response plans complete a secure release.
- Unauthorized access is a crime in both countries; testing needs written authorization.
- Coordinated vulnerability disclosure, disclosure policies and security.txt protect users and researchers.
- Ethical codes and strong technical fundamentals underpin a career in security.
- Data flow diagram
- A diagram of processes, stores, entities and data flows used in threat modelling.
- Trust boundary
- A line where data passes between zones of different trust.
- STRIDE
- Spoofing, tampering, repudiation, information disclosure, denial of service, elevation of privilege.
- Residual risk
- The risk that remains after controls are applied.
- Security checklist
- A list of required controls, ideally verified automatically before release.
- Penetration test
- An authorized assessment that tries to find exploitable weaknesses.
- Coordinated vulnerability disclosure
- Reporting vulnerabilities privately and publishing after a fix or deadline.
- security.txt
- A standard file (RFC 9116) telling researchers how to report vulnerabilities.
- CVE
- Common Vulnerabilities and Exposures: unique identifiers for published vulnerabilities.
- Bug bounty
- A program that rewards researchers for valid vulnerability reports.
Practice problems
Work each problem on paper first, then reveal the answer to check.
What does a trust boundary mark in a data flow diagram?
Show answer
Where data crosses between zones of different trust, a place where controls belong.
Which two threats scored highest in the Larch Clinic model?
Show answer
Credential stuffing and patients reading others' bookings by id.
Why do controls usually reduce likelihood rather than impact?
Show answer
They make an attack harder, but if it still succeeds the consequences are similar.
Which checklist item blocked the release, and how is it fixed?
Show answer
Admin access was not restricted; place the portal behind a bastion or identity-aware proxy.
Name two things a written penetration-test authorization must include.
Show answer
Any two of scope, exclusions, timing, permitted methods, data handling, contacts or signatures.
Which Canadian Criminal Code section covers unauthorized use of a computer?
Show answer
Section 342.1.
What did the US Department of Justice announce in May 2022?
Show answer
That it would not charge good-faith security research under the CFAA.
What is a common default deadline in coordinated disclosure?
Show answer
90 days.
What does a security.txt file contain?
Show answer
Contact details and policy for reporting vulnerabilities.
Name three security career roles.
Show answer
Any three of application security engineer, SOC analyst, penetration tester, cryptography engineer, privacy engineer or architect.
Lesson quiz · 5 questions
Score 60% or more to complete this lesson.
Create a free account to save your progress, take quizzes and earn a certificate.