1. XSS (Cross-Site Scripting) là gì?
XSS (Cross-Site Scripting) là một lỗ hổng bảo mật web cho phép kẻ tấn công xâm phạm các tương tác mà người dùng thực hiện với một ứng dụng dễ bị tấn công. Nó cho phép kẻ tấn công phá vỡ chính sách xuất xứ tương tự, được thiết kế để tách biệt các trang web khác nhau với nhau.
Các lỗ hổng kịch bản chéo trang thường cho phép kẻ tấn công giả dạng người dùng nạn nhân, thực hiện bất kỳ hành động nào mà người dùng có thể thực hiện và truy cập bất kỳ dữ liệu nào của người dùng. Nếu người dùng nạn nhân có quyền truy cập đặc quyền vào ứng dụng thì kẻ tấn công có thể giành được toàn quyền kiểm soát tất cả chức năng và dữ liệu của ứng dụng.
3.Các loại tấn công XSS
Có ba loại tấn công XSS chính. Đó là:
- XSS được phản ánh , trong đó tập lệnh độc hại xuất phát từ yêu cầu HTTP hiện tại.
- XSS được lưu trữ , nơi tập lệnh độc hại đến từ cơ sở dữ liệu của trang web.
- XSS dựa trên DOM , trong đó lỗ hổng tồn tại trong mã phía máy khách chứ không phải mã phía máy chủ.
4.Bối cảnh kịch bản chéo trang.
Khi kiểm tra XSS được phản ánh và lưu trữ , nhiệm vụ chính là xác định bối cảnh XSS:
Vị trí trong phản hồi nơi dữ liệu do kẻ tấn công kiểm soát xuất hiện.
Bất kỳ xác thực đầu vào hoặc xử lý nào khác đang được ứng dụng thực hiện trên dữ liệu đó.
a.XSS giữa các thẻ HTML
Khi ngữ cảnh XSS là văn bản giữa các thẻ HTML, bạn cần cho vào một số thẻ HTML mới được thiết kế để kích hoạt việc thực thi JavaScript.
Một số cách hữu ích để thực thi JavaScript là:
<script>alert(document.domain)</script>
<img src=1 onerror=alert(1)>
b.XSS trong thuộc tính thẻ HTML
Khi bối cảnh XSS nằm trong giá trị thuộc tính thẻ HTML, đôi khi bạn có thể chấm dứt giá trị thuộc tính, đóng thẻ và giới thiệu một giá trị mới. Ví dụ:
"><script>alert(document.domain)</script>
Thông thường hơn trong tình huống này, dấu ngoặc nhọn bị chặn hoặc mã hóa, do đó dữ liệu đầu vào của bạn không thể thoát ra khỏi thẻ mà nó xuất hiện. Miễn là bạn có thể chấm dứt giá trị thuộc tính, thông thường bạn có thể giới thiệu một thuộc tính mới tạo ra ngữ cảnh có thể tạo tập lệnh, chẳng hạn như trình xử lý sự kiện.Ví dụ:
" autofocus onfocus=alert(document.domain) x="
Tải trọng ở trên tạo ra một sự kiện onfocus sẽ thực thi JavaScript khi phần tử nhận được tiêu điểm, đồng thời thêm thuộc tính autofocusđể cố gắng tự động kích hoạt sự kiện onfocusmà không cần bất kỳ tương tác nào của người dùng. Cuối cùng, nó bổ sung thêm x="để sửa chữa phần đánh dấu sau một cách duyên dáng.
Đôi khi ngữ cảnh XSS nằm trong một loại thuộc tính thẻ HTML mà chính nó có thể tạo ra ngữ cảnh có thể viết được. Tại đây, bạn có thể thực thi JavaScript mà không cần chấm dứt giá trị thuộc tính. Ví dụ: nếu ngữ cảnh XSS nằm trong thuộc tính hrefcủa thẻ neo, bạn có thể sử dụng giao thức javascript giả để thực thi tập lệnh. Ví dụ:
<a href="javascript:alert(document.domain)">
Bạn có thể gặp các trang web mã hóa dấu ngoặc nhọn nhưng vẫn cho phép bạn chèn thuộc tính. Đôi khi, những thao tác chèn này có thể thực hiện được ngay cả trong các thẻ thường không tự động kích hoạt các sự kiện, chẳng hạn như canonical tag. Bạn có thể khai thác hành vi này bằng cách sử dụng khóa truy cập và tương tác của người dùng trên Chrome. Phím truy cập cho phép bạn cung cấp phím tắt tham chiếu đến một phần tử cụ thể. Thuộc tính accesskey này cho phép bạn xác định một chữ cái mà khi được nhấn kết hợp với các phím khác (các phím này khác nhau trên các nền tảng khác nhau), sẽ khiến các sự kiện xảy ra.
c.XSS vào JS
Khi bối cảnh XSS là một số JavaScript hiện có trong phản hồi, rất nhiều tình huống có thể phát sinh, với các kỹ thuật khác nhau cần thiết để thực hiện khai thác thành công.
1.Chấm dứt tập lệnh hiện có
Trong trường hợp đơn giản nhất, có thể chỉ cần đóng thẻ script chứa JavaScript hiện có và giới thiệu một số thẻ HTML mới sẽ kích hoạt việc thực thi JavaScript. Ví dụ: nếu bối cảnh XSS như sau:
<script>...var input = 'dữ liệu có thể kiểm soát ở đây';...</script>
thì bạn có thể sử dụng tải trọng sau để thoát khỏi JavaScript hiện có và thực thi mã của riêng mình:
</script><img src=1 onerror=alert(document.domain)>
Lý do điều này hoạt động là vì trình duyệt trước tiên thực hiện phân tích cú pháp HTML để xác định các thành phần trang bao gồm các khối tập lệnh và chỉ sau đó mới thực hiện phân tích cú pháp JavaScript để hiểu và thực thi các tập lệnh được nhúng. Tải trọng ở trên khiến tập lệnh gốc bị hỏng, với một chuỗi ký tự bị hủy bỏ. Nhưng điều đó không ngăn cản việc phân tích cú pháp và thực thi tập lệnh tiếp theo theo cách thông thường.
2.Thoát khỏi chuỗi JavaScript
Trong trường hợp ngữ cảnh XSS nằm trong chuỗi ký tự được trích dẫn, thường có thể thoát ra khỏi chuỗi và thực thi JavaScript trực tiếp. Điều cần thiết là phải sửa tập lệnh theo ngữ cảnh XSS, vì bất kỳ lỗi cú pháp nào ở đó sẽ ngăn toàn bộ tập lệnh thực thi.
Một số cách hữu ích để thoát khỏi chuỗi ký tự là:
'-alert(document.domain)-'
';alert(document.domain)//
3.Sử dụng mã hóa HTML
Khi ngữ cảnh XSS là một số JavaScript hiện có trong thuộc tính thẻ được trích dẫn, chẳng hạn như trình xử lý sự kiện, thì có thể sử dụng mã hóa HTML để xử lý một số bộ lọc đầu vào.
Khi trình duyệt đã phân tích cú pháp các thẻ và thuộc tính HTML trong phản hồi, nó sẽ thực hiện giải mã HTML các giá trị thuộc tính thẻ trước khi chúng được xử lý thêm. Nếu ứng dụng phía máy chủ chặn hoặc loại bỏ một số ký tự nhất định cần thiết để khai thác XSS thành công, bạn thường có thể bỏ qua xác thực đầu vào bằng cách mã hóa HTML các ký tự đó.
Ví dụ: nếu bối cảnh XSS như sau:
<a href="#" onclick="... var input='dữ liệu có thể kiểm soát ở đây'; ...">
và ứng dụng chặn hoặc thoát các ký tự trích dẫn đơn, bạn có thể sử dụng tải trọng sau để thoát khỏi chuỗi JavaScript và thực thi tập lệnh của riêng mình:
'-alert(document.domain)-'
Trình tự ' là một thực thể HTML biểu thị dấu nháy đơn hoặc dấu nháy đơn. Bởi vì trình duyệt HTML giải mã giá trị của thuộc tính onclick trước khi JavaScript được diễn giải nên các thực thể được giải mã dưới dạng dấu ngoặc kép, trở thành dấu phân cách chuỗi và do đó cuộc tấn công thành công.
4.XSS trong mẫu chữ JavaScript
Các ký tự mẫu của JavaScript là các ký tự chuỗi cho phép các biểu thức JavaScript được nhúng. Các biểu thức nhúng được đánh giá và thường được nối vào văn bản xung quanh. Các chữ mẫu được gói gọn trong dấu backticks thay vì dấu ngoặc kép thông thường và các biểu thức nhúng được xác định bằng ${...}cú pháp.
Ví dụ: tập lệnh sau sẽ in thông báo chào mừng bao gồm tên hiển thị của người dùng:
document.getElementById('message').innerText = `Welcome, ${user.displayName}.`;
Khi ngữ cảnh XSS ở dạng chữ mẫu JavaScript, thì không cần phải chấm dứt nghĩa đen. Thay vào đó, bạn chỉ cần sử dụng ${…}cú pháp để nhúng một biểu thức JavaScript sẽ được thực thi khi xử lý nghĩa đen. Ví dụ: nếu bối cảnh XSS như sau:
<script>...var input = `dữ liệu có thể kiểm soát ở đây`;...</script>
thì bạn có thể sử dụng tải trọng sau để thực thi JavaScript mà không cần chấm dứt nghĩa đen của mẫu:
${alert(document.domain)}
d.XSS thông qua việc chèn mẫu phía máy khách
Một số trang web sử dụng khung mẫu phía máy khách, chẳng hạn như AngularJS, để hiển thị động các trang web. Nếu họ nhúng thông tin đầu vào của người dùng vào các mẫu này theo cách không an toàn, kẻ tấn công có thể chèn các biểu thức mẫu độc hại của riêng họ để khởi động một cuộc tấn công XSS.
