Bảo Mật API Nâng Cao với Mã Hóa RSA: Kỹ Thuật Chống Tấn Công Hiệu Quả
Trong bối cảnh an ninh mạng ngày càng phức tạp, việc bảo vệ API khỏi các cuộc tấn công ngày càng trở nên quan trọng. Xác thực và ủy quyền là hai yếu tố thiết yếu cho bất kỳ hệ thống bảo mật nào. Tuy nhiên, chỉ dựa vào các cơ chế này không đủ để ngăn chặn những rủi ro như CSRF (Cross-Site Request Forgery) hay các cuộc tấn công brute-force.
Nhiều nền tảng lớn như X (trước đây là Twitter), Facebook, TikTok và Instagram cũng đã gặp phải những vấn đề này. Vậy, chúng ta có thể làm gì để tăng cường an ninh cho API? Câu trả lời là việc áp dụng kỹ thuật Bảo vệ CSRF Tiên tiến với mã hóa RSA. Đây là một giải pháp nhẹ nhưng vô cùng hiệu quả nhằm ngăn chặn việc sử dụng trái phép API, cũng như các cuộc tấn công brute-force và các yêu cầu không hợp lệ.
Cách Thức Hoạt Động Của Kỹ Thuật Mã Hóa RSA
Kỹ thuật này bổ sung một lớp bảo mật mới lên hệ thống xác thực hiện tại. Dưới đây là cách mà chúng ta có thể thực hiện:
- Tạo Một Cặp Khóa RSA: Khóa công khai và khóa riêng tư sẽ được tạo ra. Bạn có thể sử dụng các công cụ như cryptotools.net/rsagen để thực hiện việc này.
- Lưu Trữ Khóa Công Khai: Khóa công khai sẽ được lưu trên máy khách, tốt nhất là trong các biến môi trường.
- Mã Hóa Payload: Trước khi gửi yêu cầu API, chúng tôi sẽ mã hóa một payload chứa các thông tin quan trọng như:
- Phương thức yêu cầu
- URL yêu cầu
- Dấu thời gian hiện tại
- Gửi Payload Mã Hóa: Các payload mã hóa này sẽ được gửi kèm theo tiêu đề CSRF trong yêu cầu.
- Xác Thực Tại Backend: Trên backend, payload sẽ được giải mã bằng khóa riêng RSA. Các bước xác thực bao gồm:
- Kiểm tra xem phương thức và URL có khớp hay không.
- Đảm bảo rằng dấu thời gian không quá cũ (ví dụ: không quá 15 giây).
- Xử lý Kết Quả: Nếu xác thực thành công, yêu cầu sẽ được xử lý; ngược lại, nó sẽ bị từ chối.
Triển Khai trên Client (React + Axios)
Để thuận tiện trong việc xử lý CSRF, chúng tôi sẽ sử dụng Axios interceptors. Sau đây là thiết lập trong TypeScript:
javascript
import axios, { AxiosError } from 'axios';
import appConfig from 'config'; // Import cấu hình ứng dụng
import { rsaCrypt } from 'Utils/rsaCrypt'; // Tiện ích RSA
const axiosClient = axios.create({
baseURL: appConfig.BASE_URL,
headers: {
'Content-Type': 'application/json',
},
});
// Hàm trợ giúp để tạo payload CSRF
const getCsrfPayload = (method: string, url: string) => {
return {
url,
method,
timestamp: Date.now(),
};
};
// Interceptor yêu cầu Axios
axiosClient.interceptors.request.use(
async (config) => {
if (config && config.headers) {
// Tạo payload CSRF
const csrfPayload = getCsrfPayload(config.method!, config.url!);
// Mã hóa payload
const csrfToken = await rsaCrypt.encrypt(JSON.stringify(csrfPayload));
if (csrfToken) {
config.headers['csrf'] = csrfToken; // Gắn token đã mã hóa vào tiêu đề
}
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
// Interceptor phản hồi Axios
axiosClient.interceptors.response.use(
function (response) {
return response;
},
async function (error: AxiosError<{ code: string; message: string }>) {
return Promise.reject(error);
}
);
export default axiosClient;
Triển Khai trên Backend (Node.js + Express)
Trên máy chủ, chúng ta sẽ xác thực mã thông báo CSRF bằng khóa riêng RSA và đảm bảo tính toàn vẹn của yêu cầu.
Middleware Để Xác Thực CSRF
javascript
import { NextFunction, Request, Response } from 'express';
import { BadRequestError } from '../utils/custom.error';
import { rsaEncrypt } from '../utils/rsa.crypt';
type EncPayload = {
url: string;
method: string;
timestamp: number;
};
export async function csrfValidation(req: Request, res: Response, next: NextFunction) {
const urlPath = decodeURIComponent(req.originalUrl.split('?')[0]?.trim() || '');
const method = req.method.toLowerCase();
const csrf = req.headers['csrf'];
if (!csrf || Array.isArray(csrf)) {
throw new BadRequestError('CSRF token is missing or malformed.', 'CSRF_TOKEN_MISSING');
}
const now = Date.now();
const payload = decryptPayload(csrf);
if (!payload) {
throw new BadRequestError('Failed to decrypt or parse CSRF token.', 'CSRF_TOKEN_INVALID');
}
const payloadUrlPath = decodeURIComponent(payload.url.split('?')[0]?.trim() || '');
if (urlPath !== payloadUrlPath || payload.method.toLowerCase() !== method) {
throw new BadRequestError(
'CSRF token validation failed: URL or method mismatch.',
'CSRF_VALIDATION_FAILED'
);
}
const queryExpiry = 15 * 1000; // 15 giây
if (now - payload.timestamp > queryExpiry) {
throw new BadRequestError('CSRF token has expired.', 'CSRF_TOKEN_EXPIRED');
}
next();
}
function decryptPayload<T = EncPayload>(payload: string): T | undefined {
try {
return JSON.parse(rsaEncrypt.decrypt(payload)) as T;
} catch (error) {
console.error('Error decrypting payload:', error);
return undefined;
}
}
Các Tính Năng Chính
- Mã Hóa Bất Đối Xứng: Chỉ có máy chủ biết khóa riêng, đảm bảo rằng mã thông báo không thể bị giả mạo.
- Độ Tươi Mới Của Yêu Cầu: Dấu thời gian chỉ định thời hạn hiệu lực của mã thông báo trong vòng 15 giây, ngăn chặn các cuộc tấn công replay.
- Xác Thực Phương Thức & URL: Đảm bảo rằng mã thông báo liên kết với các hành động cụ thể, ngăn chặn các cuộc tấn công brute-force.
Kết Luận
Kỹ thuật bảo mật này không chỉ đơn thuần là bổ sung cho các cơ chế xác thực và ủy quyền hiện có, mà còn mở ra hướng đi mới cho việc củng cố bảo mật API. Nhờ vào các mã thông báo CSRF đã mã hóa với dấu thời gian, chúng ta có thể giảm thiểu rủi ro từ các cuộc tấn công độc hại, từ đó bảo vệ API một cách hiệu quả hơn. Hãy thử nghiệm và nâng cao bảo mật cho ứng dụng của bạn ngay hôm nay!
source: viblo