SyntaxStudy
Sign Up
Web Security Threat Modeling: Identifying and Prioritising Risks
Web Security Beginner 1 min read

Threat Modeling: Identifying and Prioritising Risks

Threat modeling is a structured process for identifying potential security threats to an application, understanding their impact, and deciding how to mitigate them. The most widely used methodology is STRIDE, developed at Microsoft, which categorises threats into six types: Spoofing identity, Tampering with data, Repudiation (denying actions), Information disclosure, Denial of service, and Elevation of privilege. A practical threat modeling session begins by drawing a data-flow diagram of the system — all components, data stores, external entities, and the trust boundaries between them. For each boundary crossing, the team asks which STRIDE categories apply and assigns a risk score using a framework like DREAD (Damage, Reproducibility, Exploitability, Affected users, Discoverability). High-risk items become security requirements or backlog tickets. Threat modeling is most effective when done early in the design phase and revisited whenever the architecture changes. It shifts security left, catching design flaws before they are baked into code. Tools like the Microsoft Threat Modeling Tool, OWASP Threat Dragon, and pytm can automate parts of the process and generate reports that feed directly into sprint planning.
Example
# threat_model.py — lightweight STRIDE checklist generator

from dataclasses import dataclass, field
from typing import List

STRIDE = {
    'S': 'Spoofing',
    'T': 'Tampering',
    'R': 'Repudiation',
    'I': 'Information Disclosure',
    'D': 'Denial of Service',
    'E': 'Elevation of Privilege',
}

@dataclass
class DataFlow:
    name: str
    source: str
    destination: str
    crosses_trust_boundary: bool
    threats: List[str] = field(default_factory=list)  # STRIDE codes

    def report(self) -> str:
        lines = [f"Data Flow: {self.name} ({self.source} -> {self.destination})"]
        if self.crosses_trust_boundary:
            lines.append("  [!] Crosses trust boundary — all STRIDE categories apply")
        for code in self.threats:
            lines.append(f"  Threat [{code}] {STRIDE[code]}")
        return '\n'.join(lines)

flows = [
    DataFlow('User Login',    'Browser',    'Auth Service', True,  ['S', 'T', 'I']),
    DataFlow('DB Query',      'App Server', 'Database',     True,  ['T', 'I', 'E']),
    DataFlow('Password Reset','Email',      'Browser',      False, ['S', 'R']),
]

for flow in flows:
    print(flow.report())
    print()