---
# System prepended metadata

title: "Portswigger OAuth 2.0 Authentication Vulnerabilities \U0001F976"
tags: [advanced, oauth, portswigger]

---

# Portswigger OAuth 2.0 Authentication Vulnerabilities 🥶

<style>body {text-align: justify}</style>

Hi, dưới đây là writeup của 6/6 bài lab về tấn công [OAuth 2.0 authentication](https://portswigger.net/web-security/oauth) mình đã solve trong quá trình ôn tập thi chứng chỉ của Portswigger.

**Authorization code grant type**

![](https://i.imgur.com/AczrMnj.png)

**Implicit grant type**

![](https://i.imgur.com/dkGxzKl.png)

### 1. Authentication bypass via OAuth implicit flow

##### Description

> This lab uses an OAuth service to allow users to log in with their social media account. Flawed validation by the client application makes it possible for an attacker to log in to other users' accounts without knowing their password.
> 
> To solve the lab, log in to Carlos's account. His email address is `carlos@carlos-montoya.net`.
> 
> You can log in with your own social media account using the following credentials: `wiener:peter`.

##### Writeup

Đây là dạng OAuth Implicit grant type. Đầu tiên, sau khi truy cập app và authen thì lập tức được redirect về 1 trang login theo social media với các request như sau:

```
Client App: 
--> GET /social-login
--> GET /auth?client_id=pnulrnn7d8b6dudj7m5mh&redirect_uri=https://0a60006c04f2123881fa5ce200a100db.web-security-academy.net/oauth-callback&response_type=token&nonce=1677942221&scope=openid%20profile%20email
```

Tại đây đăng nhập với account `wiener:peter`

![](https://i.imgur.com/cPF07XJ.png)

OAuth server sẽ redirect về đường dẫn đã định nghĩa ở tham số `redirect_uri` ở trên kèm theo `access_token` ở fragment.

```
OAuth server:
<--  GET /oauth-callback#access_token=_UUmuaiY5pjAx9jLQ0FkeFNgKIwXWVWw_d4nbcSVGEb&amp;expires_in=3600&amp;token_type=Bearer&amp;scope=openid%20profile%20email
```

Khi đó app truy cập đường dẫn trên.

```
Client App: 
--> GET /oauth-callback
```

Tại đây là 1 đoạn script thực hiện các bước như sau:

- `GET /me` với `token` từ fragment để lấy thông tin user.
- `POST /authenticate` với `email`, `username` và `token` có được từ request trên để login.

```javascript
<script>
const urlSearchParams = new URLSearchParams(window.location.hash.substr(1));
const token = urlSearchParams.get('access_token');
fetch('https://oauth-0aeb00f50465120a813b5a44027e0084.oauth-server.net/me', {
    method: 'GET',
    headers: {
        'Authorization': 'Bearer ' + token,
        'Content-Type': 'application/json'
    }
})
.then(r => r.json())
.then(j => 
    fetch('/authenticate', {
        method: 'POST',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            email: j.email,
            username: j.sub,
            token: token
        })
    }).then(r => document.location = '/'))
</script>
```

Cụ thể, `GET /me` trả về `username`, `email`. Có vẻ như `email` sẽ được dùng để identify user.

![](https://i.imgur.com/b0HdDm7.png)

Thực hiện authen bằng `POST /authenticate`.

![](https://i.imgur.com/ApZj6wP.png)

Sau khi hiểu được rõ flow trên, ta thay email của nạn nhân carlos để authen.

![](https://i.imgur.com/VAkk6NO.png)

Kết quả authen thành công do không có cơ chế kiểm tra access_token có match với data gửi lên hay không. Ta solve challenge.

![](https://i.imgur.com/HXDYa9q.png)

### 2. Forced OAuth profile linking

##### Description

> This lab gives you the option to attach a social media profile to your account so that you can log in via OAuth instead of using the normal username and password. Due to the insecure implementation of the OAuth flow by the client application, an attacker can manipulate this functionality to obtain access to other users' accounts.
> 
> To solve the lab, use a CSRF attack to attach your own social media profile to the admin user's account on the blog website, then access the admin panel and delete Carlos.
> 
> The admin user will open anything you send from the exploit server and they always have an active session on the blog website.
> 
> You can log in to your own accounts using the following credentials:
> 
> Blog website account: `wiener:peter`
> Social media profile: `peter.wiener:hotdog`

##### Writeup

Sau khi đăng nhập bằng `wiener:peter`, ứng dụng cho phép attach social profile.

![](https://i.imgur.com/hs8L0EJ.png)

Bằng cách đăng nhập bằng account social media,

![](https://i.imgur.com/Z46Ruqq.png)

Mình có thể đăng nhập lại mà không cần username password mà chỉ cần `Login with social media`.

![](https://i.imgur.com/Y5fvAoO.png)

Tuy nhiên khi để ý kĩ request khi attach social profile thì không có tham số `state` &rarr; có thể CSRF. 

![](https://i.imgur.com/BdGgI8A.png)

Khi OAuth server trả về code thì mình có thể sử dụng nó để khiến nạn nhân attach profile của nó vào account của mình. Miễn là code đó chưa được sử dụng.

![](https://i.imgur.com/vn34NQI.png)

Tạo CSRF payload bằng iframe load request chứa code trên.

![](https://i.imgur.com/tO02fRa.png)

`Login with social media` lúc này ta vào được account admin.

![](https://i.imgur.com/dPAPGqw.png)

Xóa user carlos và ta solve challenge.

![](https://i.imgur.com/LEvEer7.png)

### 3. OAuth account hijacking via redirect_uri

##### Description

> This lab uses an OAuth service to allow users to log in with their social media account. A misconfiguration by the OAuth provider makes it possible for an attacker to steal authorization codes associated with other users' accounts.
> 
> To solve the lab, steal an authorization code associated with the admin user, then use it to access their account and delete Carlos.
> 
> The admin user will open anything you send from the exploit server and they always have an active session with the OAuth service.
> 
> You can log in with your own social media account using the following credentials: `wiener:peter`

##### Writeup

Mình có thể chỉnh `redirect_uri` tùy ý tại authorization request.

![](https://i.imgur.com/UO7QNNz.png)

Authorization code được gửi về đúng `redirect_uri` đã gửi.

![](https://i.imgur.com/Q804Ylt.png)

Bây giờ chỉ việc gửi cho admin authorization request chứa `redirect_uri` là exploit-server.

![](https://i.imgur.com/b6VAuZC.png)

Ta sẽ nhận được authorization code của admin.

![](https://i.imgur.com/lFyYzUo.png)

Truy cập tài khoản admin bằng cách truy cập `/oauth-callback?code=<CODE>` với code lấy được.

![](https://i.imgur.com/N5rjRw6.png)

Ta vào được trang admin và xóa user carlos. Ta solve được challenge.

![](https://i.imgur.com/LtnZBv5.png)

### 4. Stealing OAuth access tokens via an open redirect

##### Description

> This lab uses an OAuth service to allow users to log in with their social media account. Flawed validation by the OAuth service makes it possible for an attacker to leak access tokens to arbitrary pages on the client application.
> 
> To solve the lab, identify an open redirect on the blog website and use this to steal an access token for the admin user's account. Use the access token to obtain the admin's API key and submit the solution using the button provided in the lab banner.
> The admin user will open anything you send from the exploit server and they always have an active session with the OAuth service.
> 
> You can log in via your own social media account using the following credentials: `wiener:peter`.

##### Writeup

Tại Authorization request, thử thay thế `redirect_uri` thành 1 URI khác thì bị báo không khớp trong whitelist.

![](https://i.imgur.com/9klEdk4.png)

Tương tự khi xóa đường dẫn `/oauth-callback`.

![](https://i.imgur.com/gDDnGwM.png)

Như vậy `redirect_uri` phải chứa `https://<LAB-ID>.web-security-academy.net/oauth-callback`. Thử path traversal thì lại thấy thành công. Như vậy mình có thể lợi dụng để redirect về  1 URL mà tại đó có chức năng open redirect về domain attacker.

![](https://i.imgur.com/EJB5vjJ.png)

Ta tìm được endpoint có chức năng open redirect đó là chức năng load next post có tham số path là URL nó sẽ redirect đến.

![](https://i.imgur.com/56LwbqJ.png)

Như vậy ta sẽ chỉnh `redirect_uri` thành như sau với path là exploit-server.

![](https://i.imgur.com/S7g3v2x.png)

Lúc này, oauth server sẽ request đến exploit-server để trả về `access_token`.

![](https://i.imgur.com/3b2Tnow.png)

Bây giờ chỉ việc tạo payload. Đoạn script có chức năng khiến nạn nhân load authorization request &rarr; `access_token` trả ngược về exploit-server qua query string (vì URL fragment không xem được trong log).

![](https://i.imgur.com/dHvQEbp.png)

`Deliver exploit to victim`, ta thấy nạn nhân đã thực hiện oauth thành công và ta lấy được `access_token` log.

![](https://i.imgur.com/hS0a3YR.png)

Sử dụng access_token trên request đến `/me` để lấy user data. Ta lấy được APIKey của admin.

![](https://i.imgur.com/Mmmrvug.png)

Submit và solve challege.

![](https://i.imgur.com/M39ERt6.png)

### 5. SSRF via OpenID dynamic client registration

##### Description

> This lab allows client applications to dynamically register themselves with the OAuth service via a dedicated registration endpoint. Some client-specific data is used in an unsafe way by the OAuth service, which exposes a potential vector for SSRF.
> 
> To solve the lab, craft an SSRF attack to access `http://169.254.169.254/latest/meta-data/iam/security-credentials/admin/` and steal the secret access key for the OAuth provider's cloud environment.
> 
> You can log in to your own account using the following credentials: `wiener:peter`

##### Writeup

Ta xem được openid config tại `<OAuth-server>/.well_known/openid-configuration`. 

![](https://i.imgur.com/oTXkqKO.png)

Để ý thấy endpoint client app registration tại `/reg`. Thực hiện đăng kí client application thử với `redirect_uris` bất kì, ta thấy server trả về tạo thành công và có `client_id`.

![](https://i.imgur.com/UuyoVkR.png)

Mặt khác quan sát ta thấy, bước confirm về thông tin có thể truy cập có xuất hiện request đến `/client/<CLIENT_ID>/logo` để hiển thị logo.

![](https://i.imgur.com/8K31czt.png)

Và theo docs, thì nó lấy logo từ đường dẫn được định nghĩa tại `logo_uri` tương ứng với `client_id`. Ta kiểm tra out bound request đến collaborator không khi đăng kí new client app với `logo_uri` là collaborator URL.

![](https://i.imgur.com/Ngjn8Sj.png)

Sử dụng `client_id` tương ứng và load logo, ta thấy đã có request đến collaborator &rarr; có thể SSRF.

![](https://i.imgur.com/3Vjyw6U.png)

Làm lại các bước tương tự với `logo_uri` chính là đường dẫn đã cho `http://169.254.169.254/latest/meta-data/iam/security-credentials/admin/`.

![](https://i.imgur.com/S4StA4Z.png)

Truy cập logo với client_id tương ứng, ta lấy được secret access key của OAuth server trên cloud.

![](https://i.imgur.com/qAD5l7c.png)

Submit key đó và ta solve được challenge.

![](https://i.imgur.com/t64mjA3.png)

### 6. Stealing OAuth access tokens via a proxy page

##### Description

> This lab uses an OAuth service to allow users to log in with their social media account. Flawed validation by the OAuth service makes it possible for an attacker to leak access tokens to arbitrary pages on the client application.
> 
> To solve the lab, identify a secondary vulnerability in the client application and use this as a proxy to steal an access token for the admin user's account. Use the access token to obtain the admin's API key and submit the solution using the button provided in the lab banner.
> 
> The admin user will open anything you send from the exploit server and they always have an active session with the OAuth service.
> 
> You can log in via your own social media account using the following credentials: `wiener:peter`

##### Writeup

Tương tự bài 4, ta có thể path traversal tại `redirect_uri`.

![](https://i.imgur.com/eFKR0Gp.png)

Tại mỗi post của blog, form comment được load bằng frame từ `/post/comment/comment-form`.

![](https://i.imgur.com/m55D0sW.png)

Tại đó, xuất hiện một `postMessage()` đến parent có origin bất kì `*`, tức là trang đang dùng frame của comment form này, với message là `window.location.href`. Như vậy nếu trang exploit-server frame chứa comment-form này thì nó sẽ nhận được message chứa `window.location.href`. Và nếu `redirect_uri` của oauth là `/post/comment/comment-form` thì `window.location.href` sẽ chứa `access_token`.

Kết hợp các điều đó, ta xây dựng payload như sau:

![](https://i.imgur.com/IFtVNYN.png)

Theo đó sẽ có iframe chứa authorization request với `redirect_uri` được sửa thành `/oauth-callback/../post/comment/comment-form`. Và khi nhận được message từ `/post/comment/comment-form`, thực hiện fetch đến exploit-server để có thể xem `access_token` qua log.

![](https://i.imgur.com/ylBqvIm.png)

Gửi cho nạn nhân, và ta lấy được access_token qua log.

![](https://i.imgur.com/cpISnyu.png)

![](https://i.imgur.com/dKNlt4g.png)

Sử dụng access_token và gửi request đến `/me`, ta xem được API key của admin.

![](https://i.imgur.com/Sh1CC1M.png)

Submit API key đó và ta solve challenge.

![](https://i.imgur.com/nalAsYb.png)

###### tags: `portswigger`, `oauth`, `advanced`