Thẻ logo WordPress trên nền navy cùng chữ .htaccess, móc so với bản gốc

Đừng đọc .htaccess và functions.php bằng mắt rồi đoán; hãy so với bản gốc. Một .htaccess WordPress sạch chỉ có 11 dòng, kể cả hai dòng chú thích, nên tệp dài hơn hoặc có rewrite sang tên miền lạ là đáng ngờ. Với functions.php, tải lại đúng phiên bản theme rồi chạy diff. Cả hai tệp sạch cũng chưa chứng minh site sạch.

Sao lưu rồi mới mở tệp

Sao lưu cả hai tệp và cơ sở dữ liệu trước khi sửa bất cứ dòng nào. Chỉ cần thiếu một dấu ngoặc trong functions.php là cả site trắng trang; một dòng sai trong .htaccess là lỗi 500.

Bản sao còn giúp bạn so sánh sau này và giữ bằng chứng nếu cần tìm đường vào. Quy trình đầy đủ từ sao lưu đến xin Google xét lại nằm ở bài xử lý WordPress bị chèn mã độc. Bài này chỉ đi sâu vào việc đọc hai tệp.

Ảnh chụp trang developer.wordpress.org hướng dẫn cấu hình Apache và tệp .htaccess cho WordPress
Trang hướng dẫn máy chủ web Apache và .htaccess trên developer.wordpress.org, đọc ngày 19/10/2026. Ảnh chụp trang developer.wordpress.org, 19/10/2026.

.htaccess sạch trông thế nào

Một site WordPress dùng đường dẫn tĩnh có khối mặc định gồm 11 dòng, nằm giữa hai dòng BEGIN WordPress và END WordPress. Đây là mẫu trong tài liệu của WordPress.org, bạn dùng để đối chiếu.

.htaccess · khối mặc định của WordPress
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Nội dung ngoài khối này chưa chắc là độc. Nhiều hosting tự thêm cấu hình nén, cache trình duyệt, HSTS hoặc chuyển http sang https. Dấu hiệu cần dừng lại là những dòng bạn hoặc nhà cung cấp hosting không nhận là của mình, nhất là dòng nhắc tên miền lạ.

Ba kiểu .htaccess hay bị chèn

Kẻ chèn mã thích .htaccess vì tệp này chạy trước WordPress, nên plugin bảo mật và cả quản trị viên đều khó thấy tác động. Ba mẫu dưới đây dùng tên giả evil.example và chỉ mang tính minh hoạ.

.htaccess · mẫu 1: rewrite theo nguồn truy cập
# Mẫu minh hoạ: đẩy khách đến từ công cụ tìm kiếm sang tên miền lạ
RewriteEngine On
RewriteCond %{HTTP_REFERER} (google|bing|yahoo) [NC]
RewriteRule ^(.*)$ http://evil.example/khuyen-mai [R=302,L]
.htaccess · mẫu 2: auto_prepend_file
# Mẫu minh hoạ: nạp một tệp PHP lạ trước mọi trang
php_value auto_prepend_file "/home/tai-khoan/public_html/wp-content/uploads/.cache.php"
uploads/.htaccess · mẫu 3: đuôi ảnh chạy như PHP
# Mẫu minh hoạ: đặt trong wp-content/uploads/, bắt máy chủ chạy ảnh như mã PHP
AddType application/x-httpd-php .jpg .png
Kiểu chèn Dấu hiệu Hậu quả Cách gỡ
Rewrite theo referrer hoặc user agent RewriteCond nhắc google, bing hoặc mobile, rồi RewriteRule sang tên miền ngoài Khách đến từ Google bị đẩy đi; chủ site vào thẳng thì không thấy gì Xoá cả khối lạ, trả khối WordPress mặc định
auto_prepend_file Dòng php_value trỏ vào một tệp PHP trong uploads hoặc thư mục tạm Tệp lạ chạy trước mọi trang, kể cả khi theme sạch Xoá dòng, rồi tìm và xoá tệp PHP mà nó trỏ tới
Đuôi ảnh chạy như PHP AddType hoặc AddHandler gắn x-httpd-php cho .jpg, .png Tệp ‘ảnh’ trong uploads thực chất là mã PHP Xoá tệp .htaccess trong uploads, rà mọi tệp ảnh có nội dung PHP

Nguồn: nhóm phân tích mã độc Sucuri (labs.sucuri.net, mẫu htaccess-spam-seo-prepend-001); Infinet (infinetinc.com, bài về webshell PHP giả đuôi); mục Hacked content trong chính sách spam của Google Search. Đọc ngày 19/10/2026.

Kiểu thứ nhất nguy hiểm vì khó phát hiện. Google mô tả hành vi này trong chính sách spam: nội dung hoặc đích đến thay đổi tuỳ theo nguồn truy cập, thiết bị hoặc trình duyệt. Bạn tự kiểm bằng cách mở site từ kết quả tìm kiếm trên điện thoại, không chỉ gõ thẳng tên miền.

functions.php: tìm gì và tìm thế nào

Cách nhanh nhất là tìm bốn hàm thường gặp trong mã bị che giấu: eval, base64_decode, gzinflate và str_rot13. Chạy lệnh dưới trong thư mục gốc của site, thay tên theme đang dùng, cả theme con nếu có.

Dòng lệnh · tìm hàm giải mã trong theme
grep -rnE --include="*.php" "eval\(|base64_decode\(|gzinflate\(|str_rot13\(" wp-content/themes/<ten-theme>

The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. (dịch: Cấu trúc eval() rất nguy hiểm vì cho phép chạy mã PHP tuỳ ý.)

— Tài liệu PHP, hàm eval, 17/10/2026

Đừng xoá eval và base64_decode hàng loạtKết quả grep chỉ là danh sách cần xem, chưa phải danh sách cần xoá. Có theme và plugin hợp lệ vẫn dùng base64_decode để mã hoá cấu hình hoặc ảnh nhúng. Xoá hàng loạt theo từ khoá có thể làm hỏng chính theme, trong khi mã độc đã được viết lại bằng hàm khác.

Bảng phân biệt dòng đáng ngờ và dòng hợp lệ

Hãy đọc ngữ cảnh của từng kết quả. Bảng dưới gom các dấu hiệu khi rà từng dòng grep trả về.

Dấu hiệu Thường là độc Thường là lành
Chuỗi bị giải mã eval(base64_decode('…')) với chuỗi dài hàng trăm ký tự, không đọc được Giải mã chuỗi cấu hình ngắn của plugin, có thể đọc lại được
Vị trí trong tệp Nằm ngay sau thẻ <?php đầu tệp, hoặc sau ?> cuối tệp Nằm trong hàm có tên rõ nghĩa, có chú thích của tác giả theme
Nguồn dữ liệu $_REQUEST hoặc $_POST kết hợp file_get_contents tới URL ngoài Đọc tệp cục bộ của chính theme
Điều kiện chạy Bỏ qua khi là is_404() hoặc wp-cron.php, hay chỉ chạy với khách từ Google Chạy mọi lần tải trang, hoặc chỉ ở trang quản trị
Tên và định dạng Biến một hai ký tự, một dòng rất dài, không xuống dòng Mã thụt lề, có tên hàm của chính theme

Tổng hợp từ kinh nghiệm rà mã của Net Solutions; đối chiếu bản gốc vẫn là bước quyết định.

Dòng nào vẫn chưa phân định được thì không đoán. Chuyển sang bước so với bản gốc ngay dưới đây.

So với bản gốc: cách chắc chắn nhất

Bạn không cần tự đánh giá từng dòng nếu có bản gốc để so. Lõi WordPress và plugin đăng ký trên WordPress.org có thể kiểm bằng WP-CLI. Ngày 17/10/2026, tài liệu WP-CLI chỉ có lệnh verify-checksums cho core và plugin, chưa có cho theme.

WP-CLI · kiểm tệp lõi và plugin
wp core verify-checksums
wp plugin verify-checksums --all

Với theme, bạn tải lại đúng phiên bản đang dùng từ nơi mua hoặc kho chính thức, rồi dùng diff -r. Mọi dòng chỉ có ở bản trên site đều cần được giải thích.

Dòng lệnh · so theme với bản tải lại
# Tải lại ĐÚNG phiên bản theme đang dùng, giải nén vào thư mục riêng, rồi so
diff -r wp-content/themes/<ten-theme> /duong-dan/theme-ban-goc/<ten-theme>

Theme do đơn vị khác tự viết thì không có bản gốc công khai. Khi đó bạn so với bản trong git hoặc bản sao lưu cũ chắc chắn còn sạch.

Gỡ an toàn: thay cả tệp, đừng cắt từng dòng

Thay nguyên tệp bằng bản gốc an toàn hơn xoá từng dòng, vì mã độc thường nằm ở nhiều chỗ trong một tệp. Với .htaccess, dán lại khối mặc định ở trên, rồi vào Cài đặt → Đường dẫn tĩnh → Lưu thay đổi để WordPress ghi lại đúng cấu hình.

Nếu mã tái xuất sau vài giờ hay vài ngày, tức là vẫn còn một đường vào khác chưa đóng. Làm tiếp bước 8 trong bài xử lý WordPress bị chèn mã độc, rồi đổi mật khẩu quản trị cho mọi tài khoản.

Tệp sạch chưa nghĩa là site sạch

Net Solutions từng hai lần chẩn đoán ‘cửa hậu nằm trong tệp’ và cả hai lần sai. Phép đối chiếu tệp và kiểm checksum lõi đều cho kết quả sạch, nhưng site vẫn bị chiếm. Thủ phạm là một cửa REST có tên batch, cho phép tạo quản trị viên mà không cần tệp lạ nào. Đo ngày 10/09/2026, trong 86 site có 3 site mở cửa này, và đúng 3 site đó là 3 site bị chiếm quyền.

Vì vậy, khi hai tệp đã sạch mà site vẫn lạ, hãy kiểm tài khoản quản trị mới, cửa REST và plugin lỗi thời. Một lỗ hổng chèn tệp cũng có thể là đường vào, như trong bài về lỗ hổng file inclusion.

Checksum sạch không bằng site sạchChecksum lõi sạch chỉ nói rằng tệp lõi không bị sửa. Nó không nói gì về tài khoản quản trị lạ, cơ sở dữ liệu hay tệp trong uploads.

Cũng cần nói rõ giới hạn của chúng tôi: tệp theme và .htaccess nằm ở tầng tệp, cần quyền hosting. Khi khách chưa cấp FTP hoặc SSH, Net Solutions không sửa tệp trên hosting, mà chỉ hướng dẫn đọc và kiểm bằng những gì quản trị WordPress cho phép.

Tự làm hay thuê

Bạn tự làm được khi có quyền hosting, có bản sao lưu và mã độc chỉ nằm ở một hai tệp bạn đã đối chiếu được. Nên nhờ người có kinh nghiệm khi gặp một trong các trường hợp sau.

Tình huống Hướng đi
Chỉ một hai tệp khác bản gốc, có quyền hosting và sao lưu Tự thay tệp bằng bản gốc, rồi theo dõi vài ngày
Có tệp .php lạ trong thư mục uploads Nhờ chuyên gia: đây thường là shell còn đường vào
Xoá xong, mã tái xuất Nhờ chuyên gia: còn cửa vào chưa đóng
Nhiều site cùng một máy chủ hoặc tài khoản hosting Nhờ chuyên gia: một site nhiễm có thể kéo theo các site còn lại

Tổng hợp từ kinh nghiệm xử lý site của Net Solutions, 19/10/2026.

Dịch vụ chăm sóc website của Net Solutions gồm quét bảo mật, sao lưu và phát hiện mã độc, ba mức 1.500.000đ, 2.500.000đ và 3.500.000đ mỗi tháng (giá niêm yết đọc ngày 08/10/2026). Mức nào hợp phụ thuộc số site và tần suất cập nhật của bạn, không phải mức đắt nhất mới tốt nhất.

Câu hỏi thường gặp

.htaccess WordPress sạch dài bao nhiêu dòng? Khối mặc định gồm 11 dòng, tính cả hai dòng chú thích BEGIN và END WordPress. Hosting có thể thêm cấu hình nén, cache hoặc HSTS nên tệp dài hơn vẫn có thể lành. Điều cần kiểm là mọi dòng ngoài khối đó có chủ.

base64_decode trong functions.php có chắc là mã độc không? Không chắc. Nhiều theme và plugin hợp lệ dùng hàm này để giải mã cấu hình ngắn. Đáng ngờ khi nó bọc trong eval với chuỗi dài không đọc được, nằm ngay đầu hoặc cuối tệp. Khi chưa chắc, hãy so với bản gốc của theme.

Xoá đoạn lạ rồi mã tự quay lại thì sao? Nghĩa là còn đường vào khác: tệp PHP lạ trong uploads, tài khoản quản trị mới, plugin lỗi thời hoặc mật khẩu hosting lộ. Thay tệp bằng bản gốc chưa đủ, bạn cần đóng đường vào rồi mới dọn.

Sửa .htaccess xong bị lỗi 500 thì làm gì? Khôi phục bản sao lưu vừa làm ở bước đầu. Nếu không có, dán lại khối mặc định ở trên và xoá mọi dòng khác. Lỗi 500 thường do một dòng cú pháp sai hoặc chỉ thị mà máy chủ không hỗ trợ.

Theme có kiểm checksum được không? Ngày 17/10/2026, WP-CLI chỉ có verify-checksums cho lõi và plugin, không có cho theme. Hãy tải lại đúng phiên bản theme từ nguồn chính thức rồi dùng diff -r, hoặc so với bản git, bản sao lưu cũ nếu theme tự viết.

Cần người rà giúp hai tệp này?

Net Solutions có dịch vụ chăm sóc website gồm quét bảo mật, sao lưu và phát hiện mã độc, để bạn không phải tự đọc từng dòng mã.

Xem dịch vụ chăm sóc websiteNhắn ZaloHotline 0906.207.001

Cập nhật 23/10/2026 bởi Công ty TNHH Net Solutions.

Gọi ngay Chat Zalo Messenger Facebook Hỗ trợ qua Email