III. DOM-based XSS
DOM-based XSS có lẽ là dạng lỗ hổng đầu tiên chúng ta có thể nghĩ tới khi nhắc đến các lỗ hổng dựa trên DOM. Trong chuỗi bài viết XSS chúng ta đã phân tích khá kỹ về dạng lỗ hổng này, bạn đọc có thể tham khảo lại.
IV. DOM-based Open redirection
Xem xét đoạn mã javascript:
let url = /https?:\/\/.+/.exec(location.hash);
if (url) { location = url[0];
}
location.hash
lấy giá trị bắt đầu từ ký tự #
cho tới kết thúc URL.
/https?:\/\/.+/.exec(location.hash)
kiểm tra giá trị location.hash
có thỏa mãn biểu thức chính quy /https?:\/\/.+/
hay không, nếu có sẽ gán vào biến url
là tập các cặp giá trị dạng key-value:
Cuối cùng sử dụng location
chuyển hướng tới giá trị của url[0]
. Nên chúng ta có thể chuyển hướng nạn nhân tới website bất kỳ khi đưa URL đích nằm phía sau ký tự #
.
Phân tích bài lab DOM-based open redirection
Quan sát source trong các bài post, nhận thấy đoạn mã Javascript xử lý hành động Back to blog trong sự kiện onclick
<a href='#' onclick='returnUrl = /url=(https?:\/\/.+)/.exec(location); location.href = returnUrl ? returnUrl[1] : "/"'>Back to Blog</a>
Biến returnUrl
nhận giá trị là phép so khớp biểu thức chính quy /url=(https?:\/\/.+)/
trong location
. Nếu thành công tìm được chuỗi khớp sẽ chuyển hướng đến returnURL[1]
, ngược lại trở về thư mục /
.
Như vậy chúng ta chỉ cần thay đổi URL để khớp với cú pháp biểu thức chính quy /url=(https?:\/\/.+)/
là sẽ có thể thay đổi đích chuyển hướng. Hai cách đơn giản là thêm tham số url=https://google.com hoặc sử dụng flag #url=https://google.com
:
Chúng ta cần lưu ý một số sinks có thể dẫn tới lỗ hổng DOM-based Open redirection:
location
location.host
location.hostname
location.href
location.pathname
location.search
location.protocol
location.assign()
location.replace()
open()
element.srcdoc
XMLHttpRequest.open()
XMLHttpRequest.send()
jQuery.ajax()
$.ajax()
Bài lab luyện tập thêm từ Portswigger: https://portswigger-labs.net/dom-invader/testcases/augmented-dom-click-location-replace/
V. DOM-based Cookie manipulation
Khi lập trình viên sử dụng Javascript để thay đổi một phần giá trị của Cookie có thể tồn tại rủi ro nếu attacker cũng có thể thao tác một phần giá trị - cookie manipulation.
Xét ví dụ đoạn mã Javascript thực hiện ghi dữ liệu vào cookie:
document.cookie = 'cookieName=' + location.hash.slice(1);
location.hash.slice(1)
chính là giá trị nằm phía sau ký tự #
trong URL, người dùng có thể thay đổi được:
Phân tích bài lab DOM-based cookie manipulation
Truy cập vào bài viết bất kỳ, quan sát source code nhận thấy đoạn mã Javascript ghi giá trị lastViewedProduct
trong Cookie:
<script> document.cookie = 'lastViewedProduct=' + window.location + '; SameSite=None; Secure'
</script>
lastViewedProduct
nhận giá trị là URL của sản phẩm gần nhất chúng ta truy cập. Do window.location
là một yếu tố chúng ta có thể điều khiển giá trị được nên đoạn mã tồn tại lỗ hổng Cookie manipulation có thể khai thác ở đây.
DOM thay đổi cấu trúc HTML trong source code, có thể thực hiện tấn công XSS ở đây với payload đơn giản:
&'><script>alert(origin)</script>
VI. DOM-based Javascript injection
Khi input từ attacker được đưa vào các hàm thực thi như javascript code sẽ dẫn đến lỗ hổng DOM-based Javascript injection. Lập trình viên cần thận trọng khi đưa dữ liệu được nhập từ người dùng vào các hàm có thể thực thi code như:
eval()
Function()
setTimeout()
setInterval()
setImmediate()
execCommand()
execScript()
msSetImmediate()
range.createContextualFragment()
crypto.generateCRMFRequest()
Phân tích lab luyện tập https://portswigger-labs.net/dom-invader/testcases/augmented-dom-eval/
Có thể thấy hàm eval()
được sử dụng thực thi giá trị lấy từ tham số x
, attacker có thể thay đổi x
để thực hiện javascript code trong hàm này, payload:
alert('DOM')
VII. DOM-based Ajax request-header manipulation
Khi các header của Ajax request không được kiểm tra hoặc xử lý đúng cách, attacker có thể thao túng dữ liệu đầu vào dẫn đến lỗ hổng DOM-based. Một số sinks đáng chú ý có thể kể đến như:
XMLHttpRequest.setRequestHeader()
XMLHttpRequest.open()
XMLHttpRequest.send()
jQuery.globalEval()
$.globalEval()
Xét đoạn code ví dụ dưới đây:
<!doctype html>
<html> <head> <meta charset="UTF-8" /> <title>DOM Invader testcases</title> <script src="../../js/jquery-1.8.2.js"></script> </head> <body> <a href="index.php?x=burpdomxss">Test</a> <script> window.onload = function(e){ let x = ""; jQuery.globalEval(x); }</script> </body>
</html>
Mã JavaScript trong đoạn code trên sử dụng phương thức jQuery.globalEval(x)
để thực thi giá trị của biến x
. Khi giá trị x
chứa mã JavaScript độc hại được thao túng bởi attacker, ứng dụng sẽ thực thi mã độc không mong muốn trên trình duyệt người dùng.