- AJAX trong WordPress hoạt động thế nào?
- Vì sao AJAX dễ bị hack?
- Ví dụ AJAX nguy hiểm
- 1. Không kiểm tra quyền
- 2. Không có nonce → CSRF
- 3. wp_ajax_nopriv để lộ dữ liệu nhạy cảm
- Cách secure AJAX trong WordPress
- 1. Kiểm tra quyền bằng current_user_can()
- 2. Bắt buộc dùng nonce
- Front-end
- Back-end
- 3. Validate dữ liệu trước khi xử lý
- 4. Escape output trước khi trả về
- 5. Không trả về dữ liệu nhạy cảm
- 6. Không dùng wp_ajax_nopriv trừ khi thật sự cần
- 7. Không để AJAX tự chạy hành động nguy hiểm
- 8. Dùng wp_send_json() thay vì echo
- 9. Luôn đặt die(); / exit tại cuối AJAX custom
- 10. Log lại các request AJAX quan trọng
- Ví dụ AJAX bảo mật chuẩn WordPress
- Chuỗi tấn công AJAX thường gặp trong WordPress
- Checklist bảo mật AJAX
- Kết luận
Bài viết này giúp bạn nắm toàn bộ cách bảo mật AJAX trong WordPress – dành cho mọi plugin/theme developer.
AJAX trong WordPress hoạt động thế nào?
WordPress cung cấp 2 loại endpoint AJAX:
- wp_ajax_* – dành cho user đã đăng nhập
- wp_ajax_nopriv_* – dành cho user chưa đăng nhập
Endpoint URL luôn là:
/wp-admin/admin-ajax.php
Chỉ cần client gửi action=my_action là WordPress chạy function tương ứng.
Vì sao AJAX dễ bị hack?
- Dev quên kiểm tra quyền (capability)
- Quên kiểm tra nonce → dính CSRF
- Xử lý dữ liệu user input thẳng → dính XSS, SQL Injection
- wp_ajax_nopriv mở toang cho toàn bộ internet
- AJAX trả về dữ liệu nhạy cảm (email, option, key…)
- Không log request
Hacker rất thích quét AJAX của các plugin để tìm endpoint quên bảo mật.
Ví dụ AJAX nguy hiểm
1. Không kiểm tra quyền
add_action( 'wp_ajax_delete_post', function() {
wp_delete_post( $_POST['id'] );
});
→ User subscriber cũng gọi được → xóa sạch bài viết website.
2. Không có nonce → CSRF
add_action( 'wp_ajax_update_settings', function() {
update_option( 'my_settings', $_POST['data'] );
});
→ Chỉ cần admin đang login → hacker chèn form bẫy là dính.
3. wp_ajax_nopriv để lộ dữ liệu nhạy cảm
add_action( 'wp_ajax_nopriv_get_users', function() {
echo json_encode( get_users() );
});
→ Hacker download full danh sách user.
Cách secure AJAX trong WordPress
1. Kiểm tra quyền bằng current_user_can()
Luôn luôn kiểm tra capability trước khi thực hiện hành động:
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( 'No permission.' );
}
Nếu action là admin setting → dùng manage_options.
2. Bắt buộc dùng nonce
Front-end:
var ajaxData = {
action: "my_update",
nonce: myAjax.nonce,
data: "hello"
};
Back-end:
check_ajax_referer( 'my_update_action', 'nonce' );
Không có nonce = 100% dính CSRF.
3. Validate dữ liệu trước khi xử lý
$id = intval( $_POST['id'] );
$text = sanitize_text_field( $_POST['text'] );
Đừng bao giờ tin input người dùng.
4. Escape output trước khi trả về
wp_send_json_success( array(
'title' => esc_html( $title )
));
Tránh trả raw HTML chứa script.
5. Không trả về dữ liệu nhạy cảm
- admin_email
- user email
- API keys
- non-public option
Hacker rất thích brute-force API keys qua AJAX.
6. Không dùng wp_ajax_nopriv trừ khi thật sự cần
Nếu endpoint cho người chưa đăng nhập → phải validate kỹ:
if ( empty( $_POST['safe_field'] ) ) {
wp_send_json_error();
}
7. Không để AJAX tự chạy hành động nguy hiểm
Ví dụ nguy hiểm:
wp_ajax_nopriv_delete_product
Chỉ cần nghe tên là thấy sai.
8. Dùng wp_send_json() thay vì echo
wp_send_json_success( $data );
Tự động set header JSON, exit và sạch sẽ.
9. Luôn đặt die(); / exit tại cuối AJAX custom
Tránh bị lỗi hoặc leak dữ liệu ngoài ý muốn.
10. Log lại các request AJAX quan trọng
AJAX là nơi hacker thử khai thác nhiều nhất.
Ví dụ AJAX bảo mật chuẩn WordPress
function my_secure_ajax() {
// 1. Check nonce
check_ajax_referer( 'my_nonce_action', 'nonce' );
// 2. Check capability
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( 'No permission.' );
}
// 3. Validate input
$data = sanitize_text_field( $_POST['data'] );
// 4. Process
update_option( 'my_plugin_settings', $data );
// 5. Output safely
wp_send_json_success( array(
'message' => 'Updated successfully'
) );
}
add_action( 'wp_ajax_my_secure_ajax', 'my_secure_ajax' );
Chuỗi tấn công AJAX thường gặp trong WordPress
- CSRF → update option → takeover site
- Privilege Escalation → user thường gọi AJAX admin
- SQL injection qua AJAX input
- XSS khi trả HTML không escape
- Data leak → lấy danh sách user, email, token
Checklist bảo mật AJAX
- Luôn dùng nonce (check_ajax_referer)
- Luôn dùng current_user_can()
- Validate dữ liệu user input
- Escape output
- Không dùng wp_ajax_nopriv trừ khi bắt buộc
- Không xử lý dữ liệu nguy hiểm qua AJAX public
- Dùng wp_send_json() thay vì echo
- Không trả về dữ liệu nhạy cảm
Kết luận
AJAX là nơi xảy ra nhiều lỗ hổng nhất trong plugin WordPress vì developer thường quên kiểm tra quyền hoặc nonce. Chỉ một endpoint sơ suất cũng đủ để hacker xóa dữ liệu, chiếm quyền admin hoặc leak toàn bộ user. Áp dụng đúng các phương pháp trong bài này sẽ giúp bạn bảo mật toàn bộ AJAX endpoint và tránh gần như mọi rủi ro phổ biến.
Bình luận