Nếu site WordPress của bạn dùng Elementor Pro và có form cho phép khách tải file lên (đơn xin việc, đính kèm ảnh, hóa đơn…), bạn đang nằm trong nhóm nguy hiểm cao. Đầu tháng 8/2026, Patchstack công bố lỗ hổng CVE-2026-32475 trong module Forms của Elementor Pro, cho phép người dùng chưa đăng nhập upload file PHP trực tiếp lên thư mục public và chiếm quyền điều khiển toàn bộ server, với điểm CVSS lên tới 9.0. Trong bài này, mình sẽ đi từng bước kiểm tra site có bị ảnh hưởng không, vá đúng cách, và rà soát dấu vết tấn công nếu site bạn đã lọt tầm ngắm.
Lỗ hổng Elementor Pro CVE-2026-32475 hoạt động như thế nào?

Điểm mấu chốt nằm ở file modules/forms/fields/upload.php của Elementor Pro phiên bản 4.2.1 trở xuống. Khi form có trường File Upload được gửi lên, plugin xử lý file qua hai vòng lặp riêng biệt: một vòng kiểm tra phần mở rộng file, một vòng di chuyển file vào thư mục wp-content/uploads/elementor/forms/. Vấn đề là hai vòng này xử lý “entry rỗng” theo hai cách khác nhau — vòng kiểm tra dùng return (thoát hẳn cả hàm), vòng di chuyển chỉ dùng continue (bỏ qua entry đó rồi chạy tiếp).
Kẻ tấn công chỉ cần gửi một request nhiều phần (multipart) chứa hai file cho cùng một field: phần đầu để trống, phần hai là file .php độc hại. Vòng kiểm tra gặp entry rỗng ở phần đầu thì thoát ra trước khi kịp đọc file PHP phía sau, trong khi vòng di chuyển vẫn chạy tiếp và ghi file PHP vào thư mục public. Từ đó, attacker chỉ cần truy cập trực tiếp đường dẫn file là thực thi mã từ xa (RCE) mà không cần tài khoản, không cần nonce, không cần cookie.
Site nào đang nằm trong diện bị tấn công?
Điều kiện duy nhất để site bị khai thác là có ít nhất một trang đã publish chứa Form widget của Elementor Pro kèm trường File Upload. Đây là cấu hình cực kỳ phổ biến: form ứng tuyển việc làm, form yêu cầu đính kèm CMND hoặc ảnh, form ticket hỗ trợ. Chú ý là trường File Upload mặc định để chế độ “không bắt buộc” (Required tắt), nên kể cả site đã tinh chỉnh kỹ cũng khó thoát nếu đang dùng phiên bản cũ.
Các giá trị cần cho request tấn công — post_id, form_id, tên field — đều hiển thị ngay trong HTML của trang công khai. Endpoint nhận upload là AJAX action elementor_pro_forms_send_form, hoạt động hoàn toàn không cần xác thực. Tóm lại: mọi tham số cần thiết đều nằm trong HTML mà bất kỳ ai cũng xem được.
Cách kiểm tra phiên bản Elementor Pro đang chạy?
Bạn kiểm tra bằng một trong hai cách sau. Cách 1, vào WordPress dashboard, mở Plugins → Installed Plugins, tìm dòng Elementor Pro và nhìn cột Version. Cách 2, nếu bạn quản lý nhiều site và quen dòng lệnh, dùng WP-CLI cho nhanh:
sudo -u www-data wp --path=/var/www/thienlv.com/public_html plugin list --status=active | grep -i elementorNếu phiên bản hiển thị là 4.2.1 trở xuống, site bạn đang bị lỗ hổng này và cần vá ngay lập tức. Nếu bạn không thấy plugin này nhưng site vẫn có form tải file, hãy kiểm tra thêm các plugin form khác — mình đã từng viết chi tiết về lỗ hổng file upload tương tự ở Forminator Forms CVE-2026-15748, tình trạng này khá phổ biến trong hệ sinh thái plugin form của WordPress.
Cách vá lỗ hổng Elementor Pro an toàn từng bước?
Bước 1 — Backup đầy đủ trước khi động vào bất cứ thứ gì: cả database lẫn thư mục wp-content. Plugin form mà lỗi mid-update rất khó gỡ rối nếu không có bản sao lưu.
Bước 2 — Cập nhật Elementor Pro lên 4.2.2 hoặc mới hơn. Vì đây là plugin trả phí, bạn phải cập nhật qua dashboard (nếu license còn hiệu lực) hoặc tải bản mới từ trang tài khoản Elementor rồi upload thủ công. Nếu license đã hết hạn, đây là lúc cần cân nhắc gia hạn — với CVSS 9.0 không khai thác được, chi phí gia hạn rẻ hơn nhiều so với dọn site bị deface.
Bước 3 — Nếu bạn không dùng trường File Upload ở form nào cả, hãy tắt hẳn nó đi như một lớp phòng thủ bổ trợ. Đồng thời kiểm tra và xóa các file rác trong thư mục upload của form:
# Liệt kê toàn bộ file đã được upload qua form Elementor
ls -la wp-content/uploads/elementor/forms/ | awk '{print $9}' | grep -E '\.(php|phtml|php[0-9]|pht|shtml)$'
# Nếu phát hiện file PHP khả nghi, backup cách ly rồi xóa
mkdir -p /root/quarantine-2026-09-08
mv wp-content/uploads/elementor/forms/<file_kha_nghi>.php /root/quarantine-2026-09-08/Bước 4 — Chặn thực thi PHP trong thư mục uploads bằng web server. Với Nginx, thêm vào server block:
location ~* ^/wp-content/uploads/.*\.(php|php5|phtml|pht)$ {
deny all;
}Với OpenLiteSpeed/Apache, dùng file .htaccess đặt tại wp-content/uploads/.htaccess:
<FilesMatch "\.(php|php5|phtml|pht|shtml)$">
Require all denied
</FilesMatch>Lớp chặn này không vá gốc lỗi nhưng khiến file PHP dù có lọt vào uploads cũng không chạy được — mình luôn áp dụng cho mọi site mình quản trị, bất kể plugin đã vá chưa.
Làm sao biết site đã bị khai thác trước đó?
File độc sau khi upload được lưu với tên dạng <uniqid>.php — 13 ký tự hex sinh từ hàm uniqid() của PHP (8 ký tự mã hóa giây, 5 ký tự mã hóa microsecond). Đây là chi tiết quan trọng khi rà soát: bạn cần tìm trong access log các request POST tới admin-ajax.php với action elementor_pro_forms_send_form, sau đó đối chiếu timestamp với các request GET đến file .php bất thường trong /uploads/elementor/forms/:
grep 'elementor_pro_forms_send_form' /var/log/nginx/access.log | grep -v ' 200 '
find wp-content/uploads/elementor/forms/ -name '*.php' -newer /path/to/mark-file -lsNgoài ra hãy kiểm tra tài khoản admin lạ, cron event khả nghi, và file .php mới xuất hiện ở các thư mục bất thường khác. Nếu bạn muốn quy trình rà soát tổng thể hơn sau các đợt lỗ hổng, tham khảo runbook 10 phút bằng WP-CLI mà mình từng chia sẻ — áp dụng nguyên vẹn cho trường hợp này.
Nếu phát hiện dấu hiệu bị khai thác thật sự, hãy coi như toàn bộ server đã mất kiểm soát: đổi toàn bộ mật khẩu, regenerate key trong wp-config.php, cài lại WordPress core từ bản sạch, và khôi phục từ backup trước thời điểm tấn công. Trường hợp GiveWP dính lỗi RCE CVSS 10.0 mới đây mà mình viết hướng dẫn khắc phục tại đây cũng xử lý theo đúng nguyên tắc này.
Có nên dùng tường lửa ứng dụng (WAF) làm lớp bảo vệ thêm?
Có, và mình khuyên dùng luôn. Lỗ hổng kiểu này khai thác qua request AJAX công khai, nên các WAF như Cloudflare (có rule chặn upload PHP qua form) hoặc Patchstack (hãng đã phát hành rule mitigate cho chính CVE này) đều chặn được ở tầng network trước khi request chạm tới plugin. WAF không thay thế việc cập nhật plugin, nhưng nó là lớp đệm quý giá trong khoảng thời gian từ khi lỗ hổng được công bố đến khi bạn kịp vá — đặc biệt với đội ngũ quản trị nhiều site như chúng ta.
Một số câu hỏi thường gặp
Bản miễn phí Elementor có bị ảnh hưởng không? Không. Lỗ hổng nằm ở module Forms của bản Pro. Tuy nhiên nếu bạn chạy cả hai thì vẫn nên cập nhật đủ để tránh các lỗi khác.
Site không có form nào dùng File Upload thì sao? Rủi ro khai thác trực tiếp gần như bằng không, nhưng mình vẫn khuyên cập nhật lên 4.2.2+ và giữ nguyên layer chặn PHP ở uploads, vì nội dung site có thể thay đổi bất cứ lúc nào.
Kẻ tấn công làm sao biết tên file đã upload? Hàm uniqid() sinh tên theo thời gian chứ không ngẫu nhiên, nên attacker có thể brute-force rất rẻ bằng chính timestamp từ response header của server. Đây cũng là lý do việc chặn thực thi PHP ở uploads quan trọng hơn cả việc “giấu” file.
Kết luận
CVE-2026-32475 là minh điển hình cho việc một bug logic tưởng chừng nhỏ — khác nhau duy nhất giữa return và continue — lại dẫn tới RCE không cần xác thực trên hàng triệu site dùng Elementor Pro. Việc của bạn khá gọn: kiểm tra phiên bản, cập nhật lên 4.2.2 trở lên, rà thư mục uploads/elementor/forms/ tìm file PHP lạ, và thiết lập chặn thực thi PHP ở uploads nếu chưa có. Làm cả bốn việc này trong chưa đến 30 phút nhưng giúp bạn ngủ ngon hơn nhiều giữa mùa lỗ hổng dày đặc như hiện nay.
