Attacking Authentication Mechanisms  

Improper CSRF Protection


As we discussed a couple of of sections ago, the state parameter in the OAuth flow is optional but, highly recommended parameter that serves as CSRF protection from a security perspective. This section will discuss how a missing or improperly validated state parameter leads to a CSRF vulnerability and how to exploit it.


Missing state

When examining an OAuth implementation in the real world, it is crucial to take note of all parameters that are set in the OAuth flow. A particularly interesting target is the state parameter in the authorization request. If the parameter is missing, a CSRF attack on the OAuth flow might be possible. The impact of such an attack can be severe, depending on the concrete utilization of OAuth.

For now, let us assume an OAuth implementation that does not utilize the state parameter:

image

In this case, an attacker can conduct a Login-CSRF attack that results in the victim being unknowingly logged-in to the attacker's account. While the consequences of such an attack might seem unclear at first, these attacks pose a significant threat to the security and privacy of users. Depending on the web application, the impact might be non-existent or severe. Imagine a scenario where a victim gets logged in to an attacker account and enters payment information into their profile, thinking it was their own account they are logged-in to. This enables the attacker to steal the victim's payment information, as they unknowingly added the details to the attacker's account.

Generally, these attacks can result in loss of victim data. However, they typically required the victim to enter information into the attacker's account thinking it is their own account.

Attack Execution

The execution of an attack on an OAuth flow without a state parameter is as follows. Firstly, the attacker needs to obtain an authorization code for their own account, which can be achieved by sending an authorization request and authenticating using the attacker's credentials:

POST /authorization/signin HTTP/1.1
Host: hubgit.htb
Content-Length: 96
Content-Type: application/x-www-form-urlencoded

username=attacker&password=attacker&client_id=0e8f12335b0bf225&redirect_uri=%2Fclient%2Fcallback

The response contains a valid authorization code tied to the attacker's account:

image

The attacker can now craft the URL for the authorization code grant using the obtained authorization code:

http://hubgit.htb/client/callback?code=Z0FBQUFBQm1BekxRVGFLdTk5WHZycU9zZ0dCS2IzaWwzWTkxME9tVHJPbXpibTVLV0g0MVRyUVhCSF9vVHVNSHdXX0NZV2FzTHEzTzRFLW5wejU5ai1ONVdxMlc0LU0wMDdURXVPRGYtX05Mb21mZTljTUtzTWwxa1pvdktUVzlWcXJFNzMtZGJ1eWtKcllFQy0xd3RlM3JXUzczUEUtU3lnPT0

This is the payload for the CSRF attack that needs to be supplied to the victim, just like in a regular CSRF attack. An attacker could achieve this through social engineering or phishing.

When a victim clicks the provided link, the victim's browser will automatically complete the OAuth flow and trade the authorization token for an access token, thereby logging the victim in to the attacker's account:


How the state parameter prevents the attack

The state parameter prevents the attack discussed above. Depending on the implementation, this is typically achieved by a mismatch between the state values in the authorization code grant if the previous authorization request was not initiated by the same user.

For instance, just like before, an attacker might obtain an authorization code for their own account. In the authorization request, the attacker can choose an arbitrary value for the state:

POST /authorization/signin HTTP/1.1
Host: hubgit.htb
Content-Length: 96
Content-Type: application/x-www-form-urlencoded

username=attacker&password=attacker&client_id=0e8f12335b0bf225&redirect_uri=%2Fclient%2Fcallback&state=1337

Just like before, the response will contain a valid authorization code for the attacker's account:

image

The attacker can now craft the URL for the authorization code grant using the obtained authorization code and the same state value used before:

http://hubgit.htb/client/callback?code=Z0FBQUFBQm1BelRBRnlnUmRkQXRaclFtaEhFcUhHZ2ZQRURnaEN2bWIxRXEteXhGc2RuMVdWY3FZS1lGMnRrejdMOEEzYUMzS3ZIZlM3OEpVNGNFWmswZ2VKdjV4a2lTMmFpb2NDRFJ5QmFqOVFaUmI1WS1YM0xoVWVOUnhMZ1FJV29sLWN0ZE9sMXZOUzZkYmZBSk9hb25MbW54bnY1QWZ3PT0&state=1337

However, if the victim now accesses the attacker-provided URL, a mismatch in the state parameter is detected, the request is rejected, and the OAuth flow is aborted:

image

That is because the attacker-provided state parameter does not match the value in the cookie stored in the victim's browser, resulting in a mismatch. The exact details of this mismatch may vary depending on the OAuth implementation, but it usually depends on a cookie-based value used for comparison to the state value.

Just like regular CSRF-tokens, the security of the state parameter relies on the value being unpredictable. If an attacker is able to predict the value, they can set the state value accordingly in their authorization request and defeat the protection entirely.

/ 1 spawns left

Waiting to start...

Questions

Answer the question(s) below to complete this Section and earn cubes!

Click here to spawn the target system!

Target: Click here to spawn the target system!

Authenticate to with user "htb-stdnt" and password "AcademyStudent!"

+10 Streak pts

Previous

+10 Streak pts

Next