Tổng hợp 84 câu hỏi phỏng vấn Bảo Mật kèm đáp án chi tiết, song ngữ Việt–Anh — sắp xếp từ cơ bản đến nâng cao. Ôn luyện miễn phí, tự động lưu tiến độ.
XSS là lỗ hổng cho phép attacker inject script độc hại chạy trong browser của nạn nhân — đánh cắp session, redirect user, sửa nội dung trang. - Stored XSS — script được lưu vào DB (comment, profile), tấn công mọi user xem trang. -…
CSRF lợi dụng việc browser tự động đính kèm cookie khi gửi request đến một domain — attacker đặt form/img trên evil.com trỏ đến bank.com, request mang theo session cookie của nạn nhân. - Ví dụ — <img src='https://bank.com/transfer?to=attacker&amount=1000': nếu user đang đăng nhập và…
OAuth 2.0 là framework uỷ quyền (delegated authorization) — không phải authentication; OpenID Connect (OIDC) là layer trên OAuth bổ sung authentication, trả về idtoken. - Bốn vai trò — Resource Owner (user), Client (app), Authorization Server (cấp token), Resource Server (API). - Authorization Code…
HTTPS là HTTP chạy trên TLS — mã hoá toàn bộ giao tiếp, xác thực danh tính server, đảm bảo toàn vẹn dữ liệu. - TLS handshake — Client Hello (cipher suites, version) → Server Hello (cipher đã chọn + certificate) → client verify certificate…
Same-origin policy (SOP) chặn JavaScript từ một origin (scheme + host + port) đọc response từ origin khác — bảo vệ khỏi việc đọc trộm dữ liệu cross-origin (data theft). Lưu ý: SOP không chặn việc GỬI request cross-site — vì vậy CSRF vẫn tồn…
Security headers là các response header điều khiển hành vi browser để chặn tấn công — Helmet.js (app.use(helmet())) set sẵn bộ mặc định hợp lý. - Strict-Transport-Security — max-age=31536000; includeSubDomains: ép HTTPS, chặn SSL stripping. - X-Content-Type-Options: nosniff — chặn MIME sniffing, browser không tự…
SQL Injection là tấn công chèn SQL qua user input để thao túng query — bypass đăng nhập, trích xuất hoặc xoá dữ liệu. - Ví dụ kinh điển — username ' OR '1'='1' -- biến query thành SELECT FROM users WHERE username = ''…
Ba attribute kiểm soát mức lộ và cách gửi cookie: HttpOnly, Secure, SameSite. - HttpOnly — JS không đọc được cookie qua document.cookie — XSS không đánh cắp được session token; cookie vẫn tự động gửi kèm HTTP request. - Secure — cookie chỉ gửi…
JWT stateless auth dùng signed token thay vì server-side session — không cần DB lookup mỗi request. - Login: verify credentials → tạo JWT (sign với secret) → gửi token cho client. - Request: client gửi token trong Authorization header (Bearer token). - Server: middleware…
OWASP Top 10 là danh sách 10 rủi ro bảo mật web phổ biến nhất, do Open Web Application Security Project cập nhật định kỳ vài năm một lần — bản 2021 là bản được tham chiếu nhiều nhất; bản 2025 tái cấu trúc các…
Session dễ revoke nhưng cần Redis khi chạy nhiều server; JWT stateless nên dễ scale nhưng không revoke được trước khi hết hạn. Session-based: server giữ session data trong memory/Redis, client chỉ giữ session ID trong cookie. Server stateful nên phải lookup mỗi request. -…
Cả bcrypt và Argon2 đều là password hashing function được thiết kế để chậm — ngược hẳn SHA-256/MD5 vốn tối ưu cho nhanh. bcrypt: đã đứng vững từ 1999, độ khó chỉnh bằng cost factor (saltRounds) và tăng theo hàm mũ — bcrypt.hash(password, 12). Argon2:…
Rate limiting ngăn abuse, brute-force và DoS. Bốn thuật toán hay gặp: Fixed window đếm request trong khung thời gian cố định (0:00-0:59, 1:00-1:59). Dễ làm nhưng dễ lách: gửi 100 request cuối window cũ cộng 100 request đầu window mới thành 200 request trong…
Clickjacking embed site trong invisible iframe để đánh lừa user click — fix bằng Content-Security-Policy: frame-ancestors 'none' (CSP, recommended) và X-Frame-Options: DENY (legacy, set cả hai để backward compatibility). Clickjacking là attack embed target site trong invisible iframe, user nghĩ đang click button trên trang…
SSO (Single Sign-On): đăng nhập một lần tại nhà cung cấp danh tính trung tâm (IdP — Identity Provider), rồi truy cập nhiều ứng dụng (SP/relying party) mà không phải đăng nhập lại. Ứng dụng không giữ mật khẩu; nó tin vào "giấy chứng nhận"…
Authentication (authn) xác minh bạn là ai; Authorization (authz) quyết định bạn được làm gì — authn luôn xảy ra trước authz. - Authentication — xác minh danh tính: đăng nhập bằng password, OTP, biometric, OAuth/SSO. Kết quả: hệ thống biết request đến từ user…
Hashing là một chiều (không đảo ngược được), encryption đảo ngược được khi có key, encoding đảo ngược được mà không cần key — dùng nhầm loại là lỗi bảo mật thường gặp. - Hashing — biến input thành chuỗi độ dài cố định, không…
JWT gồm ba phần header.payload.signature phân tách bằng dấu chấm, mỗi phần encode base64url — base64url là encoding chứ không phải mã hoá: ai cầm token đều đọc được payload. - Cấu trúc — header ({ 'alg': 'RS256', 'typ': 'JWT' } — thuật toán ký);…
Ý tưởng cốt lõi: trình duyệt chỉ cầm một mã tạm (authorization code), còn access token được đổi qua back-channel (server gọi thẳng server) nên không lộ ra thanh địa chỉ. Các bước: 1. App chuyển hướng user tới authorization endpoint của provider, kèm clientid,…
PKCE (Proof Key for Code Exchange) chống authorization code interception — trường hợp kẻ tấn công chặn được code ở bước redirect (app mobile đăng ký trùng custom URL scheme, log của trình duyệt, extension...) rồi tự đem đi đổi lấy token. Cách hoạt động:…
Hai token phục vụ hai mục đích khác nhau: idtoken accesstoken --------- Trả lời câu hỏi User này là ai (authentication) Bearer được làm gì (authorization) Đối tượng nhận (aud) Chính client app Resource server / API Định dạng Luôn là JWT có chữ ký…
state chống CSRF trên bước callback. Không có nó, kẻ tấn công có thể lấy authorization code của tài khoản của chính hắn rồi dụ nạn nhân mở link callback đó — kết quả là tài khoản của nạn nhân bị gắn (link) với tài…
Cần một thứ phía server để phân biệt token phát trước và sau thời điểm thu hồi. Ba cách hay dùng: 1. Cột tokenversion trên user — đơn giản nhất. Access token mang claim ver; middleware so token.ver với user.tokenversion. Đăng xuất mọi thiết bị…
Cookie phiên chuẩn: - HttpOnly — JavaScript không đọc được document.cookie. Đây là lớp chặn chính khi có XSS. - Secure — chỉ gửi qua HTTPS. Bắt buộc ở production. - SameSite — quyết định cookie có được gửi kèm request từ site khác không:…
Không kéo dài tuổi thọ của cookie phiên thường. Cách chuẩn là tách làm hai token: - Session cookie — ngắn (vài chục phút tới vài giờ), là thứ dùng cho mọi request. - Remember-me token — dài (14–30 ngày), chỉ dùng một lần để…
Ở đây không có user, nên không dùng authorization code. Hai lựa chọn phổ biến: Client credentials grant — service tự lấy token bằng chính danh tính của nó. Token nhận được là access token của service, không mang sub là user. Ưu điểm: dùng…
Khác biệt cốt lõi: API key định danh ứng dụng/khách hàng và dùng được rất lâu; access token chứng minh một quyền đã được cấp và hết hạn nhanh. API key Access token --------- Tuổi thọ Nhiều tháng/năm, đến khi thu hồi tay Vài phút…
Luồng chính: 1. User nhập số điện thoại → server chuẩn hoá về E.164 (+84...) để tránh cùng số lưu hai dạng. 2. Sinh OTP 6 chữ số bằng CSPRNG, lưu hash kèm expiresat (3–5 phút) và attempts = 0. Không lưu OTP thô. 3.…
Dùng hàm băm mật khẩu chuyên dụng, chậm có chủ đích: Argon2id (khuyến nghị đầu tiên), hoặc bcrypt/scrypt khi hạ tầng chưa hỗ trợ Argon2. Không tự chế thuật toán. Vì sao không SHA-256: nó được thiết kế để nhanh. GPU băm SHA-256 ở mức…
Cả ba đều là chèn script vào trang, khác nhau ở nơi payload đi qua và nơi HTML được ghép. - Reflected: payload nằm trong request (query string, form) và được server ghép thẳng vào HTML trả về. Code sinh lỗi nằm ở template phía…
Cả hai đều parse chuỗi thành HTML thật rồi gắn vào DOM. Mọi thẻ, thuộc tính sự kiện trong chuỗi đều có hiệu lực. React mặc định escape khi bạn render {value}, nên dangerouslySetInnerHTML chính là chỗ bạn tự tay tắt lớp bảo vệ đó…
Vì trình duyệt parse mỗi vị trí trong trang theo một bộ luật khác nhau. Chuỗi đã escape đúng cho thân HTML vẫn có thể thoát ra ở ngữ cảnh khác. Bốn ngữ cảnh cần nhớ: Vị trí Cần làm ------ Thân HTML <divHERE</div Escape…
Open redirect là khi ứng dụng nhận URL đích từ tham số của user rồi chuyển hướng tới đó mà không kiểm tra. Sau khi đăng nhập, hệ thống đẩy user sang trang giả mạo. Người dùng thấy link bắt đầu bằng domain thật của…
CSP là lớp phòng thủ thứ hai sau escaping: kể cả khi payload lọt vào DOM, trình duyệt vẫn từ chối thực thi script không được cho phép. Vấn đề với framework SSR là trang luôn có inline script (hydration data, <Script của Next). Nếu…
Whitelist domain thất bại vì bạn tin cả một origin, trong khi origin đó có thể chứa những file khiến CSP vô hiệu. Ba đường bypass thường gặp: 1. JSONP endpoint trên domain được whitelist: <script src="//cdn.example.com/jsonp?callback=alert(1)" — script chạy từ domain hợp lệ. 2.…
Vẫn cần. SameSite=Lax thu hẹp rất nhiều bề mặt tấn công nhưng không phải là hàng rào đủ. Lớp 1 — SameSite cookie. Lax chặn cookie đi kèm request cross-site trừ điều hướng top-level bằng GET. Chỗ hở: - Nếu có endpoint đổi trạng thái…
Đây là hai tính năng SSRF điển hình: server tự đi gọi một URL do user kiểm soát, và server đứng bên trong mạng nội bộ. Mục tiêu kẻ tấn công nhắm tới: http://169.254.169.254/ (metadata của cloud, lấy được IAM credential), http://localhost:port (admin panel, Redis,…
Ba câu hỏi phải trả lời: file có đúng loại không, lưu ở đâu, và phục vụ lại ra sao. 1. Kiểm tra loại thật, không tin client. - Phần mở rộng và Content-Type do client gửi đều sửa được. evil.php đổi tên thành avatar.jpg…
Path traversal xảy ra khi tên file/đường dẫn lấy từ input của user rồi ghép vào thao tác đọc/ghi file. Vì sao lọc ../ không đủ: - Lọc một lần, không lặp: ....// sau khi bỏ ../ còn lại ../. - Biến thể encode: %2e%2e%2f,…
CORS là cơ chế nới lỏng Same-Origin Policy. Cấu hình sai nghĩa là bạn tự tay mở dữ liệu của mình cho site khác đọc. Sai lầm nguy hiểm nhất — reflect nguyên Origin kèm credentials: Bất kỳ site nào cũng gửi được request kèm…
Salt là một chuỗi ngẫu nhiên, duy nhất cho từng bản ghi mật khẩu, được trộn vào trước khi hash và lưu công khai cùng hash trong DB. Vì sao cần salt riêng cho mỗi user: - Hai user đặt trùng mật khẩu sẽ ra…
Brute force là dò nhiều mật khẩu cho một tài khoản: cùng một username, thử hàng nghìn chuỗi ứng viên. Credential stuffing là thử cặp email/mật khẩu đã lộ từ site khác lên hệ thống của bạn — mỗi tài khoản có thể chỉ bị…
NIST SP 800-63B lật ngược khá nhiều quy tắc cũ vì chúng làm giảm chứ không tăng an toàn thực tế. Nên làm: - Cho phép mật khẩu dài tối thiểu 8 ký tự (khuyến khích 15+), giới hạn trên không dưới 64 ký tự.…
User enumeration là việc kẻ tấn công xác định được email/username nào tồn tại trong hệ thống. Có danh sách account thật thì credential stuffing và phishing hiệu quả hơn nhiều. Ba kênh rò rỉ hay gặp: 1. Nội dung thông báo khác nhau —…
Cả ba đều là hàm hash chậm có tham số chi phí, khác nhau ở loại tài nguyên mà chúng bắt kẻ tấn công phải trả. - Argon2id — lựa chọn mặc định cho hệ thống mới. Vừa tốn CPU vừa tốn bộ nhớ (memory-hard)…
Không thể "giải mã" hash cũ, nhưng có hai chiến lược nâng cấp mà user không phải làm gì. Cách 1 — nâng cấp khi đăng nhập (lazy rehash). Giữ nguyên hash cũ, thêm cột đánh dấu thuật toán. Khi user đăng nhập thành công,…
Khoá cứng tài khoản sau N lần sai tạo ra kênh tấn công từ chối dịch vụ: kẻ tấn công chỉ cần biết email nạn nhân, gửi N request sai mật khẩu là khoá được người ta. Với danh sách email lấy từ bước enumeration,…
Cả hai — mỗi chiều chặn một dạng tấn công khác nhau, dùng một chiều là có lỗ hổng. Khoá đếm Chặn được Điểm mù --------- Theo tài khoản Dò mật khẩu một tài khoản từ botnet nhiều IP Credential stuffing rải mỏng (mỗi account…
TOTP (RFC 6238) là HOTP với bộ đếm lấy từ thời gian. Server và ứng dụng xác thực chia sẻ một secret ngẫu nhiên (encode base32, thường trao qua QR code). Mã 6 chữ số được tính: Hai bên không trao đổi gì thêm —…
Luồng chuẩn: user nhập email → server gửi link chứa token dùng một lần, hết hạn ngắn → user mở link, đặt mật khẩu mới → token bị huỷ. Yêu cầu với token: - Sinh bằng CSPRNG, tối thiểu 128 bit entropy (crypto.randomBytes(32)), không phải…
Quyền phải được kiểm tra ở phía server, tại tầng gần dữ liệu nhất, trên mọi endpoint — UI chỉ quyết định hiển thị. Ẩn nút "Xoá" chỉ làm người dùng bình thường không thấy chức năng. Kẻ tấn công không dùng UI: họ mở…
Vì git giữ lịch sử vĩnh viễn: một khi secret vào commit, nó còn nằm đó kể cả sau khi bạn xoá file ở commit sau. Repo private cũng không an toàn — chỉ cần một lần chuyển sang public, một fork, một bản clone…
Hai lớp bảo vệ hai mối đe doạ khác nhau, không thay thế nhau. - In-transit: bảo vệ dữ liệu khi đang đi trên đường — trình duyệt tới server, service tới service, app tới database. Cơ chế là TLS (HTTPS, sslmode=require khi nối Postgres).…
Phân biệt bằng một câu hỏi duy nhất: có cần lấy lại giá trị gốc không? - Hash — một chiều, không giải ngược được. Dùng khi chỉ cần so khớp hoặc kiểm tra toàn vẹn: mật khẩu, checksum file, khoá cache. - Mã hoá…
Log thường bị coi là vùng "an toàn" nhưng thực tế nó được đẩy sang hệ thống tập trung, giữ lâu, và nhiều người đọc được hơn cả database. Không ghi vào log: - Mật khẩu, kể cả trong payload đăng ký/đăng nhập. - Token,…
Nguyên tắc số một: rotate trước, dọn lịch sử sau. Nhiều người làm ngược — mất hàng giờ viết lại git history trong khi key vẫn còn hiệu lực và đã bị bot quét từ vài phút sau lúc push. Thứ tự xử lý: 1.…
Không. Đọc kết quả audit theo kiểu "số càng nhỏ càng tốt" dẫn tới hai sai lầm: nâng bừa gây hỏng build, hoặc bỏ qua cả danh sách vì "toàn cảnh báo giả". Quy trình hợp lý: 1. Phân loại theo đường đi thực tế.…
Tối thiểu hoá dữ liệu là chỉ thu thập và lưu đúng những gì cần cho mục đích đã nêu, và chỉ giữ trong thời gian còn cần. Nó là lựa chọn kiến trúc, không phải việc của riêng bộ phận pháp chế: dữ liệu…