SEN2008 · Week 13 · Software Security (I): Developing Secure Software, Secure design principles and patterns, Building security into the software development life cycle, Security in requirements

Secure software development: SDLC, design principles and threat modeling

You learn to build security into every phase of the life cycle instead of adding it to the code afterwards, the Saltzer-Schroeder design principles, threat modeling with STRIDE, and security requirements. The exam gives a scenario and asks 'which principle is violated'.

secure SDLCleast privilegedefense in depthfail-safe defaultscomplete mediationeconomy of mechanismopen designseparation of privilegeleast common mechanismpsychological acceptabilitythreat modelingSTRIDEtrust boundarydata flow diagramDREADmisuse casesecurity requirement

Most security holes are not “badly coded lines” but badly made decisions: nobody thought about authorization, what happens on error was never defined, the admin panel was left open to the Internet. This week you learn how to put security inside the software life cycle (SDLC). The typical exam question is this: a short scenario is given and you are asked “which principle is violated?” or “which STRIDE category?”. A DREAD or risk calculation may also appear.

Golden rules:

  1. Security is not a phase, it is every phase. It starts at requirements and doesn’t end at maintenance.
  2. The default answer is “no”. If you are not sure, deny access.
  3. Check every access. Checking once and forgetting is not enough.
  4. Find threats systematically. STRIDE makes you question letter by letter and catches what you wouldn’t think of.
  5. Rank risk by number. You can’t fix everything at once.

Secure SDLC (secure software development life cycle)

You get a secure SDLC by adding the security work to be done in each phase of the classic SDLC. Microsoft SDL, OWASP SAMM and BSIMM are different frameworks of this idea.

PhaseSecurity workOutput
Requirementssecurity requirements, misuse cases, compliance (GDPR, KVKK)a list of measurable requirements
Designthreat modeling, attack surface analysis, secure architectureDFD + threat list + mitigations
Implementationsecure coding standards, code review, SASTclean static analysis report
Verification (test)DAST, fuzzing, penetration testingfindings list, closed vulnerabilities
Releasefinal security review, incident response planapproval
Maintenancepatch management, monitoring, dependency trackingan up-to-date system

Why at the very start? Fixing a design flaw in the design phase is a diagram change. If the same flaw is found in a live system, code, data migration, customer notification and loss of reputation follow. The “cost of a late-found defect multiplies” curve in the literature is even steeper for security.

PITFALL · the “we’ll do a pentest at the end” approach. A penetration test shows the hole it finds, but fixing a design flaw afterwards is expensive. A pentest does not replace a secure SDLC, it is its final check.

Secure design principles (Saltzer & Schroeder)

The eight principles written by Saltzer and Schroeder in 1975 are still exam favorites today. We also add defense in depth, which is often included alongside them.

PrincipleIn one sentenceExample violation
Least privilegeEach component runs with just enough privilege to do its job.The web server runs as root.
Fail-safe defaultsThe default decision is to deny; permission is given explicitly.A catch that allows access on error.
Complete mediationEvery access to every object is checked.Authorization is checked only at login.
Economy of mechanismThe security mechanism should be simple and small.Your own 5000-line encryption code.
Open designSecurity does not rely on the secrecy of the design.“Nobody knows our algorithm, so it’s secure.”
Separation of privilegeA critical action requires more than one condition.A single admin can delete the production database alone.
Least common mechanismMechanisms shared among users are reduced.All tenants sharing the same temp directory.
Psychological acceptabilitySecurity must be usable, or it gets bypassed.A 20-character password that changes daily, notes stuck to screens.
Defense in depthSeveral layers independent of each other.Relying only on the firewall and using plaintext HTTP on the internal network.

Fail-safe defaults: how it looks in code

// BAD: allows everyone when the service crashes
boolean canRead(User u, File f) {
    try { return acl.allows(u, f, READ); }
    catch (Exception e) { return true; }
}

// GOOD: deny when uncertain, log the event
boolean canRead(User u, File f) {
    try { return acl.allows(u, f, READ); }
    catch (Exception e) {
        log.warn("ACL check failed, denying", e);
        return false;
    }
}

The same idea applies to firewall rules: a “deny all” rule comes at the end, and what is allowed is written one by one (allowlist).

Defense in depth and probability

With independent layers, the probabilities of the attacker getting through each one are multiplied. Example: if the probability of getting past the WAF is 0.3, getting past in-application validation is 0.2, and getting past the database privilege restriction is 0.1, the probability of getting through all of them is:

0.3×0.2×0.1=0.0060.3 \times 0.2 \times 0.1 = 0.006

Layers that look weak one by one are strong together. But note: if the layers share the same weakness (the same password, the same library), they are not independent, and the product is invalid.

TIP · how to find the principle. If the scenario has “too much privilege”, it is least privilege; “allow on error”, fail-safe; “checked once”, complete mediation; “secret algorithm”, open design; “one person is enough”, separation of privilege.

Threat modeling

Threat modeling looks for answers to four questions: What are we building? What can go wrong? What are we going to do about it? Did we do a good job?

Step 1: the data flow diagram (DFD)

You draw the system with four elements:

ElementMeaningExample
External entityan actor outside the systema user, a payment provider
Processcode that processes dataa web application, an API
Data storewhere data restsa database, a log file
Data flowmovement of data between theman HTTPS request, a SQL query

On top of these you draw trust boundary lines: between the Internet and the server, between the application and the database. Most threats appear in the flows that cross these boundaries, because one side should not trust the other’s data.

Step 2: STRIDE

You question each DFD element with six threat categories:

LetterThreatProperty brokenTypical mitigation
SSpoofing (identity forgery)Authenticationstrong authentication, MFA
TTamperingIntegrityMAC, signature, access control
RRepudiationNon-repudiationaudit log, digital signature
IInformation disclosureConfidentialityencryption, least privilege
DDenial of serviceAvailabilityrate limiting, resource quota
EElevation of privilegeAuthorizationauthorization checks, sandbox

Example: for the “User → Login API” flow, S: logging in with someone else’s password; T: the request is modified on the way; R: the user denies logging in; I: the error message says “this email is not registered” and leaks the existence of the user; D: thousands of login attempts per second; E: trusting the role=admin field in the request.

Step 3: rank the risks

There are two common methods.

Risk = likelihood × impact. Likelihood 0-1, impact 1-10:

ThreatLikelihoodImpactRisk
T1 spoofing0.281.6
T2 information disclosure0.563.0
T3 DoS0.732.1

Order: T2 > T3 > T1. T1, with the greatest impact, comes last, because its likelihood is low.

DREAD. Five categories are scored 0-10 and averaged: Damage, Reproducibility, Exploitability, Affected users, Discoverability.

ThreatDREADAverage
SQL injection in the login form9871088.4
Tampering with the log file654354.6
Verbose error messages398697.0

DREAD is subjective, so Microsoft has dropped it internally, but it still appears in textbooks and exams. CVSS is a more standard alternative.

Step 4: mitigation and verification

For each threat there are four options: mitigate, eliminate (remove the feature), transfer (insurance, a third party), accept (a documented decision). Then it is verified by testing that the mitigation really works.

Security requirements and misuse cases

A functional requirement says “what the system should do”. A security requirement says “what the system must not allow and how it must be protected”. A good security requirement is measurable and testable.

Bad (vague)Good (testable)
“The system must be secure.”“Passwords must be stored with bcrypt (cost ≥ 12).”
“Brute force must be prevented.”“The account must be locked for 15 minutes after 5 failed logins.”
“Data must be protected.”“All client-server traffic must be encrypted with TLS 1.2+.”

The way to find these requirements is to write misuse cases. In a normal use case the actor is “Customer” and the scenario is “Logs into their account”. In a misuse case the actor is “Attacker” (misactor) and the scenario is “Automatically tries a list of passwords”. A misuse case “threatens” the use case; a countermeasure “mitigates” the misuse case. Each misuse case yields a security requirement.

PITFALL · not writing a security requirement like a functional one. “Admins can delete users” is functional. The security side: “Only the admin role can delete, and every deletion is logged with who did it.” The second sentence is testable and closes the E and R threats.

Common mistakes

Wrong ideaCorrect
Threat modeling is done in the test phaseIt is done in design, then updated
Tampering → confidentialityIntegrity. What breaks confidentiality is Information disclosure
Repudiation → authenticationNon-repudiation; the countermeasure is logs and signatures
Allowing access on error is user-friendlyA fail-safe defaults violation; default deny
Checking once at login is enoughComplete mediation: check on every access
A secret algorithm is extra securityOpen design: only the key should be secret
Fix the highest-impact threat firstRisk = likelihood × impact; take likelihood into account too
“The system must be secure” is a requirementNot measurable; write a testable sentence
Layers always multiply probabilitiesOnly if independent; a shared weakness breaks the product

Test yourself

Exam-style questions. Solve them on paper first, then reveal the answer.

Question 1easy

A web server process runs as root even though it only needs to read files in /var/www and listen on one port. Which secure design principle is violated?

  1. Open design
  2. Least privilege
  3. Economy of mechanism
  4. Psychological acceptability
Show answer
B) Least privilege

The process has more privilege than the minimum it needs to do its job. The least privilege principle forbids exactly this. If the server is compromised, the attacker also gets root privileges. The right way: run it with a separate unprivileged user and give read-only permission.

Question 2easy

In the STRIDE model, a threat of type Tampering violates which security property?

  1. Confidentiality
  2. Availability
  3. Integrity
  4. Authentication
Show answer
C) Integrity

STRIDE maps each letter to a property. Tampering is modifying data or code without permission, and the property it breaks is integrity. Confidentiality corresponds to Information disclosure, availability to DoS, and authentication to Spoofing.

Question 3medium

A user transfers money and later claims 'I never made that transfer', and the system has no way to prove otherwise. Which STRIDE category is this, and which property is missing?

  1. Spoofing / authentication
  2. Repudiation / non-repudiation
  3. Tampering / integrity
  4. Elevation of privilege / authorization
Show answer
B) Repudiation / non-repudiation

The user denies an action they performed, and the system can't prove it. This is a repudiation threat. The missing property is non-repudiation. The fix: reliable, tamper-proof audit logs and, where needed, digital signatures.

Question 4easy

Security should not depend on keeping the design or the algorithm secret; only keys and passwords should be secret. Which principle is this?

  1. Open design
  2. Complete mediation
  3. Least common mechanism
  4. Fail-safe defaults
Show answer
A) Open design

Open design is the general form of Kerckhoffs's principle in cryptography. Relying on the design staying secret (security through obscurity) is weak, because code leaks and gets reverse engineered. Only the key should remain secret.

Question 5medium

A threat is scored with DREAD as Damage = 8, Reproducibility = 6, Exploitability = 7, Affected users = 9, Discoverability = 5. What is its DREAD risk score (simple average)?

Show answer
7.0

The DREAD score is the average of the five categories.(8+6+7+9+5)/5=35/5=7.0(8 + 6 + 7 + 9 + 5) / 5 = 35 / 5 = 7.0.
On a 0-10 scale, 7 counts as high, so this threat is prioritized.

Question 6medium

Threat T1 has likelihood 0.3 and impact 9. Threat T2 has likelihood 0.6 and impact 5. Using risk = likelihood × impact, which threat should be fixed first, and what are the two risk values?

Show answer
T2 (T1 = 2.7, T2 = 3.0)

R1=0.3×9=2.7R_1 = 0.3 \times 9 = 2.7, R2=0.6×5=3.0R_2 = 0.6 \times 5 = 3.0.
Although its impact is smaller, T2 is twice as likely, and its total risk is greater. Looking only at impact and choosing T1 is the typical mistake.

Question 7medium

Which secure design principle does the code below violate?

boolean canDelete(User u, Doc d) {
    try {
        return acl.check(u, d, "DELETE");
    } catch (Exception e) {
        return true;   // ACL service down, let it through
    }
}
  1. Least privilege
  2. Fail-safe defaults
  3. Open design
  4. Separation of privilege
Show answer
B) Fail-safe defaults

In case of an error the code allows access. According to the fail-safe defaults principle, the default decision must be "deny", and access should open only when explicitly allowed. That everyone can delete every document when the ACL service crashes is exactly a violation of this principle. The fix: return false; in the catch block and log the event.

Question 8hard

An application checks a user's permissions only once at login and caches the result for the whole session. An admin revokes the user's access, but the user keeps working for hours. Which principle is violated?

  1. Economy of mechanism
  2. Complete mediation
  3. Psychological acceptability
  4. Open design
Show answer
B) Complete mediation

Complete mediation: authority must be re-checked on every access to every object. Keeping the result in a cache and never looking again lets access continue even after the permission is revoked. If a cache is used, it must be short-lived and be invalidated when permissions change.

Question 9easy

In which SDLC phase is threat modeling most cost-effective to perform?

  1. Requirements and design
  2. Deployment
  3. Maintenance
  4. After a penetration test fails
Show answer
A) Requirements and design

Threat modeling is done while the architecture is taking shape. Fixing a design flaw in the design phase is a change to a drawing. If the same flaw is found after it goes live, it needs re-architecture, patches and incident response; the cost multiplies.

Question 10medium

How does a misuse case differ from a normal use case?

  1. It describes a feature the customer forgot to request
  2. It describes how an attacker (misactor) could abuse the system, and drives security requirements
  3. It is a use case with no actors
  4. It is a test case written after deployment
Show answer
B) It describes how an attacker (misactor) could abuse the system, and drives security requirements

A use case describes what the system should do. A misuse (abuse) case describes how a malicious actor could abuse the system. Each misuse case turns into a countermeasure, that is, a security requirement: e.g. "brute-force password guessing" → "the account is locked for 15 min after 5 failed attempts".

Question 11medium

Which STRIDE threat is mitigated mainly by authorization checks?

  1. Spoofing
  2. Information disclosure
  3. Denial of service
  4. Elevation of privilege
Show answer
D) Elevation of privilege

Elevation of privilege: a user being able to do something they are not permitted to do. Its counterpart is authorization. The counterpart of Spoofing is authentication, of Information disclosure confidentiality, and of DoS availability.

Question 12hard

A system has three independent defense layers. An attacker bypasses them with probabilities 0.1, 0.2 and 0.05 respectively. Assuming independence, what is the probability that the attacker gets through all three layers?

Show answer
0.001

The layers are independent and the attacker has to get through all of them, so the probabilities are multiplied:0.1×0.2×0.05=0.0010.1 \times 0.2 \times 0.05 = 0.001.
The probability that at least one layer holds is 1−0.001=0.9991 - 0.001 = 0.999. This is where the strength of defense in depth comes from. Pitfall: if the layers share the same weakness (e.g. the same password), the independence assumption collapses.

Verification: DREAD averages, risk = likelihood × impact products and layered defense probabilities were computed with node (verify/SEN2008/13.mjs). Conceptual answers were checked against the Saltzer-Schroeder (1975) principles and the Microsoft STRIDE definitions.

Review card

Secure SDLC: req (security requirement, misuse case) → design (threat model) → code (secure coding, review) → test (SAST/DAST/fuzz/pentest) → deploy/maintain (patching, monitoring) The later a flaw is found, the more expensive. Threat model in DESIGN. Saltzer-Schroeder: least privilege | fail-safe defaults (default DENY) | complete mediation (check on every access) economy of mechanism (keep it simple) | open design (don't trust a secret design) | separation of privilege (two keys) least common mechanism (reduce shared mechanisms) | psychological acceptability (make it usable) Defense in depth: independent layers, bypass probabilities are MULTIPLIED STRIDE → property: S→authentication T→integrity R→non-repudiation I→confidentiality D→availability E→authorization DFD: external entity, process, data store, data flow, TRUST BOUNDARY (threats are at boundary crossings) DREAD = (D+R+E+A+D)/5 Risk = likelihood × impact Misuse case → countermeasure → measurable security requirement Pitfall: "return true" in a catch = fail-safe violation; a single check at login = complete mediation violation