XSS là gì ? Cách kiểm tra và ngăn chặn XSS hiệu quả
XSS là gì ?
Cross-site scripting (XSS) là một lỗ hổng bảo mật website cho phép kẻ tấn công can thiệp vào các tương tác mà người dùng thực hiện với một ứng dụng website có bảo mật kém. Lỗ hổng cross-site scripting thường cho phép kẻ tấn công ăn cắp thông tin như cookies, session tokens và các thông tin khác để giả mạo thành người dùng, thực hiện các hành động mà người dùng có thể làm, và truy cập bất kỳ dữ liệu nào của người dùng. Nếu người dùng có quyền truy cập cao trong ứng dụng, kẻ tấn công có thể chiếm toàn quyền kiểm soát chức năng và dữ liệu của ứng dụng website.
XSS hoạt động như thế nào?
Cross-site scripting hoạt động bằng chèn mã độc (thường là JavaScript) vào các trang web mà người dùng khác có thể truy cập. Khi người dùng truy cập vào trang có chứa mã độc, mã này sẽ được thực thi trên trình duyệt của họ, dẫn đến các hậu quả nghiêm trọng như đánh cắp dữ liệu người dùng, chiếm quyền điều khiển tài khoản hoặc thay đổi nội dung trang web.
Các loại tấn công XSS:
- Reflected XSS: Mã độc được chèn vào URL hoặc form input và phản hồi ngay lập tức cho người dùng khi họ nhấp vào một đường dẫn hoặc gửi thông tin.
- Stored XSS: Mã độc được lưu trữ vĩnh viễn trên máy chủ và sẽ được chạy mỗi khi người dùng truy cập vào trang web.
- DOM-based XSS: Tấn công lợi dụng việc thao tác trên Document Object Model (DOM) của trang web, thường không yêu cầu gửi dữ liệu tới máy chủ.
Reflected XSS
Reflected XSS là loại tấn công cross-site scripting đơn giản nhất. Nó xảy ra khi ứng dụng nhận dữ liệu từ một yêu cầu HTTP và đưa dữ liệu đó vào phản hồi ngay lập tức một cách không an toàn.
Dưới đây là một ví dụ đơn giản về lỗ hổng XSS phản chiếu:
https://nganhangxyz.com/status?message=All+is+well.
<p>Status: All is well.</p>
Ứng dụng không thực hiện bất kỳ xử lý nào khác trên dữ liệu, do đó kẻ tấn công có thể dễ dàng tạo ra một cuộc tấn công như sau:
https://ngahnagxyz.com/status?message=<script>/*+Mã+độc+ở+đây...+*/</script>
<p>Status: <script>/* Mã độc ở đây... */</script></p>
Nếu người dùng truy cập URL do kẻ tấn công tạo, mã độc của kẻ tấn công sẽ được thực thi trong trình duyệt của người dùng, trong bối cảnh phiên làm việc của người đó với ứng dụng. Lúc này, mã có thể thực hiện bất kỳ hành động nào và truy cập mọi dữ liệu mà người dùng có quyền truy cập.
Stored XSS
Stored XSS xảy ra khi một ứng dụng nhận dữ liệu từ một nguồn không đáng tin cậy và đưa dữ liệu đó vào các phản hồi HTTP sau này một cách không an toàn.
Dữ liệu có thể được gửi đến ứng dụng thông qua các yêu cầu HTTP, chẳng hạn như bình luận trên một bài viết blog, biệt danh người dùng trong phòng chat, hoặc thông tin liên hệ trong đơn đặt hàng của khách hàng. Trong những trường hợp khác, dữ liệu có thể đến từ các nguồn không đáng tin cậy khác; ví dụ, một ứng dụng webmail hiển thị tin nhắn nhận qua SMTP, một ứng dụng marketing hiển thị bài viết từ mạng xã hội, hoặc một ứng dụng giám sát mạng hiển thị dữ liệu gói tin từ lưu lượng mạng.
Dưới đây là một ví dụ đơn giản về lỗ hổng Stored XSS. Một ứng dụng bảng tin cho phép người dùng gửi tin nhắn, và tin nhắn đó được hiển thị cho những người dùng khác:
<p>Xin chào, đây là tin nhắn của tôi!</p>
Ứng dụng không xử lý dữ liệu thêm, do đó kẻ tấn công có thể dễ dàng gửi một tin nhắn tấn công những người dùng khác:
<p><script>/* Mã độc ở đây... */</script></p>
DOM-based XSS
DOM-based XSS còn gọi là DOM XSS) xảy ra khi một ứng dụng chứa mã JavaScript phía client xử lý dữ liệu từ một nguồn không đáng tin cậy một cách không an toàn, thường bằng cách ghi dữ liệu đó trở lại vào DOM.
Trong ví dụ sau, một ứng dụng sử dụng JavaScript để đọc giá trị từ một trường nhập liệu và ghi giá trị đó vào một phần tử trong HTML:
var search = document.getElementById('search').value;
var results = document.getElementById('results');
results.innerHTML = 'Bạn đã tìm kiếm: ' + search;
Nếu kẻ tấn công có thể kiểm soát giá trị của trường nhập liệu, họ dễ dàng tạo ra một giá trị độc hại khiến mã của họ được thực thi:
Bạn đã tìm kiếm: <img src=1 onerror='/* Mã độc ở đây... */'>
Trong trường hợp điển hình, trường nhập liệu sẽ được điền từ một phần của yêu cầu HTTP, chẳng hạn như tham số chuỗi truy vấn URL, cho phép kẻ tấn công thực hiện cuộc tấn công bằng cách sử dụng một URL độc hại, tương tự như XSS phản chiếu.
Cách tìm và kiểm tra lỗ hổng XSS
Phần lớn các lỗ hổng XSS có thể được tìm thấy nhanh chóng và đáng tin cậy bằng trình quét lỗ hổng web của Burp Suite .
Kiểm tra thủ công đối với XSS phản ánh và lưu trữ thường bao gồm việc gửi một số đầu vào duy nhất đơn giản (chẳng hạn như một chuỗi chữ số ngắn) vào mọi điểm vào trong ứng dụng, xác định mọi vị trí mà đầu vào đã gửi được trả về trong phản hồi HTTP và kiểm tra từng vị trí riêng lẻ để xác định xem đầu vào được chế tạo phù hợp có thể được sử dụng để thực thi JavaScript tùy ý hay không. Theo cách này, bạn có thể xác định bối cảnh mà XSS xảy ra và chọn một tải trọng phù hợp để khai thác nó.
Kiểm tra thủ công đối với XSS dựa trên DOM phát sinh từ các tham số URL bao gồm một quy trình tương tự: đặt một số đầu vào duy nhất đơn giản vào tham số, sử dụng các công cụ dành cho nhà phát triển của trình duyệt để tìm kiếm DOM cho đầu vào này và kiểm tra từng vị trí để xác định xem nó có thể khai thác được hay không. Tuy nhiên, các loại DOM XSS khác khó phát hiện hơn. Để tìm các lỗ hổng dựa trên DOM trong đầu vào không dựa trên URL (như document.cookie
) hoặc các bồn chứa không dựa trên HTML (như setTimeout
), không có cách nào thay thế cho việc xem xét mã JavaScript, có thể cực kỳ tốn thời gian. Trình quét lỗ hổng web của Burp Suite kết hợp phân tích tĩnh và động của JavaScript để tự động phát hiện các lỗ hổng dựa trên DOM một cách đáng tin cậy.
Chính sách bảo mật nội dung
Chính sách bảo mật nội dung (CSP) là một cơ chế trình duyệt nhằm mục đích giảm thiểu tác động của mã lệnh chéo trang và một số lỗ hổng khác. Nếu một ứng dụng sử dụng CSP có hành vi giống XSS, thì CSP có thể cản trở hoặc ngăn chặn việc khai thác lỗ hổng. Thông thường, CSP có thể bị bỏ qua để cho phép khai thác lỗ hổng cơ bản.
Dangling markup injection
Dangling markup injection là một kỹ thuật có thể được sử dụng để thu thập dữ liệu cross-domain trong những tình huống không thể khai thác toàn bộ cross-site scripting do bộ lọc đầu vào hoặc các biện pháp phòng thủ khác. Kỹ thuật này thường có thể được khai thác để thu thập thông tin nhạy cảm mà người dùng khác có thể nhìn thấy, bao gồm cả CSRF token có thể được sử dụng để thực hiện các hành động trái phép thay mặt cho người dùng.
Làm thế nào để ngăn chặn các cuộc tấn công XSS
Trong một số trường hợp, việc ngăn chặn tấn công chéo trang web rất đơn giản nhưng có thể khó khăn hơn nhiều tùy thuộc vào mức độ phức tạp của ứng dụng và cách ứng dụng xử lý dữ liệu do người dùng kiểm soát.
Nhìn chung, để ngăn chặn hiệu quả các lỗ hổng XSS có thể cần kết hợp các biện pháp sau:
- Lọc dữ liệu đầu vào. Tại thời điểm nhận được đầu vào của người dùng, hãy lọc càng chặt chẽ càng tốt dựa trên những gì mong đợi hoặc đầu vào hợp lệ.
- Mã hóa dữ liệu khi xuất ra. Tại thời điểm dữ liệu do người dùng kiểm soát được xuất ra trong phản hồi HTTP, hãy mã hóa dữ liệu xuất ra để tránh dữ liệu bị diễn giải thành nội dung đang hoạt động. Tùy thuộc vào ngữ cảnh xuất ra, điều này có thể yêu cầu áp dụng kết hợp mã hóa HTML, URL, JavaScript và CSS.
- Sử dụng tiêu đề phản hồi (response headers) phù hợp. Để ngăn chặn XSS trong các phản hồi HTTP không nhằm mục đích chứa bất kỳ HTML hoặc JavaScript nào, bạn có thể sử dụng tiêu đề
Content-Type
vàX-Content-Type-Options
để đảm bảo rằng trình duyệt diễn giải các phản hồi theo cách bạn muốn. - Chính sách bảo mật nội dung. Là tuyến phòng thủ cuối cùng, bạn có thể sử dụng Chính sách bảo mật nội dung (CSP) để giảm mức độ nghiêm trọng của bất kỳ lỗ hổng XSS nào vẫn xảy ra.
Những câu hỏi thường gặp về cross-site scripting
htmlentities
và ENT_QUOTES
cho ngữ cảnh HTML hoặc JavaScript Unicode escapes cho ngữ cảnh JavaScript.