Vào ngày 12/6/2026, một cuộc tấn công chuỗi cung ứng (supply chain attack) nhắm vào ba plugin WordPress phổ biến đã làm hơn 1,2 triệu website bị tiêm mã độc qua chính CDN của nhà cung cấp. OptinMonster, TrustPulse và PushEngage — ba công cụ marketing dưới ô Awesome Motive — bị kẻ tấn công chèn JavaScript độc hại vào file SDK phục vụ trên CDN. Nếu bạn đang dùng bất kỳ plugin nào trong ba cái này, bài viết này sẽ hướng dẫn mình kiểm tra, dọn dẹp và bảo vệ website từ A đến Z.
Tấn Công Chuỗi Cung Ứng WordPress Là Gì?
Tấn công chuỗi cung ứng là khi hacker không đánh thẳng vào website của bạn mà đánh vào một mắt xích trung gian — nhà cung cấp plugin, CDN, hoặc dịch vụ bên thứ ba mà website đang sử dụng. Trong trường hợp này, kẻ tấn công xâm nhập server marketing của OptinMonster thông qua lỗ hổng plugin UpdraftPlus, lấy được CDN API key, rồi sửa file JavaScript SDK ngay tại CDN edge. Website của bạn vẫn chạy plugin bản mới nhất, vẫn cập nhật đầy đủ, nhưng lại nhận mã độc từ CDN — một kịch bản mà rất ít người nghĩ tới.
Đường Tấn Công Đã Diễn Ra Như Thế Nào?
Theo báo cáo từ OptinMonster và Sansec, chuỗi sự kiện diễn ra như sau. Kẻ tấn công khai thác lỗ hổng UpdraftPlus trên website marketing của OptinMonster để lấy CDN API key. Từ đó, chúng thay đổi 5 file JavaScript SDK phục vụ cho hàng triệu website:
- a.omappapi.com/app/js/api.min.js (OptinMonster)
- a.opmnstr.com/app/js/api.min.js (OptinMonster)
- a.optnmstr.com/app/js/api.min.js (OptinMonster)
- a.trstplse.com/app/js/api.min.js (TrustPulse)
- clientcdn.pushengage.com/sdks/pushengage-web-sdk.js (PushEngage)
Mã độc được ghép vào cuối file SDK hợp lệ, nên plugin vẫn hoạt động bình thường. Nhờ vậy, quãng thời gian từ 22:17 UTC ngày 12/6 đến khi phát hiện và dọn dẹp xong vào ngày 14/6, mã độc đã chạy trên trình duyệt của hàng ngàn admin.
Mã Độc Đã Làm Gì Trên Website Của Bạn?
Đây là phần quan trọng. Mã độc không tấn công server trực tiếp. Nó chạy trong trình duyệt của chính admin — người đang đăng nhập vào wp-admin. Khi admin tải trang có nhúng SDK bị nhiễm, script kiểm tra xem có đang chạy trong môi trường thật không (tránh sandbox, crawler), có cookie wordpress_logged_in_ không, có admin bar không. Nếu đúng, nó bắt đầu hành động.
Đầu tiên, script lấy WordPress nonce hợp lệ từ trang. Với nonce này cộng với session cookie của admin, nó tạo tài khoản administrator giả mạo qua bốn phương thức: REST API, form user-new.php, AJAX, và iframe ẩn. Tài khoản mạo danh có dạng developer_api1 (email [email protected]) hoặc dev_xxxxxx / [email protected] ngẫu nhiên.
Sau khi có admin mới, script tải plugin backdoor từ server điều khiển (C2) tên miền tidio.cc, cài lên website qua /wp-admin/update.php?action=upload-plugin. Plugin này ngụy trang dưới tên “Content Delivery Helper” hoặc “Database Optimizer”, tự ẩn khỏi danh sách plugin trong admin, và cung cấp web shell chạy lệnh hệ thống qua tham số ?developer_api1_fm.
Làm Sao Biết Website Có Bị Nhiễm Không?
Bạn làm theo 5 bước kiểm tra sau là sẽ biết. Mình khuyên kiểm tra tất cả, đừng bỏ qua bước nào.
Bước 1: Kiểm tra tài khoản administrator
Chạy lệnh WP-CLI sau để liệt kê toàn bộ tài khoản có role administrator:
sudo -u www-data wp user list --role=administrator --fields=ID,user_login,user_email,user_registered --path=/var/www/thienlv.com/public_htmlTìm bất kỳ tài khoản nào có tên developer_api1, dev_ theo sau là chuỗi ngẫu nhiên, hoặc bất kỳ tài khoản nào bạn không nhận ra. Nếu tìm thấy, xóa ngay:
sudo -u www-data wp user delete <user_id> --reassign=1 --path=/var/www/thienlv.com/public_htmlLưu ý: thay <user_id> bằng ID của tài khoản mạo danh. Tham số --reassign=1 chuyển bài viết của tài khoản đó về admin ID 1.
Bước 2: Quét thư mục plugin trên server
Plugin backdoor tự ẩn khỏi danh sách trong wp-admin, nên bạn phải kiểm tra trực tiếp trên filesystem. Đăng nhập SSH vào server và chạy:
ls -la /var/www/thienlv.com/public_html/wp-content/plugins/Tìm các thư mục content-delivery-helper hoặc database-optimizer. Nếu thấy, xóa ngay:
rm -rf /var/www/thienlv.com/public_html/wp-content/plugins/content-delivery-helper/
rm -rf /var/www/thienlv.com/public_html/wp-content/plugins/database-optimizer/Bước 3: Tìm chữ ký mã độc trong codebase
Chạy lệnh grep để tìm các indicator đã được Patchstack công bố:
cd /var/www/thienlv.com/public_html
grep -rn "developer_api1_fm" wp-content/
grep -rn "developer_api1_eval" wp-content/
grep -rn "jX9kM2nP4qR6sT8v" wp-content/
grep -rn "tidio.cc" wp-content/Nếu lệnh nào trả về kết quả, website đã bị nhiễm. Ghi lại file bị nhiễm, backup lại để phân tích, rồi xóa code độc.
Bước 4: Kiểm tra access log
Tìm dấu vết tạo tài khoản mạo danh trong access log Nginx/Apache:
grep "wp-json/wp/v2/users" /var/log/nginx/access.log | grep POST
grep "user-new.php" /var/log/nginx/access.log | grep POST
grep "update.php?action=upload-plugin" /var/log/nginx/access.log | grep POSTNếu thấy request POST tạo user từ nhiều IP khác nhau trong khoảng 12-15/6/2026, đó là dấu hiệu bị khai thác.
Bước 5: Chạy Wordfence hoặc Patchstack scan
Cài Wordfence (miễn phí) hoặc Patchstack, chạy malware scan toàn site. Wordfence sẽ phát hiện các file không thuộc core WordPress và plugin gốc. Patchstack có rule chuyên biệt chặn campaign này — nếu site bạn đã cài Patchstack trước ngày 14/6, khả năng cao đã được bảo vệ.
Website Bị Nhiễm Thì Phải Làm Gì?
Nếu sau khi kiểm tra bạn phát hiện website bị nhiễm, mình khuyên làm sạch theo đúng thứ tự sau. Đừng bỏ qua bước nào, đặc biệt là bước đổi mật khẩu.
Thứ nhất, xóa toàn bộ tài khoản mạo danh và plugin backdoor như hướng dẫn ở trên. Thứ hai, đổi mật khẩu tất cả administrator ngay lập tức:
sudo -u www-data wp user update 1 --user_pass="<mật_khẩu_mới_mạnh>" --path=/var/www/thienlv.com/public_htmlThứ ba, regenerate WordPress security keys trong wp-config.php. Lấy key mới từ https://api.wordpress.org/secret-key/1.1/salt/ và thay thế toàn bộ hằng số AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY cùng bốn salt tương ứng. Việc này sẽ đăng xuất toàn bộ session hiện tại, kể cả session của kẻ tấn công.
Thứ tư, đổi database password trong wp-config.php, tạo API key mới cho mọi dịch vụ tích hợp (Stripe, PayPal, Google, SMTP). Thứ năm, chặn tên miền C2 ở tầng DNS hoặc firewall:
# /etc/hosts
84.201.6.54 tidio.cc
# Hoặc iptables
sudo iptables -A OUTPUT -d 84.201.6.54 -j DROPLàm Sao Để Không Bị Lần Nữa?
Bài học từ sự kiện này là: plugin an toàn không có nghĩa là script bên thứ ba mà plugin tải về cũng an toàn. Bạn cần kiểm soát được mọi JavaScript chạy trên website của mình. Đây là các bước phòng ngừa mà mình áp dụng cho tất cả website WordPress mình quản lý.
Đầu tiên, dùng Content Security Policy (CSP) header để giới hạn domain nào được phép tải script. Thêm vào Nginx config:
add_header Content-Security-Policy "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://a.omappapi.com https://a.opmnstr.com;" always;Khi domain CDN bị thay đổi file, CSP sẽ không giúp ích nhiều vì domain đó đã được cho phép. Nhưng nó chặn được các domain C2 không nằm trong whitelist — script không gửi được data về tidio.cc.
Thứ hai, cài Patchstack hoặc Wordfence Premium để có virtual patching và malware scan tự động. Patchstack đã chặn 271 request tạo rogue admin trong sự kiện này — chứng tỏ WAF rule hiệu quả. Thứ ba, tắt auto-update plugin nếu bạn chưa có staging. Trong trường hợp này auto-update không phải vấn đề (tấn công qua CDN không qua update), nhưng cho các vụ EssentialPlugin hay Smart Slider 3 Pro trước đó, auto-update đã cài mã độc lên hàng ngàn site trong đêm.
Thứ tư, kiểm tra định kỳ danh sách administrator và plugin mỗi tuần:
# Cron job mỗi sáng 6:00
0 6 * * * sudo -u www-data wp user list --role=administrator --fields=user_login,user_email --path=/var/www/thienlv.com/public_html | mail -s "Admin Users Report" [email protected]Có Nên Gỡ OptinMonster, TrustPulse, PushEngage?
Tính đến thời điểm mình viết bài này (27/6/2026), ba plugin đã sửa xong CDN, mã độc đã được gỡ sạch khỏi tất cả edge server. OptinMonster đã công bố incident disclosure đầy đủ. Vậy nên bạn không nhất thiết phải gỡ nếu website đã được kiểm tra sạch. Tuy nhiên, nếu bạn không dùng tích cực tính năng nào trong ba plugin này, mình khuyên gỡ luôn — mỗi plugin bên thứ ba là một-vector tấn công tiềm năng.
Nếu giữ lại, hãy vào Settings của từng plugin, kiểm tra xem file SDK đang load từ domain nào. Nếu vẫn từ các domain liệt kê ở trên, cập nhật plugin lên bản mới nhất để nhận đường dẫn SDK mới. Ngoài ra, theo dõi trang disclosure của OptinMonster để cập nhật nếu có thông tin bổ sung.
Tổng Kết
Sự kiện OptinMonster lần này cho thấy supply chain attack đang trở thành mối đe dọa nghiêm trọng với hệ sinh thái WordPress. Không chỉ plugin bị lỗi — bản thân CDN của nhà cung cấp lớn cũng có thể bị xâm nhập. Theo Patchstack, riêng nửa đầu 2026 đã có ba vụ supply chain attack lớn: EssentialPlugin (20+ plugin bị nhiễm, tháng 4), Smart Slider 3 Pro (tháng 4), và nay là OptinMonster (tháng 6). Xu hướng này đang tăng, không giảm.
Mình đánh giá sự kiện này 8/10 mức độ nghiêm trọng — 1,2 triệu site bị tiễm mã, attack chain tinh vi, khó phát hiện nếu không kiểm tra server trực tiếp. Nhưng quan trọng hơn, đây là lời nhắc: bảo mật WordPress không chỉ là cập nhật plugin. Nó là kiểm soát toàn bộ chuỗi cung ứng — từ code plugin cho đến từng file JavaScript được tải về trình duyệt của admin.
Nếu bạn đã kiểm tra theo hướng dẫn và thấy website sạch, hãy set lịch kiểm tra lại mỗi tháng. Còn nếu phát hiện bị nhiễm, làm theo bước dọn dẹp mình nêu ở trên, rồi thực hiện audit bảo mật toàn diện để đảm bảo không có lỗ hổng nào khác còn sót lại.