Khởi Động Nhanh: Khóa Chặt Những Thứ Cơ Bản Trong 5 Phút
Trang đăng nhập WordPress của bạn vẫn đang ở /wp-login.php mà không có rate limiting? Bạn đang để hở cửa đấy. Tôi đã thấy các bản cài đặt mới toanh gánh tới 10.000 lần đăng nhập thất bại chỉ trong một đêm. Đây là cách ngăn chặn ngay lập tức.
Bước 1: Cài Wordfence hoặc Solid Security
Một trong hai plugin này sẽ bịt ngay 80% bề mặt tấn công của bạn. Với hầu hết trường hợp, hãy dùng Wordfence Free — nó đi kèm tường lửa thời gian thực, rate limiting đăng nhập và trình quét malware. Không cần trả phí.
Vào wp-admin → Plugins → Add New, tìm Wordfence, cài và kích hoạt. Chạy setup wizard và bật ba thứ này:
- Bảo vệ brute force (khóa tài khoản sau N lần đăng nhập sai)
- Xác thực hai yếu tố cho tài khoản admin
- Tường lửa ở chế độ Extended Protection (cần thêm một dòng vào
.htaccesshoặcphp.iniđể tải trước WordPress)
Bước 2: Đổi Tên Tài Khoản Admin
Tài khoản admin vẫn có tên admin? Kẻ tấn công đã biết một nửa thông tin đăng nhập của bạn rồi. Sửa chỉ mất hai phút: tạo một user admin mới với tên khác, đăng nhập bằng tài khoản đó, rồi xóa user admin cũ đi — chuyển bài viết của nó sang tài khoản mới khi được hỏi.
Để tạo mật khẩu, tôi dùng toolcraft.app/vi/tools/security/password-generator — chạy hoàn toàn trên trình duyệt, không gửi dữ liệu qua mạng, không gọi API, không ghi log. Điều đó quan trọng khi tạo thông tin xác thực cho hệ thống production.
Bước 3: Tắt XML-RPC Nếu Không Dùng
XML-RPC thường bị lạm dụng để khuếch đại brute force: một HTTP request có thể kiểm tra hàng trăm cặp username/password cùng lúc. Trừ khi bạn dùng WordPress mobile app hoặc Jetpack, hãy tắt nó đi.
Người dùng Apache, thêm đoạn này vào .htaccess:
<Files xmlrpc.php>
Order Deny,Allow
Deny from all
</Files>
Người dùng Nginx, thêm vào server block:
location = /xmlrpc.php {
deny all;
return 403;
}
Đào Sâu: Ngăn Chặn SQL Injection và RCE
SQLi Tấn Công WordPress Như Thế Nào
SQLi hiếm khi đến từ WordPress core — nó đến từ các plugin có lỗ hổng. Một plugin có lệnh $wpdb->query() nối trực tiếp dữ liệu người dùng nhập vào là điểm xâm nhập kinh điển. Không cần đăng nhập. Tấn công đi thẳng qua một trường form, ô tìm kiếm, hoặc REST endpoint.
Tường lửa của Wordfence kiểm tra các request đến dựa trên các pattern đã biết: UNION SELECT, OR 1=1, stacked queries, các biến thể được encode. Dựa trên signature, không hoàn hảo — nhưng nó bắt được các đợt quét tự động dò tìm mọi site công khai chỉ vài giờ sau khi ra mắt.
Giải pháp thực sự là cập nhật plugin thường xuyên. Tôi chạy lệnh này trên VPS để phát hiện bất kỳ plugin nào đang tụt hậu:
# Kiểm tra những plugin nào có bản cập nhật đang chờ
wp plugin list --update=available --format=table --path=/var/www/html
# Tự động cập nhật tất cả hàng đêm lúc 3 giờ sáng
0 3 * * * /usr/local/bin/wp plugin update --all --path=/var/www/html --quiet
Tự động cập nhật tất cả trừ những plugin bạn đã tùy chỉnh. Với những plugin đó, một nhắc nhở lịch hàng tháng là đủ.
Chặn Các Vector Tấn Công RCE
RCE tấn công WordPress qua ba con đường chính:
- Lỗ hổng tải file lên — một plugin chấp nhận mọi loại file, bao gồm cả
.php - Trình sửa theme/plugin — ai đó với thông tin đăng nhập admin bị xâm phạm chỉnh sửa PHP trực tiếp trong wp-admin
- Deserialization gadgets — hiếm gặp nhưng cực kỳ nguy hiểm trong một số kết hợp plugin nhất định
Vô hiệu hóa trình sửa file. Thêm hai dòng này vào wp-config.php:
define( 'DISALLOW_FILE_EDIT', true );
define( 'DISALLOW_FILE_MODS', true ); // Cũng chặn cài đặt plugin/theme từ wp-admin
Chặn thực thi PHP trong thư mục upload. Cấu hình Nginx:
location ~* /(?:uploads|files)/.*\.php$ {
deny all;
return 403;
}
Tương đương với Apache:
<Directory "/var/www/html/wp-content/uploads">
<Files "*.php">
Order Deny,Allow
Deny from all
</Files>
</Directory>
Tăng Cường Bảo Mật wp-config.php
Thông tin đăng nhập database, secret keys, tiền tố bảng — tất cả đều nằm trong wp-config.php. Di chuyển nó lên một thư mục phía trên web root để không thể truy cập qua HTTP:
mv /var/www/html/wp-config.php /var/www/wp-config.php
# WordPress tự động kiểm tra thư mục cấp trên — không cần thay đổi code
chmod 600 /var/www/wp-config.php
chown www-data:www-data /var/www/wp-config.php
Đồng thời hãy tạo lại salt. Truy cập https://api.wordpress.org/secret-key/1.1/salt/, sao chép output, và thay thế khối AUTH_KEY / SECURE_AUTH_KEY trong wp-config.php. Tất cả phiên đăng nhập hiện tại sẽ bị vô hiệu hóa ngay lập tức — người dùng đang đăng nhập sẽ bị đăng xuất. Đây là hành vi mong muốn sau khi nghi ngờ bị xâm phạm.
Nâng Cao: Tăng Cường Bảo Mật Cấp Server
HTTP Security Headers
Không tốn hiệu năng, bảo vệ thực sự chống clickjacking, MIME sniffing và reflected XSS. Thêm các header này vào cấu hình Nginx của bạn:
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.google-analytics.com; img-src 'self' data: https:; style-src 'self' 'unsafe-inline';" always;
Sau khi triển khai, chạy domain của bạn qua securityheaders.com. Hướng tới B+ trở lên — bất kỳ điểm nào thấp hơn đều có nghĩa là có gì đó quan trọng đang bị thiếu hoặc cấu hình sai.
Rate Limiting Ở Tầng Nginx
Tính năng chống brute force của Wordfence hoạt động ở tầng PHP — nghĩa là WordPress đã khởi động, kết nối database và tốn CPU rồi mới từ chối request đó. Hãy chặn sớm hơn:
http {
limit_req_zone $binary_remote_addr zone=wp_login:10m rate=5r/m;
server {
location = /wp-login.php {
limit_req zone=wp_login burst=3 nodelay;
limit_req_status 429;
# ... phần còn lại của cấu hình
}
}
}
Năm lần đăng nhập mỗi phút mỗi IP, burst tối đa 3. Một script tấn công 100 request mỗi giây sẽ nhận 429 trước khi PHP kịp khởi động. Nếu bạn chạy nhiều server phía sau load balancer, hãy xem thêm về distributed rate limiting với Nginx và Redis để đồng bộ counter giữa các node. Với hầu hết các cuộc tấn công shared hosting, chỉ riêng điều này đã cắt giảm 95%+ lượng nhiễu.
Quyền Database: Nguyên Tắc Đặc Quyền Tối Thiểu
Nhiều cấu hình mặc định cấp cho user WordPress DB quyền ALL PRIVILEGES. WordPress thực tế chỉ cần tám quyền: SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER và INDEX. Thu hồi tất cả phần còn lại — nguyên tắc đặc quyền tối thiểu này áp dụng ở mọi tầng, không chỉ riêng database:
REVOKE FILE, SUPER, PROCESS, RELOAD ON *.* FROM 'wp_user'@'localhost';
SHOW GRANTS FOR 'wp_user'@'localhost';
Thu hồi quyền FILE là quan trọng nhất. Nếu không có nó, kẻ tấn công dù có khai thác được SQLi cũng không thể dùng LOAD_FILE() để đọc file server hay INTO OUTFILE để cài PHP backdoor.
Kinh Nghiệm Thực Tế Từ Thực Chiến
Kiểm Tra Số Lượng Plugin
Mỗi plugin là một bề mặt tấn công. Không có ngoại lệ. Tôi từng tiếp quản các bản cài WordPress với hơn 40 plugin đang hoạt động — một nửa bị bỏ hoang, một số có CVE chưa vá suốt hai năm. Chạy lệnh này và loại bỏ bất kỳ plugin nào không có cập nhật từ năm 2022:
wp plugin list --path=/var/www/html --format=table | grep -v 'active'
Thiết Lập Giám Sát Toàn Vẹn File
Wordfence phát hiện file bị sửa đổi, nhưng kiểm tra toàn vẹn file ở tầng OS nhanh hơn và không cần plugin chạy:
# Tạo snapshot tất cả file PHP ngoài thư mục uploads
find /var/www/html -name '*.php' -not -path '*/wp-content/uploads/*' \
| sort | xargs md5sum > /root/wp_baseline.md5
# Cron kiểm tra hàng tuần
md5sum -c /root/wp_baseline.md5 2>/dev/null | grep FAILED
FAILED trong output nghĩa là một file PHP đã thay đổi kể từ khi bạn tạo snapshot. Hãy điều tra trước khi cho rằng đó là cập nhật thông thường — có thể không phải vậy.
Backup Trước Khi Tăng Cường Bảo Mật
Di chuyển wp-config.php, bật CSP headers, hay tắt XML-RPC có thể âm thầm phá vỡ các tích hợp bạn đã quên mất. Hãy luôn snapshot trước:
# Xuất bằng WP-CLI
wp db export /root/wp_backup_$(date +%Y%m%d).sql --path=/var/www/html
# Hoặc dùng mysqldump
mysqldump -u root -p wordpress_db > /root/wp_backup_$(date +%Y%m%d).sql
Theo Dõi Hoạt Động Đăng Nhập
Wordfence hiển thị các lần đăng nhập gần đây trong dashboard. Để có khả năng quan sát sâu hơn, plugin WP Activity Log — kết hợp với syslog forwarder — cho bạn một audit trail có thể tìm kiếm. Khi có sự cố lúc 3 giờ sáng, bạn cần một timeline, không phải phỏng đoán.
Bảo mật không phải là danh sách kiểm tra làm một lần rồi thôi. Đó là bảo trì liên tục. Chặn ở tầng plugin, rate limiting Nginx, hạn chế quyền database và kiểm tra hàng tháng cộng lại sẽ đưa bạn đi trước xa so với các chiến dịch tự động dò tìm mọi bản cài WordPress công khai suốt ngày đêm. Hãy bắt đầu với các bước 5 phút ngay hôm nay. Thêm cấu hình server trong tuần này. Phần còn lại có thể chờ đến cuối tuần.

