← DevSecOps← DevSecOps
DevSecOpsDevSecOps19 Th7, 2026Jul 19, 202629 phút đọc22 min read

Threat Modeling & Đánh giá rủi roThreat Modeling & Risk Assessment

Thuộc bộ kiến thức DevSecOps Roadmap.

Tổng quan

Threat modeling là hoạt động “suy nghĩ như một kẻ tấn công” trước khi kẻ tấn công thật sự làm điều đó — xác định một cách có hệ thống điều gì có thể sai (what can go wrong), mức độ nghiêm trọng của nó, và cần làm gì để xử lý. Đây là một trong những hoạt động bảo mật có đòn bẩy (leverage) cao nhất trong SDLC vì nó diễn ra trên giấy (hoặc bảng trắng, hoặc công cụ vẽ diagram) — trước khi một dòng code nào được viết hay một đồng nào bị tiêu tốn để xây “đúng nhưng sai kiến trúc”.

Đánh giá rủi ro (risk assessment) là kỷ luật đi kèm: biến danh sách threat thành các quyết định ưu tiên, có thể hành động — rủi ro nào cần fix ngay, rủi ro nào chấp nhận (accept), rủi ro nào chuyển giao (transfer — bảo hiểm, hợp đồng), và rủi ro nào chỉ cần theo dõi.

Tại sao làm sớm (shift-left)

Bốn câu hỏi

Framework của Adam Shostack (được dùng trong Microsoft SDL và áp dụng rộng rãi) rút gọn threat modeling về bốn câu hỏi, lý tưởng nhất là hỏi lặp lại như một vòng lặp:

#Câu hỏiHoạt động
1Chúng ta đang xây dựng cái gì?Vẽ kiến trúc / data flow diagram (DFD), xác định component, trust boundary, data store, external entity.
2Điều gì có thể sai (what can go wrong)?Áp dụng một framework (STRIDE, attacker persona, kill chain) để liệt kê threat theo từng component/boundary.
3Chúng ta sẽ làm gì với nó?Quyết định mitigation: fix ở thiết kế, fix ở code, thêm control, chấp nhận rủi ro (accept), hoặc chuyển giao (transfer).
4Chúng ta đã làm tốt chưa?Retrospective — kiểm tra lại threat model so với thực tế, xác nhận mitigation đã thực sự triển khai, chạy lại khi hệ thống thay đổi.

Câu hỏi số 4 là câu hay bị bỏ qua nhất nhưng lại quan trọng nhất để biến threat modeling thành một quy trình sống thay vì một ô checkbox tuân thủ.

Kiến thức nền tảng

Từ vựng cốt lõi

Thuật ngữĐịnh nghĩa
AssetBất cứ thứ gì có giá trị cần bảo vệ: dữ liệu, credential, tính khả dụng (availability), uy tín, sở hữu trí tuệ.
ThreatMột sự kiện hoặc hành động tiềm ẩn của attacker có thể gây hại cho asset (ví dụ: “kẻ tấn công giả mạo JWT để mạo danh một user”).
VulnerabilityĐiểm yếu mà một threat có thể khai thác (ví dụ: thiếu xác minh chữ ký trên JWT).
Attack vector / entry pointĐường mà attacker dùng để tương tác với hệ thống (API endpoint, form upload, cổng mạng).
Attack surfaceToàn bộ tập hợp entry point và vector mà attacker có thể dùng — càng nhỏ càng ít thứ phải phòng thủ.
Trust boundaryĐiểm trong hệ thống nơi dữ liệu hoặc quyền kiểm soát đi qua giữa các component có mức độ tin cậy khác nhau (ví dụ: internet → API gateway, user → admin).
RiskSự kết hợp giữa likelihood (khả năng xảy ra) và impact (tác động) của một threat khi nó thành hiện thực — thứ bạn thực sự ưu tiên và hành động.
Mitigation / controlBiện pháp bảo vệ làm giảm likelihood hoặc impact (authentication, input validation, rate limiting, encryption).
Residual riskPhần rủi ro còn lại sau khi áp dụng mitigation — không bao giờ bằng 0, phải được ai đó có trách nhiệm chấp nhận rõ ràng.

Attack surface mapping

Trước khi hỏi “điều gì có thể sai”, bạn cần một bức tranh chính xác về hệ thống. Attack surface mapping nghĩa là liệt kê:

Data Flow Diagram (DFD) là ký hiệu chuẩn cho việc này. Một DFD có bốn loại phần tử:

Ký hiệuPhần tửÝ nghĩa
Hình tròn / chữ nhật bo gócProcessComponent biến đổi dữ liệu (một service, một function, một microservice).
Hình chữ nhậtExternal entityThứ nằm ngoài tầm kiểm soát của bạn tương tác với hệ thống (một user, một API bên thứ ba).
Hai đường thẳng song songData storeNơi dữ liệu được lưu trữ (database, cache, file system, queue).
Mũi tênData flowSự di chuyển dữ liệu giữa các phần tử.
Đường nét đứtTrust boundaryĐiểm giao cắt nơi mức độ quyền/tin cậy thay đổi.

Kỷ luật vẽ DFD — dù chỉ là phác thảo không chính thức — thường là nơi mang lại giá trị thực sự của threat modeling: team phát hiện các component họ quên mất là tồn tại, các data flow không ai từng document, và trust boundary không ai từng đồng ý là boundary.

Khái niệm chính

STRIDE

STRIDE là mnemonic của Microsoft cho sáu loại threat, mỗi loại ánh xạ tới một thuộc tính bảo mật bị vi phạm. Áp dụng nó cho từng phần tử của DFD (mỗi process, data store, data flow, và external entity), và hỏi “điều này có thể xảy ra ở đây không?”

LoạiVi phạmĐịnh nghĩaVí dụ
S — SpoofingAuthenticationGiả mạo là một thứ/người khác không phải mình.Attacker giả mạo session cookie để đăng nhập như một user khác; một service mạo danh một microservice khác bằng API key bị đánh cắp.
T — TamperingIntegritySửa đổi dữ liệu hoặc code mà không có quyền.Sửa tham số giá trong một request client-side không ký trước khi nó đến checkout API; thay đổi payload của JWT khi chữ ký không được xác minh.
R — RepudiationNon-repudiationChối bỏ đã thực hiện một hành động, không có cách nào chứng minh ngược lại.Một user xóa dữ liệu của user khác và hệ thống không có audit log gắn hành động với một identity.
I — Information DisclosureConfidentialityĐể lộ thông tin cho người không có quyền xem.API trả về toàn bộ user object (bao gồm password hash hoặc internal ID) trong khi chỉ cần display name; thông báo lỗi quá chi tiết lộ stack trace.
D — Denial of ServiceAvailabilityLàm giảm hoặc từ chối dịch vụ với người dùng hợp lệ.Một endpoint không xác thực chấp nhận upload file lớn không giới hạn kích thước, làm cạn kiệt dung lượng đĩa; một regex dễ bị ReDoS trên input người dùng.
E — Elevation of PrivilegeAuthorizationĐạt được năng lực mà không có quyền phù hợp.Một user thường gọi trực tiếp API endpoint chỉ dành cho admin vì frontend ẩn nút bấm nhưng backend không kiểm tra role.

Cách chạy một buổi STRIDE trong thực tế:

  1. Vẽ hoặc import DFD.
  2. Với mỗi phần tử (process, data store, data flow, external entity), đi qua cả sáu chữ cái và hỏi “threat này có áp dụng ở đây không, và áp dụng như thế nào?”
  3. Không phải chữ cái nào cũng áp dụng cho mọi phần tử — ví dụ, một data store thuần túy khi ở trạng thái nghỉ (at rest) hiếm khi là mục tiêu Spoofing, nhưng rất có thể là mục tiêu Tampering và Information Disclosure.
  4. Ghi lại mỗi threat được xác định với: component, loại STRIDE, mô tả, và mức độ nghiêm trọng sơ bộ.
  5. Chuyển sang lập kế hoạch mitigation (xem phần “Chuyển threat thành backlog item” bên dưới).

Một quy tắc tắt phổ biến về mức độ liên quan STRIDE theo loại phần tử:

Loại phần tửMức độ liên quan STRIDE điển hình
External entityS, R (không thể tamper với thứ bạn không sở hữu, không thể DoS một con người, nhưng có thể spoof identity và repudiate hành động)
ProcessS, T, R, I, D, E (cả sáu đều áp dụng)
Data storeT, I, D, R (nếu thiếu lịch sử thay đổi)
Data flowT, I, D

PASTA (Process for Attack Simulation and Threat Analysis)

PASTA là một phương pháp risk-centric, được dẫn dắt bởi góc nhìn attacker (khác với STRIDE vốn design-centric, dẫn dắt bởi developer). Nó nặng hơn và thường dùng cho ứng dụng giá trị cao, đánh giá rủi ro chính thức, hoặc khi threat modeling cần gắn trực tiếp với impact kinh doanh và báo cáo compliance. Nó có bảy giai đoạn:

Giai đoạnTênMục tiêu
1Định nghĩa mục tiêuXác định mục tiêu kinh doanh, yêu cầu compliance, và các asset quan trọng.
2Định nghĩa phạm vi kỹ thuậtLiệt kê môi trường kỹ thuật: hạ tầng, dependency ứng dụng, thành phần phần mềm.
3Phân rã ứng dụng (application decomposition)Xây dựng DFD, xác định entry point, trust boundary và asset (nền tảng tương tự bước 1 của STRIDE).
4Phân tích threatPhân tích threat intelligence, động cơ attacker, và các mẫu tấn công đã biết liên quan đến bối cảnh kinh doanh.
5Phân tích vulnerability & weaknessĐối chiếu threat đã xác định với vulnerability thực tế (kết quả scan, phát hiện từ code review, CVE).
6Mô hình hóa / mô phỏng tấn côngMô hình hóa attack tree/attack chain thực tế cho thấy threat và vulnerability kết hợp thành đường tấn công khả thi ra sao.
7Phân tích rủi ro & impactĐịnh lượng rủi ro kinh doanh, gán residual risk, đề xuất biện pháp đối phó theo ưu tiên impact.

Giá trị của PASTA là nó gắn threat kỹ thuật với impact kinh doanh một cách rõ ràng ở mọi giai đoạn, giúp dễ dàng thuyết phục đầu tư với các bên liên quan không kỹ thuật. Cái giá phải trả là nó đòi hỏi nhiều thời gian, threat intelligence và sự tham gia liên chức năng hơn hẳn STRIDE.

STRIDE vs PASTA

Khía cạnhSTRIDEPASTA
ApproachDesign-centric, do developer dẫn dắtRisk-centric, do attacker/business dẫn dắt
Trọng tâm”Điều gì có thể sai trong thiết kế này” theo từng component”Kẻ tấn công thật sự sẽ làm gì, và impact kinh doanh là gì”
Xuất xứMicrosoft SDLVerSprite (2012, Tony UcedaVélez & Marco Morana)
Mức độ nỗ lựcNhẹ, nhanh, lặp lạiNặng, chính thức, nhiều giai đoạn
Phù hợp nhất choThreat modeling theo feature/sprint, workflow dev hằng ngàyỨng dụng giá trị cao, đánh giá theo quy định/compliance, báo cáo rủi ro cấp điều hành
Kết quảDanh sách threat theo từng phần tử DFD kèm mitigationMô phỏng tấn công, rủi ro kinh doanh được lượng hóa, roadmap biện pháp đối phó theo ưu tiên
Ai tham giaDeveloper, architect, security championSecurity team, risk/compliance, business stakeholder, threat intel
Khi nào dùngMỗi feature mới, API mới, hoặc thay đổi thiết kế đáng kểĐánh giá rủi ro hàng năm/theo major release, hệ thống rủi ro cao mới, audit

Các framework khác đáng biết (ngắn gọn): DREAD (Damage, Reproducibility, Exploitability, Affected users, Discoverability — một mô hình chấm điểm, thường đi kèm STRIDE, dù Microsoft đã ngừng dùng nội bộ vì bị đánh giá quá chủ quan), Attack Trees (phân rã dạng cây cho thấy một mục tiêu có thể đạt được bằng cách nào), LINDDUN (tương đương STRIDE nhưng tập trung vào privacy: Linkability, Identifiability, Non-repudiation, Detectability, Disclosure of information, Unawareness, Non-compliance), và ma trận MITRE ATT&CK (một cơ sở tri thức về tactic/technique của attacker thực tế, hữu ích để đưa kịch bản threat dựa trên hành vi đã quan sát thay vì lý thuyết).

Threat modeling trong SDLC

Giai đoạnHoạt động
Design / RFCThreat model đầy đủ cho service mới hoặc thay đổi kiến trúc lớn: DFD + STRIDE, được security review.
Sprint planning / theo featureThreat model “mini” nhẹ nhàng cho endpoint mới, data flow mới, tích hợp bên thứ ba mới — 15–30 phút, không phải workshop đầy đủ.
PR / code reviewChecklist threat modeling nhúng trong PR template cho các thay đổi nhạy cảm về bảo mật (auth, thanh toán, xử lý PII).
Trước khi releaseXác thực lại model so với những gì thực sự được xây dựng; xác nhận mitigation đã triển khai (câu hỏi 4: “chúng ta đã làm tốt chưa?”).
Sau incidentCập nhật threat model với đường tấn công mới được phát hiện — incident chính là threat mà bạn đã bỏ sót.
Xem lại định kỳXem lại model cho hệ thống hiện có theo chu kỳ (ví dụ hàng năm, hoặc khi dependency/kiến trúc thay đổi lớn) vì attack surface thay đổi khi code thay đổi.

Ai tham gia:

Giữ cho nó nhẹ nhàng và liên tục (chế độ thất bại lớn nhất trong thực tế là coi threat modeling là một workshop nặng nề duy nhất rồi không bao giờ xem lại):

Định lượng rủi ro (Risk quantification)

Một khi threat đã được liệt kê, bạn cần ưu tiên — không thể fix mọi thứ cùng lúc, và một số phát hiện không đáng để fix so với chi phí bỏ ra.

Likelihood × Impact là công thức nền tảng cho cả cách tiếp cận qualitative lẫn quantitative:

Risk = Likelihood × Impact

Ma trận rủi ro định tính (qualitative risk matrix) (nhanh, phổ biến trong các buổi kiểu STRIDE):

Impact ↓ / Likelihood →ThấpTrung bìnhCao
CaoTrung bìnhCaoNghiêm trọng (Critical)
Trung bìnhThấpTrung bìnhCao
ThấpThấpThấpTrung bình

Cách tiếp cận định lượng (quantitative) gán giá trị tiền tệ/số liệu, hữu ích khi cần thuyết phục đầu tư với finance/ban điều hành:

Các lựa chọn xử lý rủi ro (risk treatment) — một khi rủi ro đã được chấm điểm, cần quyết định:

Lựa chọnÝ nghĩa
Mitigate (giảm thiểu)Giảm likelihood hoặc impact bằng một control (mặc định cho mọi thứ vượt ngưỡng chấp nhận rủi ro của bạn).
Accept (chấp nhận)Chính thức ghi nhận và ký duyệt residual risk (phải có chủ sở hữu được đặt tên, chịu trách nhiệm — không phải im lặng).
Transfer (chuyển giao)Chuyển impact tài chính sang nơi khác (bảo hiểm mạng, điều khoản bồi thường hợp đồng với vendor).
Avoid (tránh)Loại bỏ rủi ro bằng cách gỡ bỏ hoàn toàn feature/component/dependency.

Risk register: artifact theo dõi tất cả những điều trên theo thời gian — thường là một bảng/spreadsheet hoặc một trường trong công cụ GRC với các cột như: ID, mô tả, asset, loại threat, likelihood, impact, điểm rủi ro, quyết định xử lý, chủ sở hữu, trạng thái, ngày đến hạn, ngày review gần nhất. Đây là hồ sơ sống mà auditor và lãnh đạo thực sự nhìn vào; một threat model không bao giờ được đưa vào risk register thường bị quên lãng.

OWASP Top 10 như một checklist threat modeling

OWASP Top 10 không thay thế cho threat modeling, nhưng là một checklist tuyệt vời để kiểm tra độ bao phủ (sanity-check) sau khi bạn đã liệt kê threat qua STRIDE/PASTA — đặc biệt với ứng dụng web, vì nó nắm bắt các lớp vulnerability bị khai thác phổ biến nhất trong thực tế:

Đối chiếu chéo: với mỗi threat STRIDE đã xác định, hỏi “threat này có ánh xạ tới một hạng mục OWASP Top 10 không, và nếu có, đã có mitigation chuẩn nào được biết đến chưa?” Việc bao phủ sâu ở mức code cho các hạng mục này (kèm mẫu secure-coding cụ thể) được trình bày trong Secure Coding & Bảo mật ứng dụng Web — note này chỉ dừng ở mức thiết kế/xác định threat.

Chuyển threat thành backlog item / yêu cầu bảo mật

Một threat model chỉ nằm trong tài liệu gần như vô giá trị. Mỗi threat được xác định nên trở thành một trong các dạng sau:

  1. Một yêu cầu bảo mật (security requirement) được viết trước/trong khi thiết kế (ví dụ: “mọi endpoint admin phải xác minh role ở server-side, không bao giờ tin tưởng việc ẩn UI ở client-side”).
  2. Một ticket backlog với mức độ nghiêm túc tương đương một bug chức năng: kịch bản tái hiện, mức độ nghiêm trọng, component bị ảnh hưởng, đề xuất fix, tiêu chí chấp nhận.
  3. Một bản ghi chấp nhận rủi ro rõ ràng trong risk register, có chủ sở hữu được đặt tên và ngày review, nếu chưa fix ngay.
  4. Một test case — lý tưởng là tự động (một unit/integration test bảo mật, một rule DAST, một policy-as-code check) để regression được phát hiện tự động về sau.

Một template ánh xạ đơn giản:

Threat IDLoại STRIDEComponentMô tảLikelihoodImpactRiskMitigationTicket backlogOwnerTrạng thái

Ví dụ thực hành: Feature “Đăng nhập + Upload File”

Mô tả hệ thống: Một feature web app nơi user đăng nhập bằng email/password, sau đó có thể upload ảnh đại diện (JPEG/PNG) được lưu trong object storage và trả về qua CDN URL.

Bước 1 — Chúng ta đang xây dựng cái gì? (Mini DFD)

[User Browser] --(1: credentials)--> [Auth API] --(2: query)--> [User DB]
                                          |
                                (3: session/JWT)
                                          |
                                          v
[User Browser] --(4: file upload)--> [Upload API] --(5: store)--> [Object Storage]
                                          |
                                (6: metadata)
                                          v
                                     [Metadata DB]

[User Browser] <--(7: served via CDN)-- [CDN] <--(8: fetch)-- [Object Storage]

Trust boundary: (a) internet ↔ Auth API, (b) internet ↔ Upload API, (c) Upload API ↔ Object Storage, (d) CDN ↔ internet (public read).

Bước 2 — Điều gì có thể sai? (STRIDE theo từng phần tử)

#Phần tửSTRIDEThreatMức độ nghiêm trọng
1Auth APISpoofingCredential stuffing / brute-force đăng nhập bằng danh sách password bị rò rỉ.Cao
2Auth API → JWTTamperingChữ ký JWT không được xác minh ở server-side; attacker sửa claim role thành admin.Nghiêm trọng
3Auth APIInformation DisclosureThông báo lỗi đăng nhập tiết lộ email có tồn tại hay không (“không tìm thấy user” vs “sai password”), cho phép account enumeration.Trung bình
4Auth APIRepudiationKhông có audit log cho lần đăng nhập thành công/thất bại, IP, hay timestamp — không thể điều tra account takeover về sau.Trung bình
5Upload APITamperingKhông validate loại file ngoài việc kiểm tra extension ở client-side — attacker upload file .php/.svg chứa script ngụy trang thành .jpg.Nghiêm trọng
6Upload APIDenial of ServiceKhông giới hạn kích thước file hay rate limit — attacker upload file cực lớn liên tục, làm cạn kiệt storage/bandwidth.Cao
7Upload APIElevation of PrivilegeEndpoint upload không xác minh user đã xác thực có sở hữu profile đang được cập nhật — user A ghi đè ảnh của user B qua ID trong request body (IDOR).Cao
8Object StorageInformation DisclosureBucket/container storage bị cấu hình sai thành công khai có thể liệt kê (publicly listable), để lộ toàn bộ file của mọi user kể cả tài liệu nhạy cảm lỡ upload nhầm.Nghiêm trọng
9CDN / Object storageTamperingFile upload được phục vụ với content-type gốc, browser thực thi file HTML/SVG upload như active content (stored XSS qua file upload).Cao
10Metadata DBInformation DisclosureMetadata API trả về đường dẫn/key storage nội bộ trong response, hỗ trợ các cuộc tấn công tiếp theo.Thấp

Bước 3 — Chúng ta sẽ làm gì với nó? (Mitigation)

Threat #Mitigation
1Rate-limit số lần đăng nhập, thêm account lockout/backoff, bắt buộc MFA cho tài khoản nhạy cảm, kiểm tra password với cơ sở dữ liệu breach (ví dụ Have I Been Pwned API) khi đăng ký/đổi password.
2Luôn xác minh chữ ký JWT ở server-side bằng thư viện đáng tin cậy; không bao giờ tin claim khi chưa xác minh; token thời hạn ngắn + refresh flow.
3Dùng thông báo chung chung “email hoặc password không hợp lệ” cho mọi trường hợp đăng nhập thất bại.
4Log các sự kiện authentication (thành công/thất bại, IP, user agent, timestamp) vào kho log tập trung, chống giả mạo (xem Monitoring & Logging).
5Validate loại file dựa trên nội dung (magic-byte/MIME sniffing), không dựa trên extension; re-encode ảnh ở server-side (loại bỏ payload nhúng); duy trì allowlist các loại file được chấp nhận.
6Bắt buộc giới hạn kích thước file tối đa ở server-side; rate-limit upload theo user/IP; dùng pre-signed URL với thời hạn ngắn và ràng buộc kích thước cho upload trực tiếp tới storage.
7Xác định user đích từ session/token đã xác thực, không bao giờ từ ID do client cung cấp; thêm kiểm tra authorization ở server-side.
8Đặt bucket storage mặc định là private; chỉ phục vụ qua signed CDN URL; bật chặn liệt kê bucket và access logging; liên tục scan cấu hình bucket (xem Bảo mật Cloud).
9Bắt buộc Content-Disposition: attachment hoặc phục vụ từ domain riêng không cookie; thiết lập Content-Type chính xác, hạn chế; không cho phép upload SVG/HTML hoặc sanitize chúng; thêm header CSP.
10Chỉ trả về URL công khai trong API response; không bao giờ để lộ key/đường dẫn storage nội bộ.

Bước 4 — Chúng ta đã làm tốt chưa?

Best Practices

Tài liệu tham khảo


Liên quan: Secure Coding & Bảo mật ứng dụng Web · Compliance, Governance & Quản lý rủi ro

Part of the DevSecOps Roadmap knowledge base.

Overview

Threat modeling is the practice of thinking like an attacker before an attacker does — systematically identifying what could go wrong in a system, how bad it would be, and what to do about it. It is one of the highest-leverage security activities in the SDLC because it happens on paper (or a whiteboard, or a diagram tool), before a single line of code is written or a single dollar is spent building the wrong thing securely.

Risk assessment is the companion discipline: turning a list of threats into a prioritized, actionable set of decisions — which risks to fix now, which to accept, which to transfer (insurance, contracts), and which to monitor.

Why do it early (shift-left)

The four questions

Adam Shostack’s framework (used by Microsoft’s SDL and widely adopted) reduces threat modeling to four questions, ideally asked as a repeatable loop:

#QuestionActivity
1What are we building?Draw the architecture / data flow diagram (DFD), identify components, trust boundaries, data stores, external entities.
2What can go wrong?Apply a framework (STRIDE, attacker personas, kill chains) to enumerate threats per component/boundary.
3What are we going to do about it?Decide mitigations: fix in design, fix in code, add a control, accept the risk, transfer it.
4Did we do a good job?Retrospective — validate the model against reality, check mitigations actually shipped, re-run when the system changes.

Question 4 is the most frequently skipped and the most important for making threat modeling a living process rather than a compliance checkbox.

Fundamentals

Core vocabulary

TermDefinition
AssetAnything of value worth protecting: data, credentials, availability, reputation, intellectual property.
ThreatA potential event or actor action that could cause harm to an asset (e.g., “an attacker spoofs a JWT to impersonate a user”).
VulnerabilityA weakness that a threat can exploit (e.g., missing signature verification on the JWT).
Attack vector / entry pointThe path an attacker uses to interact with the system (API endpoint, upload form, network port).
Attack surfaceThe complete set of entry points and vectors an attacker could use — the smaller it is, the less there is to defend.
Trust boundaryA point in the system where data or control crosses between components with different levels of trust (e.g., internet → API gateway, user → admin).
RiskThe combination of likelihood and impact of a threat being realized — what you actually prioritize and act on.
Mitigation / controlA safeguard that reduces likelihood or impact (authentication, input validation, rate limiting, encryption).
Residual riskWhat remains after mitigations are applied — never zero, must be explicitly accepted by someone accountable.

Attack surface mapping

Before you can ask “what can go wrong,” you need an accurate picture of the system. Attack surface mapping means enumerating:

Data Flow Diagrams (DFDs) are the standard notation for this. A DFD has four element types:

SymbolElementMeaning
Circle / rounded rectProcessA component that transforms data (a service, a function, a microservice).
RectangleExternal entitySomething outside your control that interacts with the system (a user, a third-party API).
Two parallel linesData storeWhere data is persisted (database, cache, file system, queue).
ArrowData flowMovement of data between elements.
Dashed lineTrust boundaryA crossing point where privilege or trust level changes.

The discipline of drawing the DFD — even informally — is often where the real value of threat modeling comes from: teams discover components they forgot existed, data flows nobody documented, and trust boundaries nobody agreed were boundaries.

Key Concepts

STRIDE

STRIDE is Microsoft’s mnemonic for six threat categories, each mapped to the security property it violates. Apply it per element of the DFD (each process, data store, data flow, and external entity), asking “could this happen here?”

CategoryViolatesDefinitionExample
S — SpoofingAuthenticationPretending to be something/someone you’re not.An attacker forges a session cookie to log in as another user; a service impersonates another microservice using a stolen API key.
T — TamperingIntegrityModifying data or code without authorization.Modifying a price parameter in an unsigned client-side request before it hits the checkout API; altering a JWT payload when the signature isn’t verified.
R — RepudiationNon-repudiationDenying having performed an action, with no way to prove otherwise.A user deletes another user’s records and the system has no audit log tying the action to an identity.
I — Information DisclosureConfidentialityExposing information to someone not authorized to see it.An API returns full user objects (including password hashes or internal IDs) when only a display name was needed; verbose error messages leak stack traces.
D — Denial of ServiceAvailabilityDegrading or denying service to legitimate users.An unauthenticated endpoint accepts large file uploads with no size limit, exhausting disk space; a regex vulnerable to ReDoS on user input.
E — Elevation of PrivilegeAuthorizationGaining capabilities without proper authorization.A regular user calls an admin-only API endpoint directly because the frontend hides the button but the backend doesn’t check the role.

How to run a STRIDE session in practice:

  1. Draw or import the DFD.
  2. For each element (process, data store, data flow, external entity), go through all six letters and ask “does this threat apply here, and how?”
  3. Not every letter applies to every element — e.g., a pure data store at rest is rarely a Spoofing target, but is very much a Tampering and Information Disclosure target.
  4. Record each identified threat with: component, STRIDE category, description, and a rough severity.
  5. Move to mitigation planning (Key Concepts → Turning threats into backlog items).

A common shortcut for element-type applicability:

Element typeTypical STRIDE relevance
External entityS, R (can’t tamper with something you don’t own, can’t DoS a person, but can spoof identity and repudiate actions)
ProcessS, T, R, I, D, E (all six apply)
Data storeT, I, D, R (if it lacks change history)
Data flowT, I, D

PASTA (Process for Attack Simulation and Threat Analysis)

PASTA is a risk-centric, attacker-driven methodology (in contrast to STRIDE’s design-centric, developer-driven approach). It is heavier-weight and typically used for high-value applications, formal risk assessments, or when threat modeling needs to be tied directly to business impact and compliance reporting. It has seven stages:

StageNameGoal
1Define objectivesIdentify business objectives, compliance requirements, and the assets that matter.
2Define technical scopeEnumerate the technical environment: infrastructure, application dependencies, software components.
3Application decompositionBuild DFDs, identify entry points, trust boundaries, and assets (similar groundwork to STRIDE’s step 1).
4Threat analysisAnalyze threat intelligence, attacker motivations, and known attack patterns relevant to the business context.
5Vulnerability & weakness analysisCorrelate identified threats against actual vulnerabilities (scan results, code review findings, CVEs).
6Attack modeling / simulationModel realistic attack trees / attack chains showing how threats and vulnerabilities combine into exploitable paths.
7Risk & impact analysisQuantify business risk, assign residual risk, and recommend countermeasures prioritized by impact.

PASTA’s value is that it explicitly ties technical threats back to business impact at every stage, which makes it easier to justify investment to non-technical stakeholders. Its cost is that it requires significantly more time, threat intelligence input, and cross-functional involvement than STRIDE.

STRIDE vs PASTA

AspectSTRIDEPASTA
ApproachDesign-centric, developer-drivenRisk-centric, attacker/business-driven
Focus”What can go wrong in this design” per component”What would a real attacker do, and what’s the business impact”
OriginMicrosoft SDLVerSprite (2012, Tony UcedaVélez & Marco Morana)
Effort/weightLightweight, fast, iterativeHeavyweight, formal, multi-stage
Best forPer-feature / per-sprint threat modeling, day-to-day dev workflowHigh-value applications, regulatory/compliance-driven assessments, executive risk reporting
OutputList of threats per DFD element with mitigationsAttack simulations, quantified business risk, prioritized countermeasure roadmap
Who’s involvedDevelopers, architects, security championSecurity team, risk/compliance, business stakeholders, threat intel
When to useEvery new feature, API, or significant design changeAnnual/major-release risk assessments, new high-risk systems, audits

Other frameworks worth knowing (briefly): DREAD (Damage, Reproducibility, Exploitability, Affected users, Discoverability — a scoring model, often paired with STRIDE, though Microsoft deprecated it internally for being too subjective), Attack Trees (hierarchical breakdown of how a goal could be achieved), LINDDUN (privacy-focused equivalent of STRIDE: Linkability, Identifiability, Non-repudiation, Detectability, Disclosure of information, Unawareness, Non-compliance), and the MITRE ATT&CK matrix (a knowledge base of real-world adversary tactics/techniques, useful for grounding threat scenarios in observed behavior rather than theory).

Threat modeling in the SDLC

PhaseActivity
Design / RFCFull threat model for new services or major architecture changes: DFD + STRIDE pass, reviewed by security.
Sprint planning / per-featureLightweight “mini” threat model for new endpoints, new data flows, new third-party integrations — 15–30 minutes, not a full workshop.
PR / code reviewThreat-modeling checklist embedded in PR templates for security-sensitive changes (auth, payments, PII handling).
Pre-releaseRe-validate the model against what was actually built; confirm mitigations shipped (question 4: “did we do a good job?”).
Post-incidentUpdate the threat model with the newly discovered attack path — incidents are threats you missed.
Periodic reviewRevisit models for existing systems on a cadence (e.g., annually, or on major dependency/architecture changes) since attack surface drifts as code changes.

Who’s involved:

Keeping it lightweight and continuous (the biggest practical failure mode is treating threat modeling as a single heavyweight workshop that never gets revisited):

Risk quantification

Once threats are enumerated, you need to prioritize — you cannot fix everything at once, and some findings aren’t worth fixing at all relative to their cost.

Likelihood × Impact is the base formula for both qualitative and quantitative approaches:

Risk = Likelihood × Impact

Qualitative risk matrix (fast, common in STRIDE-style sessions):

Impact ↓ / Likelihood →LowMediumHigh
HighMediumHighCritical
MediumLowMediumHigh
LowLowLowMedium

Quantitative approaches attach a monetary/numeric value, useful when justifying investment to finance/executives:

Risk treatment options — once a risk is scored, decide:

OptionMeaning
MitigateReduce likelihood or impact via a control (the default for anything above your risk-acceptance threshold).
AcceptFormally acknowledge and sign off on the residual risk (must be a named, accountable owner — not silence).
TransferShift the financial impact elsewhere (cyber insurance, contractual indemnification with a vendor).
AvoidEliminate the risk by removing the feature/component/dependency entirely.

Risk register: the artifact that tracks all of this over time — typically a table/spreadsheet or a field in a GRC tool with columns like: ID, description, asset, threat category, likelihood, impact, risk score, treatment decision, owner, status, due date, last reviewed date. This is the living record auditors and leadership actually look at; a threat model that never makes it into a risk register tends to be forgotten.

OWASP Top 10 as a threat-modeling checklist

The OWASP Top 10 is not a substitute for threat modeling, but it’s an excellent checklist to sanity-check coverage once you’ve enumerated threats via STRIDE/PASTA — especially for web applications, since it captures the most commonly exploited vulnerability classes in the wild:

Cross-check: for each STRIDE threat you identified, ask “does this map to an OWASP Top 10 category, and if so, is there a known standard mitigation?” Deep, code-level coverage of these categories (with concrete secure-coding patterns) is covered in Secure Coding & Web Application Security — this note stays at the design/threat-identification level.

Turning threats into backlog items / security requirements

A threat model that lives only in a document is close to worthless. Each identified threat should become one of:

  1. A security requirement written before/during design (e.g., “all admin endpoints must verify role server-side, never trust client-side UI hiding”).
  2. A backlog ticket with the same rigor as a functional bug: reproduction/scenario, severity, affected component, suggested fix, acceptance criteria.
  3. An explicit risk-acceptance record in the risk register, with a named owner and review date, if it won’t be fixed now.
  4. A test case — ideally an automated one (a security unit/integration test, a DAST rule, a policy-as-code check) so regression is caught automatically going forward.

A simple mapping template:

Threat IDSTRIDE CategoryComponentDescriptionLikelihoodImpactRiskMitigationBacklog ticketOwnerStatus

Worked Example: “User Login + File Upload” Feature

System description: A web app feature where a user logs in with email/password, then can upload a profile picture (JPEG/PNG) that’s stored in object storage and served back via a CDN URL.

Step 1 — What are we building? (Mini DFD)

[User Browser] --(1: credentials)--> [Auth API] --(2: query)--> [User DB]
                                          |
                                (3: session/JWT)
                                          |
                                          v
[User Browser] --(4: file upload)--> [Upload API] --(5: store)--> [Object Storage]
                                          |
                                (6: metadata)
                                          v
                                     [Metadata DB]

[User Browser] <--(7: served via CDN)-- [CDN] <--(8: fetch)-- [Object Storage]

Trust boundaries: (a) internet ↔ Auth API, (b) internet ↔ Upload API, (c) Upload API ↔ Object Storage, (d) CDN ↔ internet (public read).

Step 2 — What can go wrong? (STRIDE per element)

#ElementSTRIDEThreatSeverity
1Auth APISpoofingCredential stuffing / brute force login using leaked password lists.High
2Auth API → JWTTamperingJWT signature not verified server-side; attacker modifies role claim to admin.Critical
3Auth APIInformation DisclosureLogin error messages reveal whether an email exists (“user not found” vs “wrong password”), enabling account enumeration.Medium
4Auth APIRepudiationNo audit log of failed/successful login attempts, IP, or timestamp — can’t investigate account takeover later.Medium
5Upload APITamperingNo file-type validation beyond client-side extension check — attacker uploads a .php/.svg with embedded script disguised as .jpg.Critical
6Upload APIDenial of ServiceNo file size limit or rate limit — attacker uploads huge files repeatedly, exhausting storage/bandwidth.High
7Upload APIElevation of PrivilegeUpload endpoint doesn’t verify the authenticated user owns the profile being updated — user A overwrites user B’s picture via ID in the request body (IDOR).High
8Object StorageInformation DisclosureStorage bucket/container misconfigured as publicly listable, exposing all users’ uploaded files including any accidentally-uploaded sensitive documents.Critical
9CDN / Object storageTamperingUploaded file served with original content-type, browser executes an uploaded HTML/SVG file as active content (stored XSS via file upload).High
10Metadata DBInformation DisclosureMetadata API returns internal storage paths/keys in API responses, aiding further attacks.Low

Step 3 — What do we do about it? (Mitigations)

Threat #Mitigation
1Rate-limit login attempts, add account lockout/backoff, enforce MFA for sensitive accounts, check passwords against breach corpora (e.g., Have I Been Pwned API) at signup/change.
2Always verify JWT signature server-side with a vetted library; never trust claims without verification; short-lived tokens + refresh flow.
3Use a generic “invalid email or password” message for all login failures.
4Log authentication events (success/failure, IP, user agent, timestamp) to a tamper-evident, centralized log store (see Monitoring & Logging).
5Validate file type by content (magic-byte/MIME sniffing), not extension; re-encode images server-side (strips embedded payloads); maintain an allowlist of accepted types.
6Enforce max file size server-side; rate-limit uploads per user/IP; use pre-signed URLs with short expiry and size constraints for direct-to-storage uploads.
7Derive the target user from the authenticated session/token, never from a client-supplied ID; add authorization check server-side.
8Set storage bucket to private by default; serve only via signed CDN URLs; enable bucket-listing denial and access logging; scan bucket configuration continuously (see Cloud Security).
9Force Content-Disposition: attachment or serve from a separate cookieless domain; set correct, restrictive Content-Type; disallow SVG/HTML uploads or sanitize them; add CSP headers.
10Return only public-facing URLs in API responses; never leak internal storage keys/paths.

Step 4 — Did we do a good job?

Best Practices

References


Related: Secure Coding & Web Application Security · Compliance, Governance & Risk Management