oAuth token in browser history - oauth-2.0

I am writing a native app which uses oAuth. (my app is the client)
At the moment, my app is native to Windows, but I assume that this problem is the same across all desktop operating systems.
To accommodate the oauth flow: My native app opens a browser tab and directs it to the oauth provider.
I am using a browser and not an embedded webview because many Identity providers (ex: google) block non standard browser implementations. ( They want to prevent automated bots).
My app has a small web-server which it uses to listen for the redirect_url called back from the identity provider. Then my app goes on to use said token to access oauth resources from the provider (ex: gmail)
The problem is: When the identity provider (such as google) redirects back to my app, it returns the access_token to my app in the browser's address bar. As such, this token will then appear in the browser history, which will make it very easy for other native apps (or random users using the browser later) to steal my app's token.
What can I do to mitigate this?
How do I prevent the access_token from the oauth callback from showing up in my browser history?

Sounds like you are using Implicit Flow which is the main problem:
Update to Authorization Code Flow (PKCE) so that only a one time use authorization code is returned. Even if an attacker steals it somehow, it will have been used already and the attack will fail.
Another option is to show an Interstitial Page in the browser after login, with a button click to return to your app. As part of that click you can clear the browser tab's history and move to a new location:
history.replaceState({}, document.title, redirectLocation):
See my blog post for some further details on how this looks.

Related

Transfer the authenticated user to a SPA without forcing them to re-enter their credentials

This is my current setup:
IdentityServer4
API (Bearer authentication)
SPA page (oidc-client implicit flow redirected to IdentityServer4 Quickstart UI)
Native application (written i C#)
The native application already have the users credentials. I want to provide a web link to the SPA page from the native application, but I don't want to force the user to login again when navigating to the web. Instead I want to move their current session to the web page.
Is it possible to "inject" the access token into the oidc-client? (using a url fragment). Or is there any other flow or way to make this work?
In general the answer should be: you are on a wrong way.Look: you use resource owner password flow in your native app and that's wrong. It's not interactive, meaning not only IdP has access to the credentials. In general such flow is recommended for test purposes etc, not for general use. One huge limitation of the non-interactive flow is that it does not create a user session. If you switch your native app to an interactive flow such as Code flow with PKCE extension, it will create the session. After that your other app will get authenticated automatically whenever the session cookie for Identity server is alive.NB: If you don't like to improve your architecture, you are free to do whatever you like, including providing a token in the link. That token will still be valid for calling the API. But that will be not the implicit flow, you will not have a session, nor the possibility to use silent refresh feature.

How to implement OAuth2 flow in Single Page Applications (Angular2 + Rails4)

I am wondering which OAuth2 flow best suit the SPA scenario. The front-end is angular and the backend is rails.
I think the authorization code grant type is the most adequate for this scenario but I am not sure how to handle the redirection when the user grants access to my application. That redirection breaks the SPA spirit to keep the user in the same page.
Thanks
EDIT (Added information):
Let me be more precise. Particularly I am trying to integrate google calendar into my app using this flow https://developers.google.com/identity/protocols/OAuth2WebServer. I am facing various problems, most of them because I have an angular SPA.
My first problem is how to handle the authorization endpoint. Up to now, I have devise and endpoint called /google_auth that will check whether the current user has authorized the app or not. If not, I will respond with a json body that has the authorization_uri. Here comes the first problem, how does the front-end show the authorization dialog. If I call window.open the browser will block it because it thinks its a popup. If I change the current window location it will leave my app and I don't want this.
The second problem appears when the user authorize my app in the authorization window presented by google. Here, google will send a request with the authorization code to the redirect uri callback previously defined. As I am using JWT token for authentication, in this request I lose which user has granted me authorization so I can't associate the refresh token to the user. How can I handle this? I am thinking I can use the state parameter to forward the JWT token, but I am no sure this is secure enough
It does indeed, but don't forget why this happens.
The whole point is that the user does not enter their password in an unknown application and most won't. When people see the login page from Facebook for example, they trust that and are cool with it. A random form asking them for their password is not cool and can lead to them being hacked which is why everyone who is concerned with security will simply leave that insecure website and move on.
My suggestion is to stick with the flow which makes sense. Once the user is authenticated and gives your app access, they will be sent back to your app and there you can get the token and use it to do further work so you are basically back in the SPA flow. It's just that your flow now has 2 steps, that's all.
Basically, you have 2 UI options: open the authorization page in the same window thus unloading your SPA, or in a pop-up, thus having risk of it being blocked. Unless the frontend app's state is too large, you may store essential app's state, go through authorization, and reload the app restoring the state. The state may be stored in browser's localStorage, in the redirect URL (if protocol allows variable part) or on the server side.
If your application is in public space, follow the authorization based flow if in enterprise then either the first option of password grant flow is also ok.

Receive cross-client Google+ authorization code for offline access without library on iOS

It's funny but I can't find description of using HTTP requests to receive Google+ authentication code for offline access without iOS Google+ library.
Though example of it's integration is pretty straightforward, I don't want to add additional 20mb of weight to my iOS app.
I tried the approach described here
https://developers.google.com/accounts/docs/OAuth2WebServer#offline
but in case of server clientId I receive message abount incorrect redirect uri.
Could someone give me advice about it?
There are two approaches you could take that may/may not work for you.
Installed app flow with internally stored client secret
Web flow within a web view.
Installed app flow
You will must likely need to use the offline OAuth v2 / installed app flow which has redirect URI that has something like urn:ietf:wg:oauth:2.0:oob enabling you to redirect back to the browser, from there you can get a code to exchange for tokens.
In your case, I'm guessing you didn't create the right client type (installed application) which is preventing the *:oob redirect.
It's less secure to handle sign in in this way - if the user can extract the client secret from your app, they can do bad things like authorize a malicious 3P app with access to your application data.
Web signin flow
An alternative would be to use the web signin flow from within a WebView, something that Apple may reject your app for and which is also insecure.
What you would do is host the sign-in solution on your web server, use the JavaScript web signin flow to initiate sign in, request offline access, then exchange the resulting code for an access token and refresh token.
You would then store the refresh token / access token on the device and exchange it for an access token when you need access to the user data or exchange the refresh token server-side and pass the bearer token back to the iOS app when it needs access. This again is bad because it can expose other apps to user authorization credentials and could potentially allow a malicious 3P to access user data.
I can't recommend either approach. Is there a reason other than the app size impact that you can't use the library? I'll see if there is a good way to avoid the file size hit from the framework.

OAuth2 breaks security for desktop apps?

Currently in the process of moving from OAuth1 to OAuth2 in a desktop application for a web service (Imgur), I've been baffled by the OAuth2 specs. Apparently it breaks all the security OAuth1 provided, according to this doc http://aaronparecki.com/articles/2012/07/29/1/oauth2-simplified and by looking at different services docs regarding OAuth2.
With OAuth1 you could use a URL to the service where the user would grant access and a PIN was displayed to copy/paste in your app, which was really nice security in the sense that the user never grants their login/password to the app, and can revoke the given access to it at any time through the service's website.
Now with OAuth2 they left this scenario out, forcing the app to request the user's login/password, unless the app makes their own script in their website to receive a token from the service after granting access (then have the user copy/paste it from your website)
Am I missing something here?
Desktop applications can and should use a user agent (browser) to do OAuth and that is described in the OAuth 2 spec under "Native Applications". The flow you described is meant more for devices with limited input capabilities like a gaming console, printer, camera, etc.
AFAIK, the device flow was in the early specs of OAuth 2, but was omitted at some point. Some API providers like Google have implemented limited support for it regardless.
Native applications are the way to go. See the ["Native Applications"][1] section of OAuth 2.0 RFC. The native applications are not intended to store passwords. If you want to avoid entering of credentials directly in the app (even within a browser control), you may do the following from the OAuth 2.0 native application:
Launch the default browser with the authorization endpoint.
Implement a simple web page for your redirect URI, which picks the authorization code and shows it to the user.
Ask the user to copy the code and paste it back in the native application.
Alternatively, the spec suggests that you leverage the URL redirection scheme of the native platform to bring back the original application. You may check iOS and Android's "URL Scheme" capabilities. Unfortunately, neither of these platforms guarantees uniqueness of the URL scheme, hence the authorization code may be hijacked by another rogue app, which is activated on the same URL. I have filed an iOS bug for that.
[1]: https://www.rfc-editor.org/rfc/rfc6749#page-52

OAuth for Desktop apps?

i wonder how do desktop apps without any domain names use oauth? or is it not supposed to be used this way? if so what do i use? say for tumblr they have an authentication api so i will have to put the username and password in the url/query string?
i am thinking of using WPF/Adobe AIR. how does something like tweetdeck work?
I've been puzzled by the same question about lack of domain or app url, but it turns out redirection is not the only possible way to complete OAuth authentication process.
I.e., when webapp requests access it provides callback url: the one user will be redirected to when process is completed. That's how webapp know that everything's done.
But you can't redirect to application on user's machine. Thus, there's another way: upon successful authentication server presents special code to the user. Then user copies this code and provides it to application.
You can see both ways described in specification draft.
Also, here's an example of this authentication flow with twitter.
It looks like it may be possible, see googles docs on the subject:
https://developers.google.com/identity/protocols/oauth2/native-app
For a desktop app where a user needs to authenticate himself, you will usually want to use the Authorization code flow.
The approach goes roughly like this:
setup a temporary webserver that listens on the loopback interface
present the login page to the user (either in an embedded browser control or an external browser), with the URL of your temporary webserver as redirect_url
upon successful login, the user will be redirected to your temporary webserver and you can obtain the access code from the code query parameter
Using the access code, you can obtain a token and start making requests using it
Shutdown the temporary webserver
Please note that you will have to allow localhost as redirect URL in your identity provider, in ordrer for this approach to work.
For further details, please take a look at these sample apps from Google.
You should start by reading about getting started with OAuth. Eventually, even a desktop application will open a browser window to authenticate the user - TweetDeck and other Twitter clients do this, as you've probably noticed.
Tumblr, in your example, doesn't use OAuth but rather basic authentication that is being performed via simple HTTP web requests.
Twitter doesn't want users entering their credentials into your application. So at some point the desktop app will need to open a browser window through which Twitter can authenticate their users and return an access token representing the user. From that point the desktop app can use the access token to represent the user in all subsequent API calls to Twitter.
In a desktop environment you have another way to get the token, the browser open url itself.
the OAuth2 server will redirect the users browser to the Redirect URL with the token as a query parameter, so if you control the browser used, you can read the the token directly from the url that the user was redirected to.
Graphical libraries like GKT+ have integrated options to create mini browsers that the user can use to authenticate, and it automatically return the token to the app, but other options are possible, like reading Firefox url for example.

Resources