Threat Modeling and Attack Surface Analysis Questions
Systematically identifying how a system can be attacked and where its exposure lies. Covers structured methodologies (STRIDE, PASTA, DREAD, OCTAVE, attack trees), enumerating and reducing attack surface, mapping trust boundaries and data flows via DFDs, profiling likely threat actors, and prioritizing identified threats by likelihood and impact during design. Includes applying this methodology to specific architectural substrates (cloud-native and serverless, microservices, ML/AI systems, IoT, CI/CD pipelines, cryptographic subsystems) and operationalizing it as a recurring program (SDLC integration, governance, tooling, KPIs). The proactive 'think like an attacker before you build' discipline: distinct from live penetration testing (the adversarial validation of a built system), from runtime detection/monitoring (recognizing an attack already in progress), and from implementing the resulting security controls (a separate design-and-build discipline).
Given this simplified login flow: 1) User submits credentials over HTTPS; 2) Frontend posts to auth API; 3) Auth service validates credentials and issues JWT; 4) Client stores JWT in browser. Perform a STRIDE analysis: list threats for each step and propose at least one concrete mitigation per identified threat.
Sample Answer
Direct answer
STRIDE (Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege) works by walking each step of a flow and asking which of the six categories applies there. For this login flow the two highest-value steps are issuing the token (step 3) and storing it in the browser (step 4), because a failure there yields full account takeover, but all four steps need to be walked: skipping a step is the most common threat-modeling miss.
Structured elaboration
Step 1: user submits credentials over HTTPS
- Spoofing: the user is phished onto a look-alike domain and submits real credentials to an attacker-controlled site (our backend is never touched). Mitigation: move toward phishing-resistant authentication (WebAuthn/passkeys, which bind the credential to the origin so a look-alike domain simply cannot use it), plus DMARC/SPF and lookalike-domain monitoring.
- Information Disclosure: a Transport Layer Security (TLS) downgrade or misconfiguration lets an on-path attacker read the credentials in transit. Mitigation: enforce TLS 1.2+, turn on HTTP Strict Transport Security (HSTS) with preload, disable weak cipher suites, and redirect all plain HTTP to HTTPS at the edge so there is no window to strip encryption.
Step 2: frontend posts to the auth API
- Tampering: a malicious browser extension or injected script rewrites the request body before it leaves the browser. Mitigation: a strict Content-Security-Policy limiting script sources, Subresource Integrity on any third-party script, and no unnecessary third-party scripts on the login page.
- Denial of Service: scripted credential stuffing floods the endpoint. Mitigation: per-IP and per-account rate limiting, a challenge (CAPTCHA or proof-of-work) after repeated failures, and a web application firewall (WAF) in front of the API.
Step 3: auth service validates credentials and issues a JSON Web Token (JWT, a signed, self-contained token format)
- Elevation of Privilege: weak signature verification, such as accepting an unsigned token (
alg=none) or a symmetric secret an attacker can guess or brute-force, lets an attacker mint a token claiming to be any user. Mitigation: sign with an asymmetric algorithm (RS256/ES256), hard-code the accepted algorithm on the verifier side rather than trusting the token's own header, and manage signing keys through a key management service (KMS) or hardware security module (HSM) with rotation. - Information Disclosure: the credential store itself is breached and password material leaks. Mitigation: hash passwords with a slow, salted algorithm (bcrypt or argon2), encrypt the datastore at rest, and restrict database access to the minimum the auth service needs.
- Repudiation: there is no record of who authenticated, when, from where, so a disputed login cannot be reconstructed. Mitigation: an append-only authentication audit log (timestamp, source IP, outcome) shipped to a store the auth service itself cannot rewrite.
- Denial of Service: the deliberately slow password-hash comparison is itself a resource-exhaustion lever if an attacker can trigger many validations. Mitigation: rate-limit before the expensive comparison runs, autoscale the service, and add a circuit breaker that degrades gracefully under load rather than falling over.
Step 4: client stores the JWT in the browser
- Information Disclosure: if the token sits in
localStorageor a cookie without theHttpOnlyflag, any cross-site scripting (XSS) bug anywhere on the site can read it directly. Mitigation: store the token in anHttpOnly,Secure,SameSitecookie so page JavaScript cannot read it; if a bearer token is unavoidable for a single-page app, hold it only in memory (never in persistent storage) with a short lifetime. - Tampering / Elevation of Privilege: a copied token is a bearer credential, replayable as-is by whoever holds it. Mitigation: keep the access token short-lived (minutes), pair it with a separate,
HttpOnly, rotating refresh token, and bind the session to context (device or IP-range fingerprint) so a token reused from an unrelated context is flagged. - Repudiation: without session metadata it is unclear which client instance performed a given action. Mitigation: embed a session identifier tied to a server-side session record so any individual session can be revoked and its actions traced.
Cross-cutting: multi-factor authentication at step 1 shrinks the blast radius of a leaked password well before step 3 is reached, and a security information and event management (SIEM) system correlating the audit trails from steps 2 through 4 is what turns "we have logs" into "we noticed the attack while it was happening."
Worked example
Suppose the token is kept in localStorage, a common shortcut, and the application has one reflected XSS bug on a rarely-tested support page. The step 4 STRIDE entry above predicts this exact failure mode (Information Disclosure via script access to storage) independently of whether that specific XSS bug is ever found in code review. The durable fix is not "find and patch the XSS bug," because another one will eventually exist; it is removing the token from any storage that page JavaScript can reach. That is the concrete payoff of walking the flow step by step instead of relying on general code review alone: the mitigation holds even against a bug the team has not found yet.
Trade-offs and pitfalls
The most common mistake is stopping the analysis at step 3 because "the client isn't our code," which is exactly backward: the storage decision at step 4 is the single biggest lever for whether a leaked credential or a stray script tag turns into full account takeover. A second pitfall is trying to force all six STRIDE letters onto every step; some steps genuinely have four applicable categories (step 3), step 4 has three entries covering four categories, and steps 1 and 2 have two apiece, so padding the thin ones out to six produces a checklist nobody actually reads. Watch for mitigations that trade one threat for another rather than eliminating it: moving the token into an HttpOnly cookie closes the XSS-theft path but reopens Cross-Site Request Forgery (CSRF), which needs its own control (a CSRF token or SameSite=Strict, when the login UX tolerates it); a senior answer names that trade explicitly instead of presenting cookie storage as a strictly better fix with no cost.
As an Information Security Analyst, perform threat modeling for a cloud-native service running in Kubernetes. Identify the top five attack vectors specific to containers and orchestration (e.g., image supply chain, misconfigured RBAC), and recommend concrete mitigations you would implement both in CI/CD and at runtime.
Sample Answer
Direct answer
Threat modeling a cloud-native service running on Kubernetes (an open-source system for orchestrating containerized applications across a cluster of machines) means walking the whole lifecycle, not just the running cluster: what gets built and signed before deployment, what the cluster's own control plane and configuration allow once it's running, and what a workload can reach if it's compromised. The five attack vectors below cover that full lifecycle deliberately, because a threat model that only looks at runtime configuration misses the supply-chain and configuration threats that are usually cheaper for an attacker to exploit than anything at runtime.
Structured elaboration
The method: lifecycle-wide attack surface, not just the running cluster
Walk the service's full lifecycle in order rather than starting from the running cluster's configuration: what gets built (the image and its dependencies), what gets signed and verified before it ships, what the cluster's control plane and configuration allow once the workload is running, and what a compromised workload can reach from there (secrets, other workloads, the underlying host). For each stage, ask what a preventive control in continuous integration/continuous delivery (CI/CD, the automated pipeline that builds, tests, and ships code) would catch before deployment, and separately what a runtime control would catch or contain once the workload is live, since neither alone covers the full lifecycle. Applying that method to a concrete cloud-native service is the worked example below.
Worked example
Top five attack vectors, each with CI/CD and runtime mitigations
-
Image supply-chain compromise. A malicious or tampered container image reaches production, either through a compromised base image, a poisoned dependency, or a build pipeline that was itself compromised.
- In CI/CD: sign every image (a tool like Cosign is a common choice) and verify provenance before it's allowed to deploy; scan images for known vulnerabilities and block builds above an agreed severity threshold; enforce immutable, content-addressed tags rather than mutable tags like
latestthat can silently point to a different image over time. - At runtime: an admission controller (a component that intercepts and can reject requests to the cluster's API before they take effect, commonly implemented with Open Policy Agent Gatekeeper or a similar policy engine) enforces that only signed images from an approved registry can actually run.
- In CI/CD: sign every image (a tool like Cosign is a common choice) and verify provenance before it's allowed to deploy; scan images for known vulnerabilities and block builds above an agreed severity threshold; enforce immutable, content-addressed tags rather than mutable tags like
-
Misconfigured Role-Based Access Control (RBAC) and excessive privileges. A workload's service account, or a human operator's role binding, grants far more access than the workload actually needs, so a single compromised pod can act far beyond its intended scope.
- In CI/CD: static analysis of Kubernetes manifests catches overly broad role bindings before they merge; require least-privilege templates as the default rather than the exception, and specifically disallow binding a
ClusterRole(a cluster-wide permission set) to anything other than a small, explicitly reviewed set of administrative identities. - At runtime: keep each workload's service account bound to a narrowly scoped
Rolerather than aClusterRole, and setautomountServiceAccountToken: falseon pods that never call the Kubernetes API at all, so there is no token sitting in the pod to steal; monitor the cluster's audit logs for API calls that look anomalous for a given service account's normal behavior.
- In CI/CD: static analysis of Kubernetes manifests catches overly broad role bindings before they merge; require least-privilege templates as the default rather than the exception, and specifically disallow binding a
-
Secrets leakage. Credentials, API keys, or certificates end up somewhere they shouldn't: baked into an image layer, committed to a repository, or exposed in a pod's environment variables where any process in that pod (or a debugging tool with pod access) can read them.
- In CI/CD: secret-scanning on every commit blocks plaintext credentials from ever merging; secrets are injected at deploy time from a dedicated secrets manager rather than baked into the image or hardcoded in a manifest.
- At runtime: mount secrets through a Container Storage Interface (CSI) secrets driver rather than plain Kubernetes Secrets objects where stronger guarantees are needed, encrypt the cluster's underlying etcd datastore (the key-value store holding all of Kubernetes' cluster state, including Secrets objects, at rest), and rotate credentials on a defined schedule rather than leaving long-lived keys in place indefinitely.
-
Container escape and host compromise. A vulnerability in the container runtime, an overly permissive container configuration, or a kernel-level flaw lets a process inside a container break out and reach the underlying host or other containers on the same node.
- In CI/CD: build from minimal, hardened base images (a distroless image, containing only the application and its runtime dependencies with no shell or package manager, meaningfully shrinks what an attacker who does get code execution can do next) and explicitly drop unneeded Linux capabilities in the pod specification rather than accepting the runtime's defaults.
- At runtime: enforce the restricted Pod Security Standard through Pod Security Admission (the built-in admission controller that rejects pod specs requesting privileged mode, host namespaces, or host path mounts), run containers as a non-root user, apply a seccomp profile (restricting which system calls a container's processes can make) and a mandatory access control profile such as AppArmor, and instrument runtime behavioral monitoring (a tool like Falco is a common choice) to detect syscall patterns consistent with an escape attempt.
-
Lateral movement between workloads. Once any single workload is compromised, a flat cluster network lets the attacker reach every other service in the cluster with no additional barrier.
- In CI/CD: define default-deny network policy templates for every namespace as a baseline, so a new service starts with no implicit network access to anything else and has to explicitly declare what it needs to reach.
- At runtime: enforce Kubernetes NetworkPolicies (rules restricting which pods can communicate with which others) as the default-deny baseline described above, and consider mutual Transport Layer Security (mTLS) between services via a service mesh (Istio or Linkerd are common choices) for identity-based, encrypted service-to-service communication rather than relying on network location alone.
Monitoring and incident response, tying the vectors together
Centralizing logs and metrics from the cluster's control plane, the container runtime, and the admission controllers into one place is what makes the five vectors above actually detectable in practice rather than just theoretically covered: alert on image or policy violations caught by the admission controller, anomalous API or audit events, and privilege-escalation attempts. Maintain a specific playbook for each of the higher-severity scenarios (a compromised image reaching production, a leaked secret, a suspected cluster breach) rather than a single generic incident-response document, since the first containment step differs meaningfully between them.
Trade-offs and pitfalls
- CI/CD controls and runtime controls are complementary, not substitutes for each other. A build pipeline that blocks unsigned images is only as strong as the admission controller enforcing the same rule at deploy time; skipping either half leaves a real gap, since a determined attacker who can bypass the pipeline (a compromised CI credential, for example) faces no second check if the runtime side was never configured.
- Default-deny network policy is a real operational cost, not just a configuration flag. Every legitimate service-to-service dependency has to be explicitly declared, which means the policy has to be maintained as the architecture evolves; a stale, overly narrow policy breaks production traffic just as surely as a stale, overly broad one leaves an opening.
- Signing and provenance verification add friction to the build pipeline (key management, verification steps, occasional build failures from a misconfigured signature) that a team under deadline pressure will be tempted to bypass "just this once," which is exactly the moment the control is most needed.
- Common wrong turn: treating Kubernetes' own RBAC and network policy primitives as sufficient on their own without also addressing the supply-chain vectors (image signing, secret scanning) that get an attacker into the cluster in the first place; a cluster with excellent runtime hardening and no image provenance checking is still trusting whatever the build pipeline hands it.
Walk through a threat modeling exercise for a new cloud-native microservice that accepts file uploads and stores them in object storage. Use an explicit framework (e.g., STRIDE) to identify assets, actors, threats, attack paths, and mitigations. List the artifacts you'd produce (data flow diagram, threat list, prioritized mitigations) and one example detection control for a critical threat.
Sample Answer
Direct answer
A threat-modeling exercise for a cloud-native file-upload microservice produces three concrete artifacts: a data-flow diagram (DFD) that names every asset, actor, and trust boundary; a threat list built by walking each element of the DFD against STRIDE (Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege); and a prioritized mitigation list ranking those threats by realistic impact and likelihood. For this specific design, the highest-priority threat is Elevation of Privilege through the asynchronous processing worker, since a compromised file-processing step inherits whatever cloud permissions that worker's identity holds, and the concrete detection control below is built around exactly that threat.
Structured elaboration
Assets, actors, and the data-flow diagram. Assets: the uploaded file content itself, the object storage bucket it lands in, the metadata database recording upload and processing state, and the upload API's authentication tokens. Actors: the authenticated end user (legitimate uploader), an external attacker (unauthenticated, or holding a stolen or forged token), and two internal service identities, the upload API and the asynchronous processing worker, each of which holds its own cloud permissions.
flowchart LR
User[Authenticated End User]
Attacker[External Attacker]
subgraph Edge["Edge: public-facing"]
API[Upload API]
end
subgraph Internal["Internal: service network"]
Queue[[Processing Queue]]
Worker[Async Processing Worker]
MetaDB[(Metadata Database)]
end
subgraph Storage["Object Storage"]
Bucket[(Object Storage Bucket)]
end
User -->|upload request plus token| API
Attacker -.->|forged or stolen token| API
API -->|validated file| Bucket
API -->|enqueue job| Queue
Queue --> Worker
Worker -->|reads object| Bucket
Worker -->|writes result metadata| MetaDB
API -->|writes upload record| MetaDB
Threat list (STRIDE walked against the diagram above):
| STRIDE category | Threat | Where |
|---|---|---|
| Spoofing | Attacker uses a stolen or forged token to call the upload API as a legitimate user | Upload API edge boundary |
| Tampering | Uploaded object is modified after storage by an actor with broader-than-intended bucket write access | Object storage bucket |
| Repudiation | A user who uploaded malicious content denies doing so, with no verifiable record tying the upload to their authenticated session | Upload API to metadata database |
| Information Disclosure | Overly broad bucket policy, or an overly long-lived pre-signed URL, exposes stored files to unintended readers | Object storage bucket |
| Denial of Service | An attacker uploads very large files, many small files rapidly, or a decompression-bomb-style file that consumes excessive resources when the worker processes it | Upload API and processing worker |
| Elevation of Privilege | A malicious file exploits a vulnerability in the processing worker's file-handling logic (an image, document, or archive parser), and the worker's cloud identity has broader permissions than the processing task needs, letting the compromise reach other cloud resources | Async processing worker |
Attack path for the highest-priority threat. The Elevation of Privilege path runs: attacker uploads a crafted file that passes the upload API's basic validation (correct declared content type, acceptable size) but is actually built to exploit a parsing vulnerability in whatever library the worker uses to process it (image library, document parser, archive extractor); the worker picks the job off the queue, reads the object, and processing triggers the exploit; if the worker's cloud identity holds permissions beyond what processing strictly requires (for example, broad read/write across all buckets rather than just the one it processes, or permissions to call unrelated cloud application programming interfaces, APIs), the compromised worker process can pivot to reading or modifying data well outside the original upload's scope.
Prioritized mitigations, ranked by the combination of how likely the path is and how much damage it enables:
- Least-privilege identity for the processing worker (addresses Elevation of Privilege, ranked highest because it is the one threat here whose worst case is otherwise unbounded: every other entry on the list has a blast radius confined to one upload, one bucket, or one log record, while a compromised worker holding broad cloud permissions reaches resources that have nothing to do with file uploads at all. Ranking it first is not the same as it being sufficient, and it is worth saying which entries it does not touch: least-privilege scoping on the worker does nothing for Repudiation, nothing for Information Disclosure through an over-long pre-signed URL, and nothing for resource exhaustion, which is why items 2 through 5 are requirements rather than nice-to-haves): scope the worker's cloud identity to only the specific bucket paths and operations processing requires, with no broad cross-bucket or administrative permissions.
- Content validation beyond declared type (addresses Elevation of Privilege and Denial of Service): validate actual file content (magic-byte/content sniffing, not just the client-declared content type or file extension), enforce size limits before the file is fully accepted, and guard against decompression bombs by capping expanded size during any extraction step.
- Short-lived, narrowly scoped upload tokens and pre-signed URLs (addresses Spoofing and Information Disclosure): tokens tied to a specific authenticated session with a short expiry, and any pre-signed URLs generated for reading objects scoped to minutes, not days.
- Bucket policy least privilege plus encryption (addresses Information Disclosure and Tampering): default-deny bucket policy with explicit, narrow grants, and server-side encryption so a misconfigured policy is not the only line of defense.
- Signed, immutable audit logging of upload events (addresses Repudiation): record each upload tied to the authenticated identity and a content hash, in a log the uploading service itself cannot retroactively edit.
Worked example
One example detection control for the highest-priority threat, Elevation of Privilege via the processing worker: alert on any API call made by the processing worker's cloud identity that falls outside its expected, narrow allow-list, most importantly any call touching a bucket other than the one it is scoped to process, or any call to an unrelated service (identity and access management, compute control-plane APIs, and so on). Because the least-privilege mitigation above already constrains what the worker's identity is supposed to be able to do, any call outside that expected set is a strong, low-noise signal, not a fuzzy heuristic: a correctly-behaving worker should never generate one. Concretely, this means shipping the cloud provider's own API audit log (for example, an AWS-style CloudTrail equivalent) for the worker's service identity to a monitoring pipeline with a rule that fires the moment that identity's calls deviate from its documented allow-list, which catches exactly the pivot step in the attack path above (the compromised worker attempting to read or write outside its intended scope) even if the initial exploit itself was never directly observed.
Trade-offs and pitfalls
The most common mistake is validating only the client-declared content type or file extension and treating that as sufficient input validation; an attacker fully controls both of those fields, so real validation has to inspect actual file content. A second is scoping the worker's cloud identity broadly "to avoid permission issues later," which is precisely the choice that turns a contained parsing-library exploit into a cross-resource compromise; least-privilege scoping has real operational cost (more explicit configuration, more friction when the processing logic legitimately needs a new resource) but that cost is the point, since it forces each new permission to be a deliberate decision rather than a default. A third pitfall is treating the DFD, threat list, and mitigation list as one-time deliverables produced once at design time and never revisited; this pipeline's processing logic and dependencies will change, and a new library version or a new processing step reopens the STRIDE walk for at least the elements it touches, not the whole system from scratch, but not nothing either.
Given a Data Flow Diagram for a file-sharing service, explain your method to identify attack surfaces and derive attack paths. Describe how you would annotate the DFD with threat information, attach severity and likelihood, and escalate high-risk findings into prioritized remediation tickets with owner and SLA.
Sample Answer
Direct answer
Read the Data Flow Diagram (DFD) element by element, external entities, processes, data stores, and the data flows connecting them, and apply STRIDE at every element to produce a candidate threat list scoped to exactly what that element does, then chain the individually-scoped threats ACROSS the diagram to find attack paths (a sequence of elements an attacker can move through, not just an isolated per-element finding). Annotate each threat directly on the diagram or in a linked table with severity and likelihood, and route anything crossing a defined severity threshold into a remediation ticket with a named owner (the team that owns the specific element) and a service-level agreement (SLA) tied to that severity, so a high-risk finding has a defined clock running on it rather than sitting in a backlog indefinitely.
Structured elaboration
Deriving the DFD and identifying trust boundaries
Before threats can be attached, the DFD needs trust boundaries marked explicitly, the lines where data crosses from one level of trust to another (the public internet into the application, the application into an internal data store, a third-party integration crossing into the system). A threat is meaningfully more likely, and needs more scrutiny, at a boundary crossing than deep inside a single trusted zone, so marking boundaries first is what tells you where to concentrate analysis effort rather than spreading it evenly across the whole diagram.
For a file-sharing service, a representative DFD. The three boxes below are trust ZONES; the trust BOUNDARIES are the two lines between them (Zone 1 to Zone 2, where an untrusted caller crosses into internal services, and Zone 2 to Zone 3, where a service reaches a data store), since a boundary is the crossing itself, not the region on either side of it:
flowchart LR
User([User's browser])
Mobile([Mobile app])
Auth[Authentication service]
Upload[Upload processing service]
Share[Sharing/permissions service]
Files[(File storage)]
Meta[(Metadata database)]
Scan[Malware scanning service]
subgraph Zone1[Zone 1: public internet, untrusted]
User
Mobile
end
subgraph Zone2[Zone 2: internal services]
Auth
Upload
Share
Scan
end
subgraph Zone3[Zone 3: data stores]
Files
Meta
end
User -->|credentials| Auth
Mobile -->|credentials| Auth
User -->|file upload, token| Upload
Upload -->|scan request| Scan
Scan -->|verdict| Upload
Upload -->|store file| Files
Upload -->|store metadata, owner| Meta
User -->|share request| Share
Share -->|read/write permissions| Meta
Share -->|generate share link| Files
Method: applying STRIDE per element, then chaining across the diagram
- Per external entity (User's browser, Mobile app): primarily Spoofing (is the entity who it claims to be) and Repudiation (can the entity later deny an action) concerns, since external entities are outside the system's direct control.
- Per process (Authentication, Upload processing, Sharing/permissions, Malware scanning): all six STRIDE categories generally apply, since a process is where logic executes and can be manipulated (Tampering with a request, Denial-of-service against the process, Elevation of privilege if the process's own permissions are broader than its function needs).
- Per data store (File storage, Metadata database): primarily Tampering (unauthorized modification), Information disclosure (unauthorized read), and Denial of service (making the store unavailable or unusable), since a data store's core function is holding data, not executing arbitrary logic.
- Per data flow (the arrows): Tampering (altering data in transit), Information disclosure (an attacker reading data in transit), and Denial of service (flooding or severing the flow so the data never arrives), scoped to whether that specific flow crosses a trust boundary, since a flow entirely within one trust zone carries materially lower likelihood than one crossing from Boundary1 to Boundary2.
Chaining into attack paths is the step that goes beyond a flat per-element list: a per-element STRIDE pass on the Sharing/permissions service alone might flag "Elevation of privilege: a user could request another user's file's share link"; tracing that same concern ACROSS the diagram (does the Share process's over-broad access to the Metadata database, itself a separate per-element finding, mean this specific privilege-escalation attempt succeeds, versus being caught) turns two individually-moderate per-element findings into one higher-severity attack PATH: an authenticated but unauthorized user reaches another user's file by exploiting a permission-check gap in Share, which is only exploitable because Share's own database access is broader than its function needs.
Annotating the DFD with threat information
- Attach findings directly to the specific element or flow they concern, either as a linked table keyed to diagram element identifiers or, for a small diagram, as inline annotations, so the threat's location is unambiguous rather than living in a separate document disconnected from the diagram it references.
- Record the attack PATH, not just the element, for chained findings: a table row for a path-level finding lists the sequence of elements it traverses (Boundary1 crossing at User to Upload, then Upload's access to Files), not just a single element, so the finding is traceable back to exactly which trust-boundary crossings make it possible.
- Version the annotations alongside the diagram itself, since a DFD that changes (a new service added, a new data flow introduced) without a corresponding review of whether previously-closed findings still hold, or new ones are now possible, is exactly the model-drift problem a maintained threat model needs to avoid.
Attaching severity and likelihood
Score each finding, whether per-element or a chained path, on severity (the qualitative impact if realized, using a small ordinal scale such as Critical/High/Medium/Low rather than a fabricated numeric precision the analysis does not actually support) and likelihood (informed by whether the finding requires crossing a marked trust boundary, whether it requires an authenticated or unauthenticated attacker, and whether known similar issues have been seen in comparable systems). A chained attack path typically inherits at least the severity of its most severe constituent step, and often a HIGHER combined severity than any single step in isolation, since the path represents a fuller realized compromise (unauthorized cross-user file access) rather than any one step's narrower individual consequence (an over-broad database role, on its own, is a finding; chained with the permission-check gap, it becomes a specific realized privacy violation).
Escalating into prioritized remediation tickets
- A defined severity threshold routes a finding into a ticket automatically, rather than every finding becoming a ticket regardless of severity, which would drown the highest-priority items in noise; commonly, High and Critical findings ticket immediately, Medium findings batch into a periodic remediation backlog review, and Low findings are logged but not individually ticketed.
- Owner assignment follows the element(s) the finding concerns, using the same service-ownership mapping the rest of the threat-modeling program relies on; a chained path spanning multiple elements owned by different teams needs an explicit primary owner (typically the team owning the element where the actual FIX belongs, the permission-check gap in Share in the worked example below) plus the other involved teams as informed stakeholders, rather than the ticket sitting unowned because "it touches multiple teams."
- The SLA is tied to severity, not negotiated per finding: a fixed, pre-agreed remediation window per severity tier (illustrative example: Critical remediated or mitigated within days, High within roughly two weeks, Medium within a defined quarter-scale window) keeps the escalation objective and comparable across findings, rather than each finding's urgency being argued case by case after the fact.
Worked example
The chained attack path identified above, carried through to a concrete escalated ticket:
Attack path: an authenticated user (crossing Boundary1 to Boundary2 legitimately, via normal login) sends a share-link-generation request for a file they do not own, via the Share process. Share's permission check has a gap (it verifies the requester is authenticated, but not that they specifically own or have been granted access to the target file) before querying the Metadata database, which itself grants Share's service account read access to ALL files' metadata rather than being scoped per-request; the two gaps combine to let the attacker successfully generate a valid share link for another user's private file.
Severity: High (direct unauthorized access to another user's private data, a core confidentiality violation for a file-sharing product).
Likelihood: High (requires only a normal authenticated account, no special privilege or exploit chain beyond crafting the request itself, and the underlying permission-check gap is a straightforward logic omission rather than a hard-to-trigger edge case).
Ticket: "Sharing/permissions service does not verify file ownership before generating a share link, combined with overly broad database access enabling cross-user data exposure." Owner: the team owning the Sharing/permissions service (primary fix location: add the missing ownership check), with the team owning the Metadata database's access-control configuration listed as a secondary stakeholder (the broader database-scoping fix that reduces the blast radius of any FUTURE similar gap). SLA: High severity, remediate within the organization's defined High-severity window (illustrative: 14 days), tracked against that deadline the same way any other High-severity finding in the program is tracked.
Trade-offs and pitfalls
- Per-element STRIDE analysis alone, without the chaining step, systematically understates severity. The worked example's two individual findings (a missing ownership check, an over-broad database role) might each score Medium in isolation; only tracing them together across the diagram reveals the High-severity realized attack path, which is the specific value chaining adds over a flat element-by-element list.
- Annotating severity with fabricated numeric precision (a specific decimal score with no derivation behind it) is a common overreach; a qualitative Critical/High/Medium/Low scale, consistently applied and documented with its reasoning, is more honest and just as actionable as a spurious-looking number.
- A DFD that goes stale because nobody re-derives it after an architecture change is worse than not having one, since it creates false confidence that the attack-path analysis is current when it is analyzing a system that no longer matches reality; the annotation and versioning discipline above exists specifically to keep this from happening silently.
- SLA windows with no defined escalation for a MISSED deadline become advisory rather than enforced. A High-severity finding sitting past its 14-day SLA with no automatic escalation to a manager or a defined next step is functionally the same as having no SLA at all; the escalation mechanism, not just the existence of a deadline, is what makes the SLA real.
A vulnerability with CVSS v3.1 score 9.0 is found in a production billing API and the asset criticality is rated as high on your business impact scale. Describe a method to calculate a combined risk score that uses CVSS and business impact, show a numeric example calculation, and explain how this combined score should influence remediation prioritization and SLAs.
Sample Answer
Direct answer
A combined risk score should multiply neither in isolation: it should blend the Common Vulnerability Scoring System (CVSS) base score, which measures technical exploitability and severity in the abstract, with a separate business-impact factor that captures what this specific asset is worth to the organization. A vulnerability's CVSS score never changes based on where it lives, but its actual organizational risk does, so the combining formula is what lets a 9.0 mean something different on a billing API than on an internal test server. For this billing API (CVSS 9.0, business-impact criticality High), a defensible weighted blend lands the combined score at 8.4 out of 10, which maps to the organization's Critical remediation tier and a short, fixed service-level agreement (SLA) rather than the default queue.
Structured elaboration
Two independent axes. CVSS scores exploitability and technical severity (attack vector, complexity, privileges required, and the confidentiality/integrity/availability impact of the vulnerability itself), assuming nothing about which system it lives on. Business-impact criticality scores what happens to the organization if that asset is compromised, regardless of how easy the compromise was. Neither axis alone is sufficient: a CVSS 9.0 bug on an air-gapped internal tool is a different remediation priority than the same CVSS 9.0 bug on a production billing API that moves money and holds payment data.
A simple combining formula. Normalize both to a common 0-10 scale, then take a weighted average biased toward the technical score, since exploitability should dominate but business context should still meaningfully move the number:
CombinedScore=wcvss⋅CVSS+wbi⋅BI10
with wcvss=0.6, wbi=0.4 as an illustrative, organization-chosen weighting (there is no single industry-standard split; some organizations weight the two axes evenly, others let business impact act as a multiplier rather than an additive term), and business-impact criticality mapped onto the same 0-10 scale by ordinal position:
| Business-impact criticality | BI10 |
|---|---|
| Low | 2.5 |
| Medium | 5.0 |
| High | 7.5 |
| Critical | 10.0 |
Mapping the combined score to remediation tiers and SLAs, an illustrative but common pattern:
| Combined score | Tier | Remediation SLA |
|---|---|---|
| 8.0-10.0 | Critical | 7 calendar days |
| 6.0-7.9 | High | 30 days |
| 4.0-5.9 | Medium | 90 days |
| 0.0-3.9 | Low | next scheduled patch cycle |
This is deliberately a different scale from CVSS's own qualitative severity bands (None 0.0, Low 0.1-3.9, Medium 4.0-6.9, High 7.0-8.9, Critical 9.0-10.0): the combined score is an organizational prioritization signal built on top of CVSS, not a replacement for it, and the two should not be confused when reporting to auditors or partners who expect the raw CVSS number.
Worked example
Given values from the scenario: CVSS v3.1 base score = 9.0 (which sits in CVSS's own Critical severity band, 9.0-10.0), business-impact criticality = High.
BI10=7.5 (from the mapping table, High)
CombinedScore=0.6×9.0+0.4×7.5=5.4+3.0=8.4
8.4 falls in the 8.0-10.0 band, so this finding lands in the Critical remediation tier with a 7-calendar-day SLA, the same urgency tier as the raw CVSS score alone would have implied (CVSS 9.0 is already Critical on its own scale), which makes sense: a Critical technical vulnerability on a High-impact production billing API should not be softened by the blend.
The formula's real value shows up when the business-impact input changes while the vulnerability stays fixed. Holding CVSS at 9.0 and varying only the business-impact criticality:
| Business-impact criticality | Combined score | Tier | SLA |
|---|---|---|---|
| Low | 0.6(9.0) + 0.4(2.5) = 6.4 | High | 30 days |
| Medium | 0.6(9.0) + 0.4(5.0) = 7.4 | High | 30 days |
| High (this scenario) | 0.6(9.0) + 0.4(7.5) = 8.4 | Critical | 7 days |
| Critical | 0.6(9.0) + 0.4(10.0) = 9.4 | Critical | 7 days |
Even at the lowest business-impact input (Low), the same underlying CVSS 9.0 vulnerability still lands at 6.4, a High tier with a 30-day SLA, not a Low tier: the 0.6 weight on CVSS deliberately prevents a low-impact asset label from letting a technically Critical vulnerability drop out of active remediation entirely, while still meaningfully separating a 7-day response from a 30-day one depending on what the asset actually is.
Trade-offs and pitfalls
The most common mistake is letting business-impact scoring become subjective and inflated: if every asset owner rates their own system as "Critical" to get faster remediation attention, the business-impact axis stops discriminating and the combined score collapses back to a re-scaled CVSS. Business-impact criticality needs its own defined rubric (data classification handled, revenue dependency, regulatory exposure, blast radius if compromised) reviewed by someone other than the asset owner, the same way CVSS needs a consistent scorer to stay comparable across findings. A second pitfall is picking weights that let a low business-impact rating fully cancel a Critical CVSS score; a formula where a low-value asset can push a remotely exploitable, no-authentication-required Critical vulnerability all the way down to a Low tier is usually wrong, because "low impact today" often changes as the asset's role in the architecture evolves, and a forgotten Critical-severity hole is exactly the kind of thing that gets rediscovered by an attacker after the business context around it has quietly changed. Finally, do not present the combined score as if it were CVSS itself when talking to external parties (auditors, customers, disclosure coordination): report both numbers separately, since CVSS is a portable, vendor-agnostic measure and the combined score is internal prioritization logic that will not mean the same thing outside the organization.
Unlock Full Question Bank
Get access to all 20 Threat Modeling and Attack Surface Analysis interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.