Published on

Hạn chế malware chuyển hướng website WordPress với CSP

Authors

Đây là một malware, hay virus, hay shell gì đó tùy theo cách bạn gọi, và loại malware này cực kì phổ biến hiện nay. Nó gây khó chịu cho người dùng và các chủ nhân các website vì liên tục chuyển hướng website người dùng sang các website lừa đảo, bạo lực, khiêu dâm,...

Bài viết này không giúp các bạn loại bỏ malware, nó chỉ giúp malware bị hạn chế thực thi, giúp website không bị chuyển hướng nữa thôi. Điều này giúp bạn có thêm thời gian để loại bỏ malware mà không ảnh hưởng đến khách hàng.

Bài viết vẫn dài như cách mình hay viết, bạn có thể bỏ qua và chuyển tới phần hướng dẫn bằng cách nhấn vào đây.

Nguyên nhân

Nguyên nhân mình thấy rõ ràng nhất đó là sử dụng theme/plugin không rõ nguồn gốc. Đây là loại tài nguyên được chia sẻ trên internet rất nhiều nhưng không ai đảm bảo người chia sẻ sở hữu bản gốc từ tác giả, hoặc họ không chỉnh sửa gì đó trước khi chia sẻ.

Đồng ý rằng các theme/plugin trên WordPress.org không thể an toàn 100% nhưng việc sử dụng những theme/plugin không rõ nguồn gốc, trả phí được share miễn phí hay mua qua trung gian với giá rẻ bèo thì thật khó tránh khỏi.

Thủ thuật này mình sử dụng response header Content-Security-Policy 🔗 đang được hỗ trợ bởi rất nhiều trình duyệt 🔗 hiện đại ngày nay. Nói đơn giản, CSP hoạt động như một whitelist (danh sách cho phép) quy định những domain nào, giao thức nào có thể được tải trên trang hiện tại. Những domain không nằm trong whitelist này sẽ bị từ chối tải, từ đó mã độc sẽ khó được thực thi hơn.

Nhờ header CSP được trả về từ server của website, trình duyệt từ chối tải các tài nguyên như JS, CSS, hình ảnh từ cách nguồn không tin cậy và nằm ngoài whitelist.

Vậy có liên quan gì đến malware chuyển hướng không?

. Khi nhận được website từ khách hàng, mình nhận thấy có rất nhiều request lạ, yêu cầu tải những đoạn mã JS từ những tên miền khác làm cho trình duyệt chuyển hướng sang trang khác. Khi sử dụng CSP, những domain xấu hoàn toàn nằm ngoài whitelist, đảm bảo trình duyệt không tải và không bị chuyển hướng dù rằng đoạn mã JS vẫn còn đó.

true

Click vào hình để xem lớn hơn. Tất cả đều bị chặn lại với Status (blocked:csp)

Bài viết này bao gồm hai cách để khắc phục, mình luôn khuyên các bạn sử dụng cách thứ hai vì sẽ bảo đảm an toàn hơn. Tuy vậy thì cách làm rất đơn giản, bạn tự tin nhé.

true

Click vào hình để xem lớn hơn. Những domain lạ bị chặn lại và không được load, vì vậy website vẫn có thể truy cập "bình thường" dù rằng malware vẫn còn đó.

Hướng dẫn

Có 2 cách chính để chèn header Content-Security-Policy vào response của website nhưng mình khuyên nếu có thể, hãy chèn vào cài đặt của webserver (Apache, Nginx,...) thay cho PHP vì hacker vẫn có thể vô hiệu hóa đoạn mã của chúng ta đi.

Triển khai bằng PHP

Chèn đoạn script bên dưới vào cuối tập tin functions.php của theme mà bạn đang dùng, sau đó tận hưởng thành quả.

<?php  
  
function header_csp_generate(){  
    header("Content-Security-Policy: script-src 'self' 'unsafe-inline' 'unsafe-eval' www.googletagmanager.com connect.facebook.net www.googleadservices.com www.google-analytics.com googleads.g.doubleclick.net onesignal.com tpc.googlesyndication.com");  
}  
add_filter('wp_head', 'header_csp_generate');

Triển khai trên Webserver

Đây là cách mình khuyên dùng, một bởi vì hacker khó có thể can thiệp làm thay đổi giá trị này đi, hai bởi vì bạn có thể chèn vào cấu hình của các webserver, bảo đảm tất cả các trang trên server đều được triển khai header này ngay lập tức.

Nginx

Chèn vào tập tin /etc/nginx/nginx.conf, đặt trong block http, sau đó restart lại Nginx.

http {  
    # ....  
    add_header Content-Security-Policy "script-src 'self' 'unsafe-inline' 'unsafe-eval' www.googletagmanager.com connect.facebook.net www.googleadservices.com www.google-analytics.com googleads.g.doubleclick.net onesignal.com tpc.googlesyndication.com;";  
    # ....  
}

Apache

Với apache có thể đơn giản hơn, bạn chỉ việc chèn vào tập tin .htaccess (vẫn khuyên không nên vì hacker có thể can thiệp, nếu không còn cách nào khác, hãy chmod hợp lý trước khi dùng) là được, hoặc chèn vào /etc/httpd/conf/httpd.conf. Sau đó restart lại Apache.

Header set Content-Security-Policy "script-src 'self' 'unsafe-inline' 'unsafe-eval' www.googletagmanager.com connect.facebook.net www.googleadservices.com www.google-analytics.com googleads.g.doubleclick.net onesignal.com tpc.googlesyndication.com;";

Đọc thêm

#1

CSP là một danh sách cho phép các domain được tải trên website của bạn, vì vậy, nếu bạn sử dụng ứng dụng hay CDN nào đó (uhchat, Google Analytics, CDNJS,...) tải các tập tin JS từ bên ngoài, bạn bắt buộc phải thêm mới vào để ứng dụng đó có thể hoạt động được.

Script của mình ở phần trên đã bao gồm Google Tag Manager, Google Analytics, Facebook Pixel, Google Ads Tracking Code. Nếu bạn thấy thiếu thì có thể thêm vào vào. Cách thêm rất đơn giản, mỗi domain cách nhau một dấu trắng (space). Đơn giản vậy thôi.

#2: Làm sao để biết có script nào đó bị chặn?

Bạn có thể mở Developer Console của Google Chrome, chuyển qua tab Console để kiểm tra xem có script nào bị chặn hay không. Trong ví dụ này, mình chưa thêm gist.github.com vào whitelist nên bị chặn.

true

Click vào để xem ảnh lớn hơn.

#3

Domain và subdomain được đối xử khác nhau. Nếu bạn điền www.google.com 🔗 thì tất cả đoạn script trên google.com sẽ không hoạt động được. Vì vậy, bạn có thể dùng *.google.com để thêm tất cả subdomain của Google vào whitelist.

#4: Có dùng được với Cloudflare không?

Được, dùng bình thường. Cloudflare giữ lại các header này.

Còn cập nhật...

Kết

Mong rằng hướng dẫn của mình giúp các bạn thở phào nhẹ nhõm. Tuy nhiên, mình xin nhắc lại malware vẫn còn đó, chỉ là nó đã bị ngăn chặn thực thi thôi.

Mình đang lo rằng trong những phiên bản mới của malware, nó sẽ sử dụng inline JS, từ đó khiến đoạn script bảo vệ trở nên vô hiệu.