AppSec 1 — Tư duy bảo mật ứng dụng & DevSecOps
AppSec 1 — Tư duy bảo mật ứng dụng & DevSecOps
Một ngân hàng không giống một startup bán áo phông. Nếu website bán áo bị hack, bạn mất vài đơn hàng và một buổi tối khó ngủ. Nếu hệ thống ngân hàng bị hack, bạn mất tiền của khách hàng, mất dữ liệu định danh của hàng triệu người, đối mặt với thanh tra của Ngân hàng Nhà nước, án phạt theo Nghị định 13/2023 về bảo vệ dữ liệu cá nhân, và — thứ khó phục hồi nhất — niềm tin. Đó là lý do bảo mật ứng dụng (Application Security, gọi tắt AppSec) không phải là một checkbox cuối dự án, mà là cách bạn tư duy từ dòng code đầu tiên.
Bài này mở đầu series Bảo mật ứng dụng & OWASP. Nó không dạy bạn một công cụ cụ thể mà xây cho bạn một bộ khung tư duy: cách kẻ tấn công nhìn hệ thống của bạn, cách bạn nhìn ngược lại để phòng thủ, và cách nhúng bảo mật vào quy trình phát triển thay vì chắp vá lúc cuối. Bối cảnh xuyên suốt series là bảo vệ các hệ thống dữ liệu và API ngân hàng — nơi mỗi endpoint là một cánh cửa, và mỗi cánh cửa đều có người đang thử mở.
AppSec là gì và vì sao ngân hàng phải quan tâm gấp bội
AppSec là tập hợp các thực hành nhằm tìm, sửa và ngăn ngừa lỗ hổng ở tầng ứng dụng — code bạn viết, API bạn expose, thư viện bạn import, cấu hình bạn deploy. Nó khác với bảo mật hạ tầng (tường lửa, mạng, endpoint) ở chỗ nó xử lý những lỗi mà firewall không nhìn thấy: một câu SQL ghép chuỗi sai cách, một token JWT không kiểm chữ ký, một API trả về dư trường dữ liệu.
Với ngân hàng, bốn yếu tố khiến AppSec trở nên sống còn:
- Dữ liệu cực nhạy cảm. Số CMND/CCCD, số tài khoản, số dư, lịch sử giao dịch, điểm tín dụng. Rò rỉ một bản ghi thôi cũng đủ để lừa đảo danh tính.
- Tiền thật, di chuyển được. Khác với dữ liệu tĩnh, một lỗ hổng logic ở luồng chuyển khoản có thể bị biến thành máy in tiền. Kẻ tấn công có động cơ tài chính trực tiếp.
- Ràng buộc tuân thủ nặng. PCI-DSS (nếu xử lý thẻ), ISO 27001, các quy định của NHNN, Nghị định 13/2023. Vi phạm không chỉ tốn tiền phạt mà có thể bị đình chỉ dịch vụ.
- Là mục tiêu chủ động. Ngân hàng không bị hack "tình cờ". Có những nhóm tấn công chuyên nghiệp, được đầu tư, kiên nhẫn quét bạn 24/7. Bạn phải phòng thủ đúng 100% lần; kẻ tấn công chỉ cần đúng 1 lần.
Một con số để cảm nhận quy mô: theo báo cáo ngành, chi phí trung bình cho một vụ rò rỉ dữ liệu trong lĩnh vực tài chính cao hơn đáng kể so với mặt bằng chung các ngành, chưa kể thiệt hại uy tín kéo dài nhiều năm. Trong bối cảnh đó, đầu tư vào AppSec luôn rẻ hơn nhiều lần so với dọn dẹp hậu quả.
Ba trụ cột kinh điển: CIA triad
Mọi mục tiêu bảo mật quy về ba tính chất, gọi là CIA triad. Đừng nhầm với cơ quan tình báo — đây là ba chữ cái nền tảng của toàn ngành.
| Tính chất | Nghĩa | Vi phạm nghĩa là gì | Ví dụ ngân hàng |
|---|---|---|---|
| Confidentiality (Bảo mật/Riêng tư) | Chỉ người được phép mới đọc được dữ liệu | Rò rỉ, lộ thông tin | API trả về số dư của khách hàng khác |
| Integrity (Toàn vẹn) | Dữ liệu không bị sửa đổi trái phép | Dữ liệu bị đổi lén | Số tiền chuyển khoản bị thay đổi giữa đường |
| Availability (Sẵn sàng) | Hệ thống luôn phục vụ được người dùng hợp lệ | Dịch vụ ngừng, DoS | Tấn công làm sập cổng thanh toán giờ cao điểm |
Ba tính chất này thường đánh đổi lẫn nhau. Mã hóa toàn bộ (tăng Confidentiality) có thể làm chậm hệ thống (giảm Availability). Ghi log chi tiết mọi giao dịch (phục vụ Integrity/điều tra) lại tạo thêm dữ liệu nhạy cảm cần bảo vệ (áp lực lên Confidentiality). Nghề bảo mật phần nhiều là nghệ thuật cân bằng các đánh đổi này theo đúng bối cảnh rủi ro.
AAA — bộ khung kiểm soát truy cập
CIA nói mục tiêu; AAA nói cơ chế để đạt được, đặc biệt là Confidentiality và Integrity:
- Authentication (xác thực) — "Bạn là ai?" Chứng minh danh tính: mật khẩu, OTP, sinh trắc học, chứng chỉ. Trả lời câu hỏi đúng người không.
- Authorization (phân quyền) — "Bạn được làm gì?" Sau khi biết bạn là ai, quyết định bạn được truy cập tài nguyên nào. Một giao dịch viên xác thực thành công vẫn không được xem lương của giám đốc.
- Accounting (ghi nhận/audit) — "Bạn đã làm gì?" Ghi lại mọi hành động để truy vết, điều tra, và chứng minh tuân thủ. Trong ngân hàng, audit log là bằng chứng pháp lý.
Nhầm lẫn kinh điển của lập trình viên: coi authentication là xong. Đăng nhập thành công không có nghĩa được phép làm mọi thứ. Phần lớn lỗ hổng nghiêm trọng nhất trong OWASP nằm ở tầng authorization — chúng ta sẽ mổ xẻ ở bài 4 về access control & crypto.
Tư duy tấn công: nghĩ như kẻ đột nhập
Đây là chuyển dịch tư duy quan trọng nhất mà một kỹ sư cần thực hiện. Lập trình viên được huấn luyện để trả lời câu hỏi: "Làm sao cho tính năng này chạy đúng khi người dùng dùng đúng?" Kẻ tấn công hỏi câu ngược lại: "Làm sao lạm dụng tính năng này khi tôi dùng nó sai cách một cách có chủ đích?"
Xét một ô nhập "số tiền chuyển khoản":
- Dev nghĩ: người dùng gõ
500000, hệ thống trừ tiền, xong. - Attacker nghĩ: gõ
-500000được không (chuyển âm để cộng tiền vào tài khoản mình)? Gõ500000.999999để lợi dụng làm tròn? Gõ số lớn hơn số dư nhưng gửi hai request đồng thời (race condition)? Bỏ trườngamountkhỏi request? Đổiaccount_idđích thành tài khoản người khác?
Attacker mindset không phải là đạo đức xấu — nó là thói quen luôn tự hỏi "chuyện gì xảy ra nếu đầu vào này là ác ý?". Nguyên tắc vàng: không bao giờ tin đầu vào từ client. Mọi thứ đến từ trình duyệt, app mobile, hay một service khác đều có thể bị giả mạo. Validation ở client chỉ để trải nghiệm người dùng; validation thật sự phải ở server.
Ba khái niệm phòng thủ nền tảng
Attack surface (bề mặt tấn công)
Attack surface là tổng hợp tất cả điểm mà kẻ tấn công có thể tương tác với hệ thống: mọi API endpoint, mọi form nhập liệu, mọi cổng mạng mở, mọi thư viện phụ thuộc, mọi tài khoản admin. Nguyên tắc: bề mặt càng nhỏ, càng ít chỗ để tấn công. Một endpoint debug quên tắt trên production, một cổng database mở ra Internet, một tính năng cũ không ai dùng nhưng vẫn chạy — tất cả đều nới rộng bề mặt một cách vô ích. Rà soát và cắt bỏ những gì không cần là hành động phòng thủ rẻ nhất, hiệu quả nhất.
Least privilege (đặc quyền tối thiểu)
Mỗi thành phần — người dùng, service, tài khoản DB — chỉ nên có đúng quyền tối thiểu cần để làm việc, không hơn. Service báo cáo chỉ cần quyền SELECT, đừng cấp nó quyền DROP TABLE. Nếu tài khoản đó bị chiếm, thiệt hại bị giới hạn. Least privilege biến một sự cố lẽ ra là thảm họa thành một sự cố có thể kiểm soát. Chi tiết cách áp dụng trong ngân hàng nằm ở bài governance về access control.
Defense in depth (phòng thủ nhiều lớp)
Đừng bao giờ đặt tất cả trứng vào một rổ. Defense in depth là xếp nhiều lớp bảo vệ độc lập, để khi một lớp bị xuyên thủng, các lớp sau vẫn chặn được. WAF chặn ở biên; xác thực chặn ở cổng ứng dụng; phân quyền chặn ở tầng logic; input validation chặn injection; mã hóa bảo vệ dữ liệu lúc nghỉ; và audit log giúp phát hiện nếu tất cả đều thất bại.
Kẻ tấn công phải xuyên mọi lớp mới chạm được dữ liệu; bạn chỉ cần một lớp trụ vững để cứu cả hệ thống. Đó là toán học đứng về phía người phòng thủ.
Threat modeling: phòng thủ có hệ thống với STRIDE
Nghĩ như kẻ tấn công là tốt, nhưng làm ngẫu hứng thì dễ bỏ sót. Threat modeling (mô hình hóa mối đe dọa) là quy trình có cấu trúc để liệt kê các mối đe dọa một cách hệ thống, ngay từ giai đoạn thiết kế — trước khi viết một dòng code nào.
Khung phổ biến nhất là STRIDE của Microsoft, gồm sáu loại đe dọa. Điều hay là mỗi loại STRIDE đối nghịch trực tiếp với một tính chất bảo mật, giúp bạn kiểm tra không sót:
| Chữ | Loại đe dọa | Nghĩa | Vi phạm tính chất | Ví dụ ngân hàng |
|---|---|---|---|---|
| S | Spoofing | Giả mạo danh tính | Authentication | Đăng nhập bằng token đánh cắp của người khác |
| T | Tampering | Sửa đổi dữ liệu trái phép | Integrity | Đổi số tiền trong payload API chuyển khoản |
| R | Repudiation | Chối bỏ hành động đã làm | Non-repudiation | Khách phủ nhận đã lệnh chuyển tiền, không có log |
| I | Information disclosure | Rò rỉ thông tin | Confidentiality | API lộ số dư/CCCD khách hàng khác |
| D | Denial of service | Làm tê liệt dịch vụ | Availability | Flood request làm sập cổng thanh toán |
| E | Elevation of privilege | Leo thang đặc quyền | Authorization | User thường tự nâng mình thành admin |
Quy trình bốn bước
- Vẽ sơ đồ hệ thống (Data Flow Diagram). Vẽ các thành phần (app, DB, API bên thứ ba), luồng dữ liệu giữa chúng, và đặc biệt là trust boundary — ranh giới nơi mức độ tin cậy thay đổi. Ví dụ: ranh giới giữa Internet và mạng nội bộ, giữa app và database. Mọi dữ liệu vượt qua trust boundary đều phải được kiểm tra lại.
- Xác định tài sản và luồng. Cái gì đáng giá cần bảo vệ? (Số dư, PII, khóa ký giao dịch.) Dữ liệu nhạy cảm đi qua những đâu?
- Liệt kê mối đe dọa. Duyệt từng thành phần/luồng qua sáu chữ STRIDE: "Chỗ này có thể bị Spoofing không? Tampering không?..." Cách làm cơ học này giúp bạn không bỏ sót góc nào.
- Giảm thiểu (mitigation). Với mỗi đe dọa có thực, chọn biện pháp: chống Spoofing bằng MFA, chống Tampering bằng chữ ký/HMAC + HTTPS, chống Repudiation bằng audit log ký số, chống Information disclosure bằng mã hóa + phân quyền, chống DoS bằng rate limit, chống Elevation bằng kiểm soát phân quyền chặt.
Ví dụ minh họa một DFD đơn giản với trust boundary cho luồng chuyển khoản:
Đường nét đứt là trust boundary: mọi request từ khách phải được xác thực, phân quyền và validate trước khi được tin. Threat modeling nên là một hoạt động sống — cập nhật mỗi khi kiến trúc thay đổi, không phải tài liệu viết một lần rồi bỏ xó.
Shift-left và DevSecOps
Trong mô hình cũ, bảo mật là chốt chặn cuối: đội security audit ứng dụng ngay trước go-live, tìm lỗ hổng, rồi bắt dev sửa gấp. Kết quả: sửa muộn, đắt, căng thẳng, và thường bị bỏ qua vì "sát deadline rồi". Một lỗi phát hiện ở giai đoạn thiết kế rẻ hơn hàng chục đến hàng trăm lần so với lỗi phát hiện ở production.
Shift-left security là dịch chuyển các hoạt động kiểm tra bảo mật về phía trái của vòng đời phần mềm (SDLC) — gần lúc thiết kế và viết code hơn — thay vì dồn hết về cuối. DevSecOps là hiện thực hóa triết lý này: tự động hóa kiểm tra bảo mật ngay trong pipeline CI/CD, biến bảo mật thành trách nhiệm của mọi người, không riêng một đội. Chi tiết công cụ (SAST, DAST, SCA, secret scanning) sẽ nằm ở bài 7 về DevSecOps tooling, và bức tranh vận hành rộng hơn ở bài DevOps về security & SRE.
Đi kèm là hai nguyên tắc thiết kế:
- Secure by design — bảo mật là yêu cầu kiến trúc từ đầu, không phải tính năng bổ sung. Bạn thiết kế luồng chuyển tiền với giả định "sẽ có người tấn công", ngay từ bản vẽ.
- Secure by default — cấu hình mặc định phải an toàn nhất. Endpoint mặc định yêu cầu xác thực; dữ liệu mặc định được mã hóa; quyền mặc định là từ chối (deny-by-default), chỉ mở ra cái gì thực sự cần. Người dùng phải chủ động nới lỏng, chứ không phải chủ động siết chặt.
OWASP và lộ trình series
OWASP (Open Worldwide Application Security Project) là tổ chức phi lợi nhuận, nguồn tài nguyên bảo mật ứng dụng uy tín và miễn phí bậc nhất. Sản phẩm nổi tiếng nhất là OWASP Top 10 — danh sách mười loại rủi ro nghiêm trọng nhất, cập nhật vài năm một lần dựa trên dữ liệu thực tế toàn ngành. Đây là điểm khởi đầu chuẩn mực cho bất kỳ ai học AppSec, và là ngôn ngữ chung khi trao đổi về rủi ro.
Series này sẽ đi lần lượt, luôn bám bối cảnh dữ liệu/API ngân hàng:
| Bài | Chủ đề |
|---|---|
| Bài 1 (bài này) | Tư duy bảo mật, CIA/AAA, threat modeling, DevSecOps |
| Bài 2 | OWASP Top 10 — tổng quan mười rủi ro |
| Bài 3 | Injection (SQLi, XSS...) & lỗi authentication |
| Bài 4 | Broken access control & lỗi mã hóa (crypto) |
| Bài 5 | Quản lý secret & bảo mật chuỗi cung ứng (supply chain) |
| Bài 6 | Bảo mật API (OWASP API Top 10) |
| Bài 7 | Công cụ DevSecOps trong pipeline |
| Bài 8 | Bảo mật dữ liệu chuyên biệt cho ngân hàng |
Nếu muốn nối sang góc nhìn liên quan, xem thêm xác thực & bảo mật API và mã hóa & masking dữ liệu.
Use case thực tế
Bối cảnh. Đội bạn xây một endpoint mới cho app mobile NCB: GET /api/v1/accounts/{account_id}/transactions — trả về lịch sử giao dịch của một tài khoản. Deadline sát, cả nhóm chỉ tập trung làm "chạy đúng".
Bước 1 — Threat model nhanh (30 phút, dùng STRIDE). Vẽ DFD: mobile app → API Gateway → Transaction Service → DB. Trust boundary nằm giữa app và Gateway. Duyệt STRIDE:
- Spoofing: endpoint có bắt buộc token xác thực không? → Có, nhưng...
- Elevation / Broken access control: service có kiểm tra
account_idtrong URL thuộc về đúng người đang đăng nhập không? Phát hiện: code chỉ kiểm token hợp lệ, rồi truy vấn thẳng theoaccount_idtừ URL. Nghĩa là khách hàng A đăng nhập hợp lệ, đổiaccount_idthành của khách hàng B, sẽ xem được toàn bộ giao dịch của B. Đây chính là lỗ hổng BOLA/IDOR — sẽ mổ kỹ ở bài API. - Information disclosure: response có trả dư trường (số CCCD, số dư nội bộ) không cần thiết cho màn hình này không?
Bước 2 — Ước lượng thiệt hại. Giả sử hệ thống có 2 triệu tài khoản. Một script quét tuần tự account_id có thể trích xuất lịch sử giao dịch của toàn bộ khách hàng chỉ trong vài giờ — vi phạm Confidentiality nghiêm trọng, đủ để kích hoạt nghĩa vụ báo cáo theo Nghị định 13/2023.
Bước 3 — Giảm thiểu (shift-left, sửa trước khi lên production).
- Thêm kiểm tra authorization: xác nhận
account_idthuộc vềcustomer_idlấy từ token, nếu không → trả 403. - Áp least privilege: tài khoản DB của service này chỉ có quyền
SELECTtrên đúng các bảng cần. - Giảm attack surface / info disclosure: chỉ trả các trường màn hình cần; che (masking) số tài khoản.
- Thêm audit log (Accounting) cho mỗi lần truy cập lịch sử giao dịch, phục vụ chống Repudiation và điều tra.
- Đưa một integration test kiểm tra "user A không xem được dữ liệu user B" vào CI — biến bài học thành hàng rào tự động, đúng tinh thần DevSecOps.
Kết quả. Một lỗ hổng có thể thành thảm họa rò rỉ toàn bộ khách hàng đã bị chặn ngay ở giai đoạn thiết kế/review, với chi phí 30 phút threat modeling — thay vì hàng tỷ đồng xử lý khủng hoảng và mất niềm tin.
Ghi nhớ
- Với ngân hàng, AppSec sống còn vì dữ liệu nhạy cảm + tiền thật + tuân thủ + là mục tiêu chủ động. Bạn phải đúng 100% lần, kẻ tấn công chỉ cần đúng 1 lần.
- CIA triad = ba mục tiêu: Confidentiality (riêng tư), Integrity (toàn vẹn), Availability (sẵn sàng). Chúng thường đánh đổi nhau.
- AAA = ba cơ chế: Authentication (bạn là ai), Authorization (được làm gì), Accounting (đã làm gì). Đăng nhập thành công không đồng nghĩa được phép làm mọi thứ.
- Attacker mindset: luôn hỏi "chuyện gì xảy ra nếu đầu vào là ác ý?". Nguyên tắc vàng: không bao giờ tin đầu vào từ client; validate ở server.
- Ba trụ phòng thủ: thu nhỏ attack surface, cấp least privilege, xếp defense in depth nhiều lớp độc lập.
- Threat modeling với STRIDE (Spoofing/Tampering/Repudiation/Info disclosure/DoS/Elevation) giúp liệt kê đe dọa có hệ thống từ giai đoạn thiết kế. Quy trình: vẽ DFD + trust boundary → xác định tài sản → duyệt STRIDE → giảm thiểu.
- Shift-left / DevSecOps: đẩy bảo mật về sớm và tự động hóa trong CI/CD. Sửa sớm rẻ hơn hàng chục lần sửa muộn.
- Secure by design & secure by default: bảo mật là yêu cầu kiến trúc từ đầu; mặc định phải an toàn nhất (deny-by-default).
- OWASP Top 10 là điểm khởi đầu chuẩn — series sẽ đi sâu từng nhóm rủi ro trong bối cảnh dữ liệu/API ngân hàng.
Bài viết liên quan
Continuous Integration/Delivery/Deployment, cấu trúc pipeline, ví dụ GitHub Actions và chiến lược release.
Container vs máy ảo, image/layer, Dockerfile, volume, network, Docker Compose và best practices.
Vì sao cần orchestration; Pod, Deployment, Service, Ingress; scaling, self-healing và cấu hình.
Bản chất DevOps: phá bỏ rào cản Dev–Ops, vòng lặp vô tận, CALMS, và vì sao tự động hoá.