📜 ⬆️ ⬇️

OAuth2 Security

This blog post on Habr is primarily due to the appearance of "Keyring" - a good reason to link and transfer accumulated .


We have in the program: a free retelling of the OAuth2 spec, weaknesses and the Threat Model, 0day on Habré with authentication trick.
image

Oauth2 is just


A long, but correct way to learn it.
For the lazy, I will describe in my own words Authorization Code Flow as the most common and secure, aka Server-Side .

Key concepts - Client (website / online game / app), User (you), Provider (facebook / vkontakte / google), Code (code) and Token (access_token).

The client sends the User - “authorize me to access your resources”. The user follows the link to the provider, looks at what is required of him - the scope parameter - presses Allow. Next, the Provider redirects it back to the indicated redirect_uri on the Client's domain with the following parameters:
code - User ID from the Provider that the Client needs to get the Token
state is the same value that was passed to the initial URL. used for protection against CSRF and for convenience.
')
The code does not represent any value for the User (and User-Agent, respectively) because with it you can not make requests to the API and it is needed only for one purpose - to get the Token.
To get the Token, the Client makes a request for a specific endpoint, passing the client_id, client_secret, code, redirect_uri for which the code was received - thus the Provider is sure that it is the right Client and by the Code he gives the Token to the same User. As you can see, neither User, User-Agent, and client scripts have seen the real Token. He is known only by the Client and the Provider - ideally.

Further, the Token is used to make the API requests, it can later be refreshed (for this, refresh_token is returned with the Token).

Threat Model or I Know What You Think About


A long, but correct way to safely use OAuth.
Here I will note:

1. And what if I substitute such a redirect_uri which will lead to my website and then use this Code myself for authentication?

All redirect_uri should be on the client's domain. Often, another Provider domain is allowed. Your link will return redirect_uri_mismatch.

2. OK, but what if I find such a place on the Client's site that will merge my Code? Can an open redirect of site.com?url=http://outsite.com or a hot-linked picture that the referrer merge?

Each Code is tied to the volume for which it was released and for receiving the Token, the Client sends the “correct” redirect_uri. If your Code has been released for clientsite.com/leak_referer and the Client will send the Token to Clients.com/facebook_callback when receiving the Token, then the Provider will not give up the Token.

3. Is it possible to somehow merge the code by passing the correct redirect_uri?

No, because any correct implementation of the Client is obliged to immediately redirect to another page after receiving the Code - so that the Code is not visible even in the browser history.
Even if you managed to get the code for the correct redirect_uri it has already been used once; it is no longer active.

4. Suppose I have a code for my social network account issued for the correct redirect_uri. What happens if I force Vasya to visit this link?

In this case, the Client’s site will think that your social network account belongs to Vasya. And join him. To prevent typical CSRF from occurring, the Client is obliged to save a random value of state in the session / cookie and check for a return to the callback for compliance. Although, almost no one does (more precisely, they did not).

Reality


FB Reply Attack

Facebook Connect is vulnerable to the classic Replay attack.
Demonstrates point 3 - after one use of the code it can still be used for authentication within 60-80 minutes - the standard expire_in token. Replay attack in its purest form.
Suppose we found an XSS on the site - something like this inject will help you pull out the code for the correct redirect_uri through the document.referrer frame.


The report is made, they will be fixed soon. Well, how soon, about three months, the enterprise is
Hijacking account

The most frequent vulnerability is present, for example, in Habré - more on this below. Paragraph 4 is violated.
If you see in the request state do not rush to give up. What hubr that digg.com did not see the difference between a12b6467c3fb385e237109502277ab26 and heyman0day123123

VK redirect_uri
The implementation was made for some ancient manuscripts - the lack of verification for which redirect_uri was released The code is a gross violation of clause 3.
See, here is the link Click, do not be afraid, and open the Network Panel. See the request?

The referrer has merged, the code has merged - now it can be used to log into your account through your VKontakte (if you have tied it) already about the correct redirect_uri.
The report was made a week ago, there were no responses from living people and bots.
misc

If you use Implicit Flow - i.e. If you get access_token directly from the user, then there are no guarantees that this token belongs to the current user. He could just steal it through a malicious Client, and use it to get into the account of some user on your site.
Be sure to check if this token has been released for your client_id.

Also, OAuth2 does not make any guarantees that the user has given you the permissions that you requested at the authorization stage in the scope parameter. He could just delete them - in the end, you have to check at the callback whether he allowed what you requested.

If XSS is found on the site, then there is an easy way to steal a bunch of access_token s. Take the authorize URL that the site uses for facebook and replace response_type = code with token. It remains to insert this URL into the frame, wait for the return of the token in the link of the type callback # access_token = 123, cut the token and merge it. Spam on health!

0day on Habré?


The same exploit works for facebook / google and it’s harder to get redirect_uri with code without using it - you need NoRedirect + FF
Therefore, the demo on VK. Uncle not bath UPD: fixed the vulnerability .

1. You should not be tied VK. Login to oauth.vk.com/authorize?response_type=code&client_id=3110645&redirect_uri=http%3A%2F%2Fhabrahabr.ru&scope=offline&display=page
2. You returned to habrahabr.ru/?code=CODE
3. Make another habraiser visit habrahabr.ru/social/callback/vkontakte/?code=CODE&state=whogivesafuckaboutstate you can throw the link itself, but it is better to hide it in img or iframe and so on. If he is logged in on Habré, your VC is tied to his habraka account.
4. Login using your VC in his habrakacount, change his avatar to nayncat.

Morality


Vkontakte : stop ignoring letters to Support, or ask your developers to condescend to talk to a mere mortal. And also enter bounty program (sarcasm: there is a risk to go broke on it).
Habr : I recommend turning off the Key for the time being and fixing the vulnerability by correctly checking the 'state' with the value from cookie / session.

Road to Hell is shorter. You can join the development of a fundamentally new standard with bored tokens - OAuth2.a ( Charm - Provider ). Cookies, however, no.

Egor Homakov ( @homakov ) & isciurus #RT pls


UPD2:
Habr closed the vulnerability, VKontakte added redirect_uri check for all new applications and notification for old ones; facebook "We’ve only reached the minutes of their creation" and “After reviewing the billingy of $ 2,000 USD”, I’ve raised again, people speculate about bounty vk’s prospects .

Source: https://habr.com/ru/post/150756/


All Articles