Xác thực Webhook không đồng nghĩa với việc kiểm chứng dữ liệu
Nhiều lập trình viên đã đưa một lỗi nguy hiểm lên môi trường production. Họ nhầm lẫn giữa xác thực (authentication) và kiểm chứng (validation).
Xác thực có nghĩa là tin nhắn đến từ đúng nhà cung cấp. Kiểm chứng có nghĩa là dữ liệu bên trong tin nhắn là chính xác.
Nếu bạn chỉ thực hiện bước đầu tiên, bạn sẽ mất tiền.
Một lỗ hổng WordPress gần đây (CVE-2026-9189) đã cho thấy sai lầm này. Add-on PayPal và Stripe của Contact Form 7 đã không kiểm tra số tiền thanh toán.
Dưới đây là cách kẻ tấn công khai thác lỗi này:
- Kẻ tấn công tạo một đơn hàng trị giá 2.000 USD.
- Kẻ tấn công thực hiện một khoản thanh toán thực tế trị giá 1 USD.
- Chúng đặt số hóa đơn trùng khớp với đơn hàng 2.000 USD.
- PayPal gửi một thông báo thực, đã được xác minh cho khoản thanh toán 1 USD.
- Plugin nhận thấy tin nhắn đã được xác minh và đánh dấu đơn hàng 2.000 USD là đã thanh toán.
Plugin đã tin tưởng người đưa tin nhưng lại bỏ qua nội dung tin nhắn.
Đừng mắc phải sai lầm này. Khi xử lý webhook, hãy làm theo các bước sau:
- Xác thực tin nhắn bằng chữ ký (signatures) hoặc mã bí mật dùng chung (shared secrets).
- Đối chiếu số tiền và loại tiền tệ với đơn hàng trong cơ sở dữ liệu của bạn.
- Xác minh email người nhận khớp với tài khoản của bạn.
- Sử dụng một giá trị phía máy chủ (server-side) để liên kết đơn hàng. Đừng chỉ tin tưởng vào ID hóa đơn được gửi trong payload.
- Sử dụng tính idempotent để bỏ qua các ID giao dịch trùng lặp.
- Luôn duy trì xác thực TLS cho tất cả các yêu cầu.
- Áp dụng cơ chế "fail closed". Nếu bất kỳ bước kiểm tra nào thất bại, hãy dừng mọi thứ lại.
Nếu bạn đang sử dụng Contact Form 7 PayPal and Stripe Add-on phiên bản 2.4.9 hoặc cũ hơn, hãy cập nhật ngay lập tức. Mọi đơn hàng chưa thanh toán đều là mục tiêu của lỗ hổng này.
Luôn xác thực người đưa tin, sau đó mới kiểm tra dữ liệu.