Đêm 22/9/2026, WordPress Security Team bất ngờ phát hành WordPress 7.1.2 cùng bản vá bảo mật backport cho toàn bộ các nhánh cũ từ 4.7 đến 7.0. Lý do là lỗ hổng CVE-2026-87902 — Unauthenticated Path Traversal dẫn tới Local File Inclusion trong chính WordPress Core, điểm CVSS 9.2 (Wordfence chấm 8.1 High). Điểm đáng lo: kẻ tấn công không cần tài khoản, chỉ cần gửi một URL specially crafted là có thể bắt WordPress include file PHP ngoài thư mục theme, và trong điều kiện thuận lợi là RCE toàn quyền server. Trong bài này mình sẽ đi từ A đến Z: lỗ hổng hoạt động ra sao, site của bạn có nằm trong vùng nguy hiểm không, cách vá bằng WP-CLI trong 2 phút và rà dấu vết sau khi vá.
WordPress 7.1.2 vá lỗ hổng gì mà khẩn cấp vậy?
CVE-2026-87902 nằm ở hàm locate_template() của WordPress Core. Hàm này nhận tên template do phía client kiểm soát rồi resolve ra đường dẫn file trong thư mục theme, nhưng nó không kiểm tra kết quả cuối cùng có nằm trong thư mục theme hay không. Kết quả: một tên template chứa ../ có thể trỏ tới bất kỳ file .php nào readable trên server và bị include như template trang.
Vector khai thác trong core là get_page_template() — hàm xây tên file page-{$pagename}.php từ query variable pagename lấy ra từ URL và được url-decode. Nghĩa là attacker chỉ cần một request GET không xác thực, không tương tác người dùng, đánh thẳng vào trang public của bạn. Nếu theme active có thư mục top-level bắt đầu bằng page- và trên server tồn tại file PHP “hữu ích” khi bị include, attacker leo thẳng lên remote code execution.
Site của mình có thực sự nằm trong vùng nguy hiểm không?
Theo advisory chính thức, khai thác RCE thành công cần hai điều kiện cùng xảy ra. Điều kiện một: theme cha hoặc theme con đang active phải chứa thư mục top-level có tên bắt đầu bằng page-. Advisory nêu rõ các ví dụ như Twenty Twelve, Twenty Fourteen (theme legacy của chính WordPress), cùng Neve, Hestia, Sydney — đều là những theme cực phổ biến. Điều kiện hai: trên server phải có file .php readable bởi web-server account, có hành vi dùng được khi bị include. Wordfence nêu ví dụ kinh điển là pearcmd.php khi register_argc_argv=On — cấu hình mặc định của official PHP Docker image và cPanel trên PHP nhỏ hơn 8.5.
Mình khuyên bạn đừng nhìn tên theme rồi đoán “không sao đâu”. Hãy kiểm tra trực tiếp bằng lệnh, 30 giây là xong:
# Liệt kê thư mục top-level của theme đang active, xem có thư mục nào bắt đầu bằng "page-" không
THEME=$(sudo -u www-data wp theme list --status=active --field=name --path=/var/www/example.com/public_html)
ls /var/www/example.com/public_html/wp-content/themes/$THEME/ | grep '^page-'
# Tìm pearcmd.php trên server (mục tiêu include phổ biến nhất)
sudo find / -name "pearcmd.php" 2>/dev/null
# Kiểm tra register_argc_argv
php -i | grep register_argc_argvNếu cả ba lệnh đều trả kết quả trống hoặc Off thì rủi ro RCE của bạn thấp — nhưng bạn vẫn nên vá ngay, vì Local File Inclusion tự nó đã là vấn đề nghiêm trọng.
Cách vá WordPress 7.1.2 (hoặc backport) bằng WP-CLI?
Cách an toàn và nhanh nhất là dùng WP-CLI. Với site đang chạy 7.1.x, bạn chỉ cần một lệnh. Trước khi update, mình luôn đề phòng trường hợp xấu bằng cách backup thư mục core và database — mất chưa tới 1 phút với site vừa và nhỏ:
# Backup nhanh trước khi vá
cd /var/www/example.com/public_html
tar czf /backup/core_pre_712.tar.gz wp-admin wp-includes
sudo -u www-data wp db export /backup/db_pre_712.sql --path=$PWD
# Vá lên 7.1.2
sudo -u www-data wp core update --path=$PWD
# Xác nhận phiên bản
sudo -u www-data wp core version --path=$PWD
# Kỳ vọng output: 7.1.2Quan trọng: nếu site bạn đang kẹt ở nhánh cũ (4.7 đến 7.0) vì plugin hoặc theme chưa tương thích, WordPress đã phát hành backport cho mọi nhánh: 4.7.37, 4.8.32, 4.9.33, 5.0.29, 5.1.26, 5.2.28, 5.3.25, 5.4.23, 5.5.22, 5.6.21, 5.7.19, 5.8.17, 5.9.18, 6.0.16, 6.1.14, 6.2.13, 6.3.12, 6.4.12, 6.5.12, 6.6.9, 6.7.9, 6.8.10, 6.9.9, 7.0.6. Chú ý số phiên bản backport thấp hơn bản thường của nhánh đó (ví dụ 7.0.6 vá lỗ hổng nhưng vẫn là nhánh 7.0), nên đừng nhìn version string rồi tưởng mình đã vá rồi. Kiểm tra bằng:
sudo -u www-data wp core check-update --path=/var/www/example.com/public_htmlKể cả bạn đang bật auto-update core, cũng nên chạy lệnh kiểm tra phiên bản để chắc chắn update đã thực sự hoàn tất — bản vá hôm qua phát hành gấp nên vài cron job có thể chưa kịp chạy.
Vá xong rồi, làm sao rà dấu vết nếu site đã bị khai thác?
Giả định xấu nhất: site đã bị đâm trước khi bạn vá. Dấu vết khai thác loại này thường nằm trong access log dưới dạng URL pagename chứa chuỗi ../ hoặc percent-encoded (%2e%2e%2f). Chạy hai lệnh sau trên Nginx/Apache log:
# Tìm dấu path traversal qua query pagename (dạng encoded và raw)
grep -E "pagename=(.*%2e%2e|\.\./)" /var/log/nginx/access.log | head -50
# Rút gọn: đếm số request khả nghi theo IP
grep -E "pagename=(.*%2e%2e|\.\./)" /var/log/nginx/access.log \
| awk '{print $1}' | sort | uniq -c | sort -rn | headVề phía WordPress, nếu nghi ngờ RCE đã xảy ra, hãy kiểm tra file mới và user lạ bằng WP-CLI — mình đã trình bày chi tiết runbook này trong bài hướng dẫn vá WordPress 7.1.1 trước đó, bạn áp dụng y hệt. Ngoài ra hãy đối chiếu thời gian các request khả nghi với mtime của file trong wp-content/uploads — attacker sau khi có RCE gần như luôn drop backdoor vào thư mục này.
Sao lại liên tục có lỗi trong template system của WordPress?
Điều mình thấy đáng suy ngẫm hơn cả CVE này: đây là lần thứ hai trong vài tháng locate_template() và cơ chế resolve template dính chuyện. Cùng một mảng code đã được vá một lần trước đó, và lần này vẫn lọt lưới. Template system là một trong những phần cũ nhất của WordPress, thiết kế từ thời mà input từ URL được tin tưởng nhiều hơn. Như cựu trưởng nhóm security của WordPress Aaron D. Campbell từng chia sẻ — AI giờ giúp cả hai phe, kẻ tấn công quét và tìm bug nhanh hơn hẳn, đội vá cũng phải chạy nước rút. Với người quản trị site, bài học rất cụ thể: tự động cập nhật security release của WordPress Core không phải là tùy chọn nữa, kể cả với site ít ai để ý. Nếu bạn quản lý nhiều site, hãy lên lịch wp core check-update hằng ngày qua cron — mình có mẫu runbook rà soát hàng loạt trong bài rà soát 6 lỗ hổng tháng 8 bằng WP-CLI, áp dụng nguyên vẹn cho đợt này.
Kết luận: việc cần làm ngay hôm nay
Tóm lại, checklist của bạn hôm nay chỉ có ba dòng. Một, cập nhật core lên bản vá của nhánh đang chạy — 7.1.2 nếu bạn ở 7.1.x, backport tương ứng nếu ở nhánh cũ. Hai, kiểm tra theme active có thư mục page-* và server có pearcmd.php hay không để đánh giá xem mình từng ở mức rủi ro nào. Ba, quét access log tìm chuỗi ../ trong query pagename để chắc chắn chưa ai ghé thăm trước. Toàn bộ làm trong 15 phút. Nếu bạn dùng Wordfence Premium/Care/Response thì đã có firewall rule từ ngày 22/9, còn bản Free phải đợi đến 22/10 — nhưng firewall chỉ là lớp giảm rủi ro, không thay thế việc vá core. Vá đi, đừng đợi.