- IDOR là gì?
- IDOR trong WordPress: vì sao dễ mắc?
- Ví dụ IDOR thực tế trong plugin/theme
- Ví dụ 1: Xóa comment qua AJAX
- Ví dụ 2: Xem thông tin profile
- Hậu quả của IDOR
- Cách phòng tránh IDOR trong WordPress
- Luôn kiểm tra capability
- Kiểm tra ownership
- Hạn chế lộ ID nhạy cảm
- Đừng nhầm nonce là đủ
- Audit định kỳ plugin/theme
- Best practice checklist
- Kết luận
IDOR là gì?
IDOR (Insecure Direct Object Reference) xảy ra khi ứng dụng cho phép truy cập trực tiếp đến một tài nguyên (ví dụ: post ID, file ID, user ID) chỉ dựa vào tham số người dùng truyền lên, mà không kiểm tra quyền hạn. Hacker chỉ cần thay đổi ID là có thể xem, sửa, hoặc xóa dữ liệu không thuộc quyền của họ.
Ví dụ đơn giản ngoài WordPress: URL /invoice.php?id=123. Nếu không có kiểm tra, người dùng chỉ cần đổi thành id=124 để xem hóa đơn của người khác.
IDOR trong WordPress: vì sao dễ mắc?
- Post, comment, user ID là số nguyên liên tục: Hacker dễ dàng đoán ID khác.
- Plugin/theme custom endpoint: Nhiều dev viết AJAX/REST API chỉ kiểm tra nonce, quên check capability/ownership.
- Tư duy “nonce là đủ”: Nonce chỉ xác nhận request đến từ user hợp lệ, không xác nhận quyền sở hữu dữ liệu.
- Thiếu kiểm tra context: Ví dụ form edit profile chỉ cần user ID, nhưng lại không ràng buộc user hiện tại = user ID.
Ví dụ IDOR thực tế trong plugin/theme
Ví dụ 1: Xóa comment qua AJAX
// JS gọi AJAX
jQuery.post(ajaxurl, {
action: 'delete_comment',
comment_id: 123,
_ajax_nonce: myData.nonce
});
// PHP xử lý (plugin dở)
add_action('wp_ajax_delete_comment', function() {
check_ajax_referer('delete_comment');
$comment_id = intval($_POST['comment_id']);
wp_delete_comment($comment_id);
});
Vấn đề: chỉ cần là user đăng nhập (có nonce hợp lệ), hacker có thể gửi comment_id của người khác để xóa comment trái phép.
Cách fix: thêm kiểm tra quyền sở hữu và capability:
$comment = get_comment($comment_id);
if ( ! $comment ) {
wp_die('Invalid comment');
}
if ( (int) $comment->user_id !== get_current_user_id() && ! current_user_can('moderate_comments') ) {
wp_die('Not allowed');
}
wp_delete_comment($comment_id);
Ví dụ 2: Xem thông tin profile
// URL: /my-profile.php?user_id=10
$user_id = intval($_GET['user_id']);
$user = get_userdata($user_id);
echo $user->user_email;
Vấn đề: bất kỳ user nào cũng có thể đổi user_id để xem email người khác.
Cách fix: ép user ID = user hiện tại, hoặc check capability:
$current_user_id = get_current_user_id();
if ( $user_id !== $current_user_id && ! current_user_can('list_users') ) {
wp_die('Not allowed');
}
Hậu quả của IDOR
- Lộ dữ liệu nhạy cảm: Email, số điện thoại, đơn hàng, hóa đơn.
- Sửa/xóa trái phép: Bình luận, bài viết, media của người khác.
- Leo thang đặc quyền: Hacker có thể đổi role, chiếm tài khoản admin.
Cách phòng tránh IDOR trong WordPress
Luôn kiểm tra capability
Dùng current_user_can() hoặc user_can() để đảm bảo user hiện tại có quyền thao tác trên object đó.
Kiểm tra ownership
Nếu hành động chỉ áp dụng cho chính user, so sánh get_current_user_id() với user_id hoặc $post->post_author.
Hạn chế lộ ID nhạy cảm
Tránh truyền user ID/email trực tiếp trong query string. Thay bằng hash/token ngẫu nhiên.
Đừng nhầm nonce là đủ
Nonce chống CSRF, nhưng không chống IDOR. Luôn bổ sung kiểm tra quyền sở hữu/capability.
Audit định kỳ plugin/theme
Chạy pentest cơ bản: đổi tham số ID trong AJAX/REST API, xem có truy cập được dữ liệu người khác không.
Best practice checklist
- Dùng
check_ajax_referer()hoặcwp_verify_nonce()cho mọi request thay đổi dữ liệu. - Kết hợp
current_user_can()để kiểm tra role/capability. - Kiểm tra ownership: user chỉ được thao tác với dữ liệu của chính họ.
- Không phơi bày ID/email nhạy cảm qua URL public.
- Test thủ công bằng cách đổi ID trên URL/AJAX để phát hiện IDOR.
Kết luận
IDOR là một lỗ hổng “âm thầm” nhưng cực nguy hiểm trong plugin/theme WordPress. Nhiều dev nghĩ chỉ cần nonce là đủ, nhưng thực tế cần 3 lớp bảo vệ: nonce (chống CSRF) + capability (chống vượt quyền) + ownership check (chống thao túng ID). Làm đúng 3 lớp này, bạn sẽ tránh được một trong những lỗi phổ biến nhất khiến plugin bị từ chối hoặc site bị khai thác trong năm 2025.
Bình luận