Đăng Ký Học EN

SEO WordPress #21: WordPress Hardening

Checklist 174-183 hardening WordPress: tài khoản, mật khẩu, 2FA, quyền file, directory listing, lịch vá, phân quyền, file nhạy cảm và checksum.

WordPress Hardening: tài khoản theo role, xác thực hai bước và quyền file tối thiểu
Kiểm tài khoản, phân quyền, xác thực hai bước, quyền file và toàn vẹn tệp trên chính máy chủ đang chạy website.

WordPress Hardening là giảm số đường vào của website, thu hẹp quyền của từng đường còn lại, và giữ khả năng phát hiện khi có ai đã vào được. Bài #21 chuyển tiêu chí 174-183 thành các bước kiểm tài khoản, mật khẩu, xác thực hai bước, quyền file, directory listing, lịch cập nhật, phân quyền, file nhạy cảm, thực thi PHP trong uploads và kiểm tra toàn vẹn.

Bài dành cho SEOer, người quản trị WordPress và đội vận hành cần một bộ nghiệm thu có bằng chứng. Mỗi tiêu chí đi kèm lệnh kiểm cụ thể, lỗi thường gặp, và ranh giới giữa việc thật sự giảm rủi ro với việc chỉ làm cho báo cáo trông đẹp.

1. WordPress Hardening là gì và liên quan gì tới SEO?

WordPress Hardening là bộ việc làm trên chính website và máy chủ để kẻ tấn công không có đường vào dễ, và nếu vào được thì không đi xa được, còn người quản trị thì phát hiện ra trong vài giờ chứ không vài tháng. Nó khác nhóm header ở bài trước: header là việc của phản hồi HTTP, hardening là việc của tài khoản, quyền và tệp.

Liên quan tới SEO thì nói ngay cho rõ: không tiêu chí nào trong mười tiêu chí này là tín hiệu xếp hạng. Google không thưởng cho một website có 2FA. Nhưng hậu quả khi thiếu chúng lại nằm đúng trong phần SEO không cứu được bằng nội dung.

Website bị chiếm quyền thường không bị phá cho hỏng, vì phá thì chủ website biết ngay. Nó bị dùng làm nơi đặt nội dung rác: hàng nghìn URL spam được sinh ra và lập chỉ mục, liên kết bán ra ngoài được chèn vào chính các bài đang có hạng, nội dung khác được trả cho công cụ tìm kiếm so với trả cho người dùng, và chuyển hướng chỉ bật với khách vào từ kết quả tìm kiếm trên điện thoại. Kết quả là nhãn cảnh báo trong SERP, thao tác thủ công theo chính sách chống spam, và một lượt dọn kéo dài nhiều tuần.

Đầu ra cần có: danh sách tài khoản kèm role, bảng quyền file, kết quả kiểm đối chiếu checksum, danh sách URL nhạy cảm đã kiểm trả về mã gì, và một lịch vận hành có người chịu trách nhiệm. Nền của chủ đề nằm ở mục tra cứu SEO Security và Brand Protection.

2. Checklist Hardening: 10 tiêu chí từ 174 đến 183

Mười tiêu chí dưới đây chia theo ba lớp: lớp danh tính gồm tài khoản, mật khẩu, xác thực hai bước và phân quyền; lớp tệp gồm quyền sở hữu, directory listing, file nhạy cảm và thực thi PHP; lớp vận hành gồm lịch cập nhật và kiểm tra toàn vẹn. Các nhãn trọng số dùng để ưu tiên trong dự án, không phải bảng yếu tố xếp hạng.

Tiêu chíBằng chứng đạtTrọng số
174Tài khoản quản trị riêng biệtKhông còn tài khoản dùng chung hay tên mặc địnhQuan trọng
175Mật khẩu dài và duy nhấtMỗi tài khoản một mật khẩu, không nằm trong danh sách đã lộBắt buộc
176Xác thực hai bướcBật cho mọi role có quyền xuất bản hoặc cài đặtBắt buộc
177Quyền file tối thiểuThư mục 755, file 644, wp-config chặt hơn, không có 777Bắt buộc
178Tắt directory listingMọi thư mục không trả về danh sách fileQuan trọng
179Cập nhật có thời hạnKhông thành phần nào hết hỗ trợ, có SLA cho bản váBắt buộc
180Phân quyền tối thiểuMỗi người một tài khoản, role đúng nhu cầuBắt buộc
181Chặn file nhạy cảmKhông URL nào trong danh sách trả về nội dungBắt buộc
182Chặn PHP trong uploadsTệp PHP trong uploads không được thực thiBắt buộc
183Toàn vẹn và mã độcChecksum khớp, có lịch quét và lịch đối chiếuQuan trọng

Hai công cụ làm được phần lớn phép kiểm. WP-CLI cho phần tài khoản, cập nhật và checksum; cURL cho phần tệp và thư mục. Bốn lệnh dưới đây là bộ khởi động cho một lượt nghiệm thu:

wp user list --fields=ID,user_login,roles,user_emailwp core verify-checksumswp plugin list --update=available --fields=name,version,update_versionwp plugin list --fields=name,status,update,version

Điểm cần nhớ khi đọc kết quả: mọi phép kiểm ở đây đo trạng thái tại một thời điểm, còn rủi ro thì tích lũy theo thời gian. Một website đạt cả mười tiêu chí hôm nay sẽ trượt tiêu chí 179 trong ba tuần nữa nếu không có lịch. Vì vậy mục 18 của bài là một phần của checklist, không phải phần phụ.

3. Tiêu chí 174: Tài khoản quản trị riêng biệt

Tài khoản quản trị riêng biệt nghĩa là không ai dùng chung tài khoản với người khác, và tài khoản mặc định do bản cài đặt sinh ra với tên như admin đã được đổi tên hoặc xóa. Cần nói rõ mức giá trị: tên đăng nhập không phải bí mật, nên đổi tên không phải một lớp bảo vệ.

Lý do tên đăng nhập không bí mật được: WordPress phơi tên tác giả qua trang lưu trữ của tác giả và qua endpoint người dùng của REST API, nên một lệnh đọc là có danh sách. Giá trị thật của việc đổi tên admin chỉ là giảm tiếng ồn từ các đợt dò mật khẩu tự động vốn thử đúng tên đó. Lớp bảo vệ thật vẫn là mật khẩu mạnh cộng xác thực hai bước.

Giá trị thật của việc mỗi người một tài khoản nằm ở chỗ khác và quan trọng hơn: có dấu vết. Khi ba người dùng chung một tài khoản, không nhật ký nào trả lời được ai đã đổi cấu hình, và khi một người rời dự án thì không cách nào rút quyền của riêng người đó mà không làm gián đoạn hai người còn lại.

Cách kiểm: đọc danh sách người dùng trong khu quản trị hoặc bằng WP-CLI, rồi đối chiếu từng dòng với một người thật đang làm việc. Điều kiện nghiệm thu: mỗi tài khoản ứng với đúng một người đang cần nó, không còn tài khoản tên mặc định, và không tài khoản nào đang được nhiều người dùng.

4. Tiêu chí 175: Mật khẩu dài và duy nhất

Mật khẩu đạt yêu cầu là mật khẩu riêng cho từng tài khoản, được lưu trong trình quản lý mật khẩu, không nằm trong danh sách mật khẩu đã lộ, và nếu nó là yếu tố xác thực duy nhất thì nên từ 15 ký tự trở lên. Điều KHÔNG nên làm là ép quy tắc trộn ký tự máy móc kiểu buộc có hoa, số và ký tự đặc biệt.

Lý do bỏ quy tắc trộn ký tự: hướng dẫn của NIST SP 800-63B chỉ ra rằng ép trộn ký tự khiến người dùng chọn những biến thể dễ đoán theo cùng một khuôn, trong khi độ dài mới là thứ làm tăng thật sự chi phí dò. Cùng tài liệu đó khuyến nghị bỏ việc ép đổi mật khẩu định kỳ, và thay bằng đổi khi có dấu hiệu bị lộ.

Phần đối chiếu danh sách đã lộ là phần dễ bỏ qua mà lại rẻ nhất. Một mật khẩu dài mà đã xuất hiện trong một vụ rò rỉ dữ liệu thì không còn giá trị nào, vì các đợt tấn công hiện nay thử đúng những cặp tài khoản và mật khẩu đã lộ chứ không dò ngẫu nhiên. Dịch vụ Pwned Passwords cho phép kiểm mà không gửi mật khẩu đi.

Cách kiểm trong thực tế: không thể đọc mật khẩu của người khác, nên phép kiểm ở đây là kiểm quy trình. Hỏi ba câu: mật khẩu đang lưu ở đâu, có ai dùng lại mật khẩu của dịch vụ khác không, và đã đối chiếu danh sách đã lộ chưa. Điều kiện nghiệm thu: mọi tài khoản có quyền cao đều dùng mật khẩu sinh bởi trình quản lý mật khẩu, và đã kiểm qua danh sách đã lộ.

5. Tiêu chí 176: Bật xác thực hai bước

Xác thực hai bước phải bật bắt buộc cho mọi tài khoản có quyền xuất bản, cài đặt hoặc quản lý người dùng, tức tối thiểu là Administrator và Editor, và mã phục hồi phải được lưu ở nơi an toàn. Đây là tiêu chí có tỉ lệ giảm rủi ro cao nhất trong cả bài, vì nó vô hiệu hóa toàn bộ nhóm tấn công dựa trên mật khẩu đã lộ.

WordPress không có sẵn xác thực hai bước trong bản lõi, nên phải dùng plugin. Khi chọn, hãy xét ba điểm: có ép được theo role hay chỉ cho người dùng tự bật, có hỗ trợ ứng dụng sinh mã theo thời gian thay vì chỉ gửi mã qua email, và có cho quản trị viên đặt lại cho người khác khi họ mất thiết bị.

Ép theo role là điểm quan trọng nhất. Nếu plugin chỉ cho từng người tự bật, thì sau ba tháng anh chị sẽ có một website trong đó người cẩn thận nhất đã bật và người dễ bị nhắm nhất thì chưa. Mã gửi qua email cũng yếu hơn rõ rệt, vì nếu hộp thư của người đó đã bị chiếm thì lớp thứ hai không còn là lớp thứ hai.

Một lỗ dễ bỏ sót: Application Password vẫn đăng nhập được qua API mà không đi qua lớp xác thực hai bước. Đó là thiết kế, không phải lỗi, nhưng nó nghĩa là rà soát Application Password thuộc cùng một việc với bật 2FA. Phần đó ở mục 13. Điều kiện nghiệm thu: mọi tài khoản Administrator và Editor đã bật, việc bật là bắt buộc theo role, mã phục hồi đã lưu, và danh sách Application Password đã được rà.

6. Tiêu chí 177: Quyền sở hữu và quyền file tối thiểu

Quyền file tối thiểu nghĩa là tệp thuộc đúng tài khoản dùng để triển khai, thư mục thường dùng 755 hoặc 750, tệp dùng 644 hoặc 640, và wp-config.php chặt hơn ở mức 440 hoặc 400 khi hosting cho phép. Không có trường hợp nào cần 777, và nếu một hướng dẫn nào yêu cầu 777 để chạy được thì vấn đề nằm ở quyền sở hữu chứ không ở quyền truy cập.

find . -type d -not -perm 755 -printf "%m %p\n" | headfind . -type f -not -perm 644 -printf "%m %p\n" | headstat -c "%a %U:%G %n" wp-config.php

Phần quyền sở hữu quan trọng hơn phần con số, và thường bị bỏ qua. Nếu tiến trình PHP chạy dưới đúng tài khoản đang sở hữu mã nguồn, thì mã nguồn tự ghi được lên chính nó, nên một lỗ hổng cho phép ghi tệp là một lỗ hổng cho phép sửa mã của website. Tách hai tài khoản là thứ làm chênh lệch lớn nhất, dù nó không xuất hiện trên bất kỳ báo cáo tự động nào.

Ba chỗ hay sai trên WordPress: thư mục uploads được nới quyền để sửa lỗi tải ảnh rồi không ai thu lại; thư mục cache của plugin được đặt 777 theo một hướng dẫn cũ; và wp-config.php giữ nguyên 644 nên mọi tài khoản trên cùng máy chủ dùng chung đều đọc được thông tin kết nối cơ sở dữ liệu.

Điều kiện nghiệm thu: không còn thư mục hay tệp nào ở 777, wp-config.php ở mức chặt nhất mà hosting còn chạy được, và chủ sở hữu tệp đúng tài khoản triển khai. Hướng dẫn gốc nằm ở tài liệu hardening của WordPress.

7. Tiêu chí 178: Tắt directory listing

Tắt directory listing là không cho máy chủ trả về danh sách tệp khi một thư mục được mở trực tiếp mà trong đó không có tệp chỉ mục. Thư mục cần kiểm không chỉ là uploads: còn thư mục backup, thư mục cache, thư mục tạm của plugin và mọi thư mục tùy chỉnh do đội phát triển thêm vào.

Lý do quan trọng: bản thân danh sách tệp đã là thông tin. Nó cho biết website đang dùng plugin nào và phiên bản nào, có bản backup nào đang nằm trong web root, có tệp dump cơ sở dữ liệu nào chưa xóa, và có tệp thử nghiệm nào ai đó để lại từ lần sửa lỗi trước. Đó là bước trinh sát mà kẻ tấn công làm đầu tiên, và nó miễn phí khi listing còn bật.

curl -sS -o /dev/null -w "%{http_code}\n" https://ten-mien.com/wp-content/uploads/

Cấu hình thì tùy máy chủ. Apache tắt bằng cách bỏ tùy chọn Indexes, Nginx thì mặc định đã tắt nhưng một khối cấu hình nào đó có thể đã bật lại, còn trên hosting dùng bảng điều khiển thì thường có một công tắc riêng. Kiểm bằng cURL rồi đọc mã trạng thái: mong đợi là 403 hoặc 404, không phải 200.

Điều kiện nghiệm thu: mọi thư mục trong danh sách đã kiểm đều không trả về danh sách tệp, và phép kiểm được chạy lại sau mỗi lần thêm thư mục mới hoặc đổi cấu hình máy chủ.

8. Tiêu chí 179: Cập nhật bảo mật có thời hạn

Cập nhật có thời hạn nghĩa là bản lõi, plugin và theme còn dùng đều đang nhận bản vá, bản vá nghiêm trọng được kiểm trên staging rồi triển khai trong một khoảng thời gian đã cam kết, và không thành phần nào đang ở trạng thái hết hỗ trợ. Chữ có thời hạn là phần quan trọng: không có mốc thời gian thì đây chỉ là một ý định tốt.

Cách kiểm: mở Site Health trong khu quản trị để thấy các cảnh báo về phiên bản, rồi dùng WP-CLI để có danh sách máy đọc được. Thêm một phép kiểm nữa mà Site Health không làm: tìm các plugin đã bị bỏ rơi, tức plugin còn cài nhưng tác giả không cập nhật trong nhiều năm hoặc đã bị rút khỏi thư mục. Một plugin bị bỏ rơi là một lỗ hổng sẽ không bao giờ được vá.

SLA nội bộ nên viết thành con số cụ thể theo mức nghiêm trọng, ví dụ lỗ hổng cho phép thực thi mã hoặc leo thang quyền thì xử lý trong vòng 24 giờ, các mức thấp hơn thì theo kỳ cập nhật hằng tuần. Con số cụ thể không quan trọng bằng việc có một con số, vì có con số thì mới đo được là đã trễ hay chưa.

Về staging: bắt buộc với bản cập nhật lớn, nhưng đừng để nó thành lý do trì hoãn bản vá nghiêm trọng. Với một lỗ hổng đang bị khai thác, rủi ro của việc chờ một tuần để kiểm kỹ thường lớn hơn rủi ro của việc một khối giao diện bị lệch. Điều kiện nghiệm thu: 0 thành phần hết hỗ trợ, 0 bản vá nghiêm trọng quá hạn SLA, và có bản ghi thời điểm cập nhật gần nhất.

9. Tiêu chí 180: Phân quyền theo nguyên tắc tối thiểu

Phân quyền tối thiểu nghĩa là mỗi người có tài khoản riêng và chỉ nhận đúng role cần cho việc của họ, kèm một lượt rà định kỳ các tài khoản Administrator, Editor, tài khoản cũ và Application Password không còn dùng. Nguyên tắc đơn giản: role Administrator cài được plugin, tức nó là quyền thay đổi mã đang chạy trên website.

Cách phân theo việc: người viết bài cần Author hoặc Contributor, người biên tập cần Editor, người thiết kế cần một môi trường staging chứ không cần Administrator trên production, còn đối tác bên ngoài thì nên có tài khoản riêng có thời hạn. Câu hỏi để quyết định luôn là việc của người này cần thao tác gì, không phải người này quan trọng đến mức nào.

Phần rà định kỳ mới là phần tạo ra kết quả. Trên một website vận hành vài năm, số tài khoản Administrator thường nhiều hơn số người thật sự cần, vì mỗi lần có việc gấp lại thêm một tài khoản và không ai quay lại rút. Hãy đặt một lượt rà theo quý và xử lý ba nhóm: tài khoản của người đã rời dự án, tài khoản của nhà cung cấp đã hết hợp đồng, và tài khoản không đăng nhập trong sáu tháng.

Application Password thuộc cùng lượt rà này vì mỗi mật khẩu ứng dụng là một đường vào API tồn tại độc lập với mật khẩu chính. Điều kiện nghiệm thu: danh sách Administrator ứng đúng với những người cần cài đặt và cấu hình, không tài khoản nào của người đã rời dự án còn hoạt động, và mọi Application Password đều truy được về một tích hợp đang dùng.

10. Tiêu chí 181: Chặn truy cập file nhạy cảm

Chặn file nhạy cảm nghĩa là wp-config.php, tệp .env, debug.log, tệp dump cơ sở dữ liệu, bản backup và gói ZIP đều không truy cập trực tiếp được từ web, và tốt nhất là không nằm trong web root. Đây là tiêu chí có tỉ lệ phát hiện cao nhất khi kiểm một website lần đầu, vì nó thường sai mà không ai biết.

Chỗ sai phổ biến nhất là debug.log. Khi bật ghi log lỗi, WordPress ghi vào một tệp nằm trong wp-content, và thư mục đó phục vụ qua web, nên tệp log đọc được bằng một URL. Trong log đó có đường dẫn tuyệt đối trên máy chủ, đôi khi có cả tham số truy vấn và thông tin phiên.

for f in wp-config.php .env wp-content/debug.log backup.zip db.sql; do printf "%-28s %s\n" "$f" "$(curl -sS -o /dev/null -w '%{http_code}' https://ten-mien.com/$f)"done

Chỗ sai thứ hai là bản backup. Nhiều plugin sao lưu ghi tệp vào một thư mục con của uploads với tên đoán được, và một gói backup là toàn bộ cơ sở dữ liệu kèm thông tin kết nối. Vì vậy phép kiểm không chỉ là thử vài tên tệp mà còn là crawl tìm các đuôi tệp không nên có, và quan trọng hơn là chuyển thư mục backup ra ngoài web root.

Điều kiện nghiệm thu: mọi URL trong danh sách trả về 403 hoặc 404, không có tệp đuôi sql, zip, tar hay bak nào trong web root, và ghi log lỗi được chuyển ra ngoài thư mục phục vụ web hoặc bị chặn ở lớp máy chủ.

11. Tiêu chí 182: Chặn thực thi PHP trong thư mục tải lên

Chặn thực thi PHP trong uploads nghĩa là một tệp PHP nằm trong thư mục chỉ dùng để lưu file sẽ không được máy chủ chạy, mà chỉ được trả về hoặc bị từ chối. Đây là lớp chặn cuối cùng cho cả một nhóm tấn công: mọi con đường đưa được một tệp vào uploads đều dừng lại ở đây.

Lý do cần dù đã kiểm tra loại tệp lúc tải lên: phần kiểm tra đó nằm trong mã PHP và có thể bị vượt qua theo nhiều cách, ví dụ một plugin kiểm theo phần mở rộng chứ không kiểm nội dung, hoặc một lỗ hổng cho phép ghi tệp trực tiếp không đi qua bộ kiểm tra nào. Chặn thực thi ở lớp máy chủ thì không phụ thuộc vào việc mã PHP có kiểm đúng hay không.

Cách kiểm phải đo trên hành vi thật, không đọc cấu hình. Đặt một tệp PHP vô hại vào uploads, ví dụ một tệp chỉ in ra một chuỗi, rồi mở nó bằng URL. Kết quả mong đợi là 403, hoặc là trình duyệt tải tệp về, hoặc là nội dung nguồn hiện ra dạng chữ. Kết quả KHÔNG được phép là chuỗi đó được in ra, vì như vậy là tệp đã chạy. Xóa tệp thử ngay sau khi kiểm.

Cấu hình thì khác nhau theo máy chủ: Apache chặn bằng một khối từ chối theo mẫu tên tệp đặt trong uploads, Nginx chặn bằng một khối location khớp đường dẫn uploads và đuôi php. Nhiều nền tảng hosting đã chặn sẵn, nên bước đầu luôn là kiểm chứ không phải cấu hình. Điều kiện nghiệm thu: tệp PHP thử trong uploads không thực thi, và phép kiểm được lặp lại sau mỗi lần đổi máy chủ hoặc gói hosting.

12. Tiêu chí 183: Kiểm tra toàn vẹn và mã độc

Kiểm tra toàn vẹn là định kỳ đối chiếu tệp của bản lõi và của plugin với bản gốc trên WordPress.org, theo dõi tệp thay đổi bất thường và quét mã độc. Điểm cần nhớ: cảnh báo từ bên ngoài không thay thế việc kiểm tệp trên máy chủ, vì bên ngoài chỉ thấy được phần đã bị phơi ra.

wp core verify-checksumswp plugin verify-checksums --all

Phép đối chiếu checksum là phép mạnh nhất vì nó không dựa vào việc nhận ra mã độc, nó chỉ trả lời một câu rất hẹp: tệp này có khác bản gốc hay không. Nhờ vậy nó phát hiện được cả những đoạn chèn mà không công cụ quét nào biết trước. Tài liệu lệnh nằm ở trang WP-CLI verify-checksums.

Nhưng phải biết đúng giới hạn của nó, và đây là chỗ dễ kết luận sai: phép này chỉ đối chiếu được với những gì có bản gốc công khai, tức bản lõi và plugin từ thư mục WordPress.org. Plugin và theme thương mại không có checksum để so, và toàn bộ thư mục wp-content ngoài phần plugin cũng không nằm trong checksum của bản lõi. Nói cách khác, một kết quả sạch nghĩa là phần kiểm được thì sạch.

Vì vậy cần bổ sung hai thứ: một công cụ quét mã độc cho phần không có checksum, và theo dõi thời điểm sửa tệp để bắt các thay đổi không đến từ một lần triển khai nào. Thêm một phép kiểm rẻ và rất hiệu quả: xem báo cáo Vấn đề bảo mật trong Search Console và kiểm số URL đã lập chỉ mục có tăng bất thường. Điều kiện nghiệm thu: checksum khớp, có lịch quét, và có một phép kiểm cho phần không đối chiếu được.

13. Application Password, REST API và XML-RPC

Application Password, REST API và XML-RPC là ba đường đăng nhập và truy cập không đi qua màn hình đăng nhập, nên chúng thường nằm ngoài mọi phép kiểm mà người quản trị nhớ tới. Cả ba không nên tắt hết theo phản xạ, vì nhiều tích hợp đang chạy nhờ chúng; việc cần làm là biết đường nào đang dùng và đường nào không.

Application Password là mật khẩu riêng cho một ứng dụng, cấp theo từng tài khoản. Hai điều cần nhớ: nó đăng nhập được qua API mà không đi qua lớp xác thực hai bước, và nó mang đúng toàn bộ quyền của tài khoản đã cấp. Nên một mật khẩu ứng dụng cấp từ tài khoản Administrator để chạy một việc đọc dữ liệu là đang trao quyền cài plugin cho một tích hợp chỉ cần đọc.

REST API thì mặc định phơi một số endpoint cho người chưa đăng nhập, trong đó có danh sách người dùng. Đó là lý do phần trên nói tên đăng nhập không phải bí mật. Hạn chế endpoint đó có ích ở mức giảm tiếng ồn, nhưng đừng đánh đổi bằng việc chặn cả những endpoint mà trình biên tập khối và các tích hợp đang cần.

XML-RPC thì khác: phần lớn website hiện nay không còn dùng nó, trong khi nó vẫn là đường để thử mật khẩu hàng loạt trong một request. Cách xử lý đúng là kiểm xem có gì đang dùng nó không, ví dụ ứng dụng WordPress trên điện thoại hay một công cụ đăng bài từ xa, rồi tắt nếu không có. Điều kiện nghiệm thu: mọi Application Password truy được về một tích hợp đang dùng, XML-RPC đã tắt nếu không ai dùng, và mỗi tích hợp dùng tài khoản có role thấp nhất đủ việc.

14. Sao lưu và khả năng phục hồi

Sao lưu không thuộc mười tiêu chí ở trên nhưng nó là thứ quyết định hậu quả của mọi tiêu chí bị trượt, nên một lượt hardening không nhắc tới sao lưu là một lượt chưa xong. Nguyên tắc cần nói thẳng: một bản sao lưu chưa từng được phục hồi thử thì chưa phải một bản sao lưu, nó chỉ là một tệp.

Bốn thuộc tính cần xác nhận, và cả bốn đều phải kiểm chứ không suy: bản sao lưu nằm ở nơi khác với máy chủ đang chạy website, nó không nằm trong web root, nó gồm cả cơ sở dữ liệu và cả tệp, và nó có nhiều mốc thời gian chứ không chỉ bản gần nhất. Điểm cuối quan trọng vì mã độc thường nằm im nhiều tuần, nên bản gần nhất có thể đã chứa nó.

Phép kiểm là một lần phục hồi thật lên môi trường staging, có ghi lại thời gian từ lúc bắt đầu tới lúc website chạy được. Con số thời gian đó là thứ cần báo cho chủ website, vì nó trả lời câu hỏi thật: nếu hôm nay mất sạch thì bao lâu có lại.

Đặt lịch cho phép kiểm này theo quý và gắn nó vào cùng lượt rà quyền ở mục 9. Hai việc dùng chung một dịp nên khả năng bị bỏ qua thấp hơn hẳn so với hai lịch riêng.

15. Khi website đã bị chiếm quyền: xử lý theo thứ tự nào

Thứ tự xử lý khi website bị chiếm quyền là chặn đường vào trước, dọn sau, rồi mới xin xét lại, và làm ngược thứ tự này là lý do phổ biến nhất của việc bị chiếm quyền lần thứ hai trong cùng một tháng. Dọn trước mà chưa chặn thì kẻ tấn công vào lại bằng đúng đường cũ ngay sau khi dọn xong.

Bước một, chặn và giữ bằng chứng: đổi toàn bộ mật khẩu tài khoản có quyền cao, thu hồi mọi Application Password, đổi các khóa bí mật trong wp-config.php để hủy mọi phiên đang mở, đổi mật khẩu cơ sở dữ liệu và mật khẩu truy cập máy chủ. Trước khi xóa gì, hãy lưu một bản sao nguyên trạng và một bản log truy cập, vì đó là thứ duy nhất trả lời được câu hỏi vào bằng đường nào.

Bước hai, dọn: thay bản lõi và plugin bằng bản tải mới từ nguồn gốc thay vì cố sửa từng tệp, đối chiếu checksum, tìm các tệp lạ trong uploads, tìm tài khoản quản trị mới được tạo, và kiểm cả những chỗ mã độc hay trú ngoài tệp, gồm tuỳ chọn trong cơ sở dữ liệu và tác vụ định kỳ. Kiểm thêm một chỗ đặc thù của tấn công nhắm vào SEO: một chủ sở hữu lạ được thêm vào Search Console.

Bước ba, phục hồi phía tìm kiếm: đọc báo cáo Vấn đề bảo mật trong Search Console, xác nhận đã dọn xong rồi gửi yêu cầu xét lại. Nếu website từng phát nội dung rác, hãy đối chiếu với chính sách chống spam của Google để biết phần nào cần xử lý thêm. Quan trọng: yêu cầu xét lại chỉ nên gửi khi đã chắc, vì một lần gửi khi chưa dọn sạch làm chậm toàn bộ tiến trình.

Bước bốn, đóng vòng: sau khi dọn xong, chạy lại đúng mười tiêu chí của bài này và ghi lại đường vào đã tìm được. Nếu không tìm được đường vào, hãy coi mọi tiêu chí đang trượt là ứng viên và xử lý hết.

16. Quan hệ thật giữa hardening và SEO

Trong nhóm hardening, không tiêu chí nào là tín hiệu xếp hạng, nhưng đây lại là nhóm có khả năng gây mất hạng lớn nhất trong cả series, vì nó không làm SEO giảm điểm mà làm website trở thành một website khác. Biết đúng quan hệ thật giữa hardening và SEO giúp giải thích được với chủ website mà không phải hứa điều Google chưa nói.

Phần không liên quan tới xếp hạng: 2FA, quyền file, directory listing, checksum. Google không đo chúng và không có cách nào đo được từ bên ngoài. Lý do làm chúng là giảm xác suất rơi vào phần dưới đây.

Phần gây hậu quả nặng, và đây là phần cần nói với chủ website: một website bị chiếm quyền có thể nhận nhãn cảnh báo trong kết quả tìm kiếm, bị áp thao tác thủ công theo chính sách chống spam, bị lập chỉ mục hàng nghìn URL rác đẩy trang thật xuống, bị chèn liên kết bán ra ngoài vào đúng những bài đang có hạng, và bị trả nội dung khác cho công cụ tìm kiếm so với cho người dùng. Không phần nội dung nào sửa được những chuyện đó.

Còn một hậu quả ít ai tính: thời gian. Một lượt dọn đầy đủ cộng chờ xét lại thường mất vài tuần, và trong khoảng đó website vẫn mất lưu lượng. So với chi phí bật 2FA và đặt một lịch cập nhật, đó là một tỉ lệ rất lệch. Cách nói đúng vì vậy là: hardening không mua hạng, nó là phí bảo hiểm cho phần hạng đã có. Góc nhìn rộng hơn nằm ở mục Security và Privacy Trust.

17. Ma trận kiểm tra theo lớp và công cụ

Ma trận dưới đây gom mười tiêu chí theo lớp, vì mỗi lớp có công cụ riêng và người chịu trách nhiệm riêng, nên đi theo lớp thì một lượt nghiệm thu không phải chuyển qua lại giữa khu quản trị và dòng lệnh. Cách dùng là đi hết một lớp rồi mới sang lớp kế.

LớpTiêu chíCông cụ kiểmBằng chứng lưu lại
Danh tính174, 175, 176, 180WP Admin Users, WP-CLI user listBảng tài khoản kèm role và trạng thái 2FA
Tệp và thư mục177, 178, 181, 182SSH, cURL, cấu hình máy chủKết quả find, mã trạng thái của từng URL
Vận hành179, 183Site Health, WP-CLI, công cụ quétDanh sách phiên bản, kết quả checksum
Đường API176, 180WP Admin, kiểm endpoint bằng cURLDanh sách Application Password và tích hợp
Sao lưungoài checklistMột lần phục hồi lên stagingThời gian từ lúc bắt đầu tới lúc chạy được
Phía tìm kiếmhậu quảSearch Console, số URL lập chỉ mụcẢnh chụp báo cáo Vấn đề bảo mật

Hai hàng cuối không thuộc mười tiêu chí nhưng luôn nên có trong cùng hồ sơ. Hàng sao lưu trả lời câu hỏi hậu quả xấu nhất là gì, còn hàng phía tìm kiếm là nơi hậu quả hiện ra sớm nhất khi có chuyện, thường trước khi bất kỳ công cụ nội bộ nào báo.

18. Lịch vận hành: hằng tuần, hằng tháng, hằng quý

Lịch vận hành là đầu ra cuối cùng của nhóm hardening, vì nhóm này không kết thúc bằng một lần nghiệm thu: trạng thái đạt hôm nay sẽ tự trượt khi có bản vá mới, có người mới và có tích hợp mới. Chia lịch thành ba nhịp hằng tuần, hằng tháng và hằng quý, mỗi nhịp có người chịu trách nhiệm và có bằng chứng lưu lại.

Hằng tuần, việc ngắn: đọc danh sách bản cập nhật đang chờ, triển khai nhóm không rủi ro, đọc cảnh báo của công cụ quét, và xem có tài khoản quản trị nào mới được tạo mà không ai biết. Toàn bộ mất chừng mười lăm phút nếu đã có lệnh sẵn.

Hằng tháng: đối chiếu checksum bản lõi và plugin, kiểm lại danh sách file nhạy cảm bằng cURL, kiểm lại directory listing, và soát danh sách plugin để phát hiện thành phần đã bị bỏ rơi. Đây cũng là dịp đọc số URL đã lập chỉ mục trong Search Console để bắt sớm dấu hiệu bị chèn nội dung rác.

Hằng quý: rà toàn bộ tài khoản và role, thu hồi Application Password không còn dùng, phục hồi thử một bản sao lưu lên staging, và chạy lại cả mười tiêu chí như một lượt nghiệm thu đầy đủ. Gắn lượt quý này vào cùng một dịp với việc rà quyền để giảm khả năng bị bỏ qua.

Một lưu ý về cách ghi: lưu kết quả mỗi lượt vào cùng một chỗ với lịch cập nhật theme và plugin. Giá trị của bản ghi cũ không phải để lưu trữ, mà để khi có sự cố thì trả lời được câu hỏi tuần trước nó còn đúng hay không, tức thu hẹp khoảng thời gian phải điều tra.

19. Công cụ Novaverb, tài liệu gốc và hướng thực hành

Với nhóm hardening, công cụ bên ngoài chỉ thấy được phần đã phơi ra web, nên hãy dùng chúng để rà nhanh phần đó rồi dành phần lớn thời gian cho WP-CLI và dòng lệnh trên máy chủ. Đọc đúng phạm vi báo cáo trước khi kết luận là điều kiện để không kết luận sai theo hướng an tâm.

  • Website Safety Checker của Novaverb: rà nhanh dấu hiệu website đang bị đánh dấu không an toàn, dùng làm bước sàng trước khi kiểm sâu trên máy chủ.
  • Website Security Checker của Novaverb: rà HTTPS, chứng chỉ và bộ header, tức phần đã bàn ở bài trước và vẫn nằm trong cùng hồ sơ bảo mật.
  • WP-CLI: công cụ chính cho nhóm này, gồm liệt kê người dùng, liệt kê bản cập nhật và đối chiếu checksum.
  • cURL: kiểm file nhạy cảm, directory listing và thực thi PHP trong uploads, vì nó đo đúng thứ máy chủ trả ra.
  • Công cụ quét mã độc: bù cho phần không có checksum để đối chiếu, gồm theme thương mại và phần còn lại của wp-content.

Tài liệu nên giữ trong hồ sơ dự án: hướng dẫn hardening của WordPress, NIST SP 800-63B về mật khẩu, chính sách chống spam của Googlebáo cáo Vấn đề bảo mật trong Search Console. Dùng tài liệu gốc để phân biệt quy định, khuyến nghị và quy ước nội bộ.

Nếu đang tìm lộ trình đào tạo SEO, có thể dùng checklist này làm bài thực hành: chạy bốn lệnh WP-CLI ở mục 2, kiểm danh sách file nhạy cảm bằng cURL, ghi bằng chứng rồi đặt một lịch vận hành. Trang khóa học SEO giúp đối chiếu chương trình theo nền tảng hiện tại.

Muốn đưa audit hardening vào quy trình SEO trên website thật, anh chị có thể xem phạm vi và cách học của khóa học SEO Master. Giá trị của bài thực hành nằm ở khả năng giải thích lỗi và chứng minh đã sửa bằng cùng một phép kiểm.

Kết hợp bài này với HTTPS và header bảo mật cùng mục tra cứu HTTPS và SSL Hardening: hai bài phủ hai lớp khác nhau của cùng một hồ sơ, lớp phản hồi HTTP và lớp tài khoản cùng tệp.

20. Câu hỏi thường gặp và kết luận

Các câu trả lời dưới đây giúp phân biệt tiêu chuẩn hardening, khuyến nghị gia cố và bằng chứng nghiệm thu trong WordPress. Khi gặp một kết quả không rõ, hãy quay về lớp cụ thể và tiêu chí cụ thể để chọn phép kiểm phù hợp trước khi đổi cấu hình hoặc cài thêm plugin bảo mật.

Đổi tên tài khoản admin có tăng bảo mật không?

Rất ít. Tên đăng nhập không phải bí mật vì WordPress phơi tên tác giả qua trang lưu trữ và qua REST API. Đổi tên chỉ giảm tiếng ồn từ các đợt dò tự động vốn thử đúng tên đó. Lớp bảo vệ thật là mật khẩu dài duy nhất cộng xác thực hai bước.

Có cần ép đổi mật khẩu định kỳ không?

Không nên. Hướng dẫn của NIST khuyến nghị bỏ việc ép đổi theo lịch và bỏ ép trộn ký tự, vì cả hai làm người dùng chọn biến thể dễ đoán. Thay vào đó hãy đòi mật khẩu dài, duy nhất, lưu bằng password manager, và đổi khi có dấu hiệu bị lộ.

Plugin bảo mật có thay được hardening không?

Không. Plugin giúp phát hiện và giúp bật 2FA, nhưng quyền file, quyền sở hữu, directory listing và chặn thực thi PHP trong uploads đều là việc của máy chủ, nằm ngoài tầm của plugin. Một website có plugin bảo mật nhưng wp-config.php ở 644 vẫn đang hở.

Checksum sạch nghĩa là website sạch chưa?

Chưa. Phép này chỉ đối chiếu với bản gốc công khai, tức bản lõi và plugin từ WordPress.org. Theme thương mại, plugin thương mại và phần còn lại của wp-content không có gì để so. Một kết quả sạch nghĩa là phần kiểm được thì sạch.

Có nên tắt REST API và XML-RPC không?

Hai thứ khác nhau. XML-RPC thì phần lớn website không còn dùng nên kiểm rồi tắt là hợp lý. REST API thì trình biên tập khối và nhiều tích hợp đang cần, nên tắt cả là làm hỏng chức năng; chỉ nên hạn chế endpoint cụ thể sau khi đã biết cái gì đang dùng.

Application Password có đi qua xác thực hai bước không?

Không, đó là thiết kế của nó. Mật khẩu ứng dụng đăng nhập qua API mà không cần yếu tố thứ hai, và nó mang toàn bộ quyền của tài khoản đã cấp. Vì vậy hãy cấp từ tài khoản có role thấp nhất đủ việc, và rà soát danh sách theo quý.

Hardening có giúp tăng hạng không?

Không. Không tiêu chí nào ở đây là tín hiệu xếp hạng. Nhưng website bị chiếm quyền thì mất hạng theo cách nội dung không cứu được: nhãn cảnh báo trong SERP, thao tác thủ công, hàng nghìn URL rác được lập chỉ mục và liên kết bán ra chèn vào bài đang có hạng.

Bị chiếm quyền thì làm gì trước?

Chặn đường vào trước, dọn sau, xin xét lại sau cùng. Đổi mật khẩu và khóa bí mật để hủy mọi phiên đang mở, lưu một bản nguyên trạng cùng log truy cập làm bằng chứng, rồi mới thay tệp bằng bản tải mới. Dọn trước khi chặn là lý do phổ biến nhất của việc bị chiếm quyền lần thứ hai.

Kết luận: hardening không mua thêm hạng, nó là phí bảo hiểm cho phần hạng website đã có. Kiểm đủ mười tiêu chí 174-183 theo bốn lớp, bổ sung sao lưu đã phục hồi thử, và chuyển kết quả thành một lịch hằng tuần, hằng tháng, hằng quý có người chịu trách nhiệm giúp SEO WordPress giữ được thứ đã xây thay vì phải xây lại.

Menu

Thêm vào màn hình chính

  1. 1 Bấm nút Chia sẻ ở thanh công cụ Safari
  2. 2 Kéo xuống, chọn Thêm vào MH chính
  3. 3 Bấm Thêm ở góc trên bên phải

Ba bước này là của Safari. Nếu đang xem trong ứng dụng khác thì bấm mở bằng Safari trước đã.