Hybrid Flow Web View Attacker Knows Redirect URL (IdentityServer4) - oauth-2.0

There is some confusion in my mind with the hybrid flow.
In this scenario, suppose we have a native desktop application that needs to authenticate a user. For such a case, we use the recommended hybrid flow.
As I understand it, we will use an embedded web browser to direct the user to the login page at the identity server. The user logs in successfully and the server redirects the web browser to the registered redirect url. The desktop application is notified of this redirect (something like an OnLoadFinished event) and parses the new url which contains some information including the authorization code. The desktop application then exchanges this authorization code for an access token/refresh token.
With this process in mind, is it not entirely possible that if a malicious user knows what the redirect url and client id is (lets pretend this user is an ex-employee), that they can create a very similar application like our desktop application to trick users into using that malicious application? Since they know both redirect url and client id, they can simulate the above process and get access/refresh tokens.
Am I correct in understanding that or is there something that I am missing?

You are absolutely correct. Just like with any other malware that a user installs on its machine/device.

This could also happen if someone applies reverse engineering in your application and gets your client_id + redirect, I guess.
Doesn't this mean that exposing client_id + redirect uri is as much dangerous as exposing client_id + client_secret in a public client?

Related

SSO for IdentityServer4 with grant type "authorization_code"

We're in a scenario where a single page application that we develop ourselves (AngularJS front end with https server APIs in the back) opens another
web application developed by a partner of ours in a new browser tab, and where this second web application needs access to a https server API that is also developed by us.
After looking around for possible solutions, we have now created a proof of concept using IdentityServer4, where the second web application is configured as a client with "authorization_code" grant type. When all applications are running on the same domain, the third party application is able to access our https server API without being prompted for user id and password.
The implementation of the second web application in this proof of concept is very much like the solution presented by bayardw for the post
Identity Server 4 Authorization Code Flow example
My question now is:
When - in production - the second web application no longer shares domain with our application and our https server API, will a call from the second web application be prompted for username and password when accessing our http server API?
Seems, you are missing some major things. First of all any API should never ask for username and password. Instead your app(s) should put a token into each request and API should validate that token. Where the user credentials should be asked is when a user accesses your (or 3-rd party) web application. Then Identity Provider creates an Identity token (usually to be persisted in a cookie and used within the app) and access token (to be provided to APIs). Each token is issued for specific Client (app) pre-registered in IdP. Probably when been hosted at the same domain your two apps shared the identity cookie and Client Id what is not correct. In production scenario you have to register the apps separately. All the rest should work fine (if you follow the routine i briefly described at the beginning).
Chosing to post an answer myself from feedback through other channels:
This boils down to the session tracking of the IdP. If cookies are being used to track IdP session, the behavior is impacted by whether a session cookie or a persistent cookie is used.
In general, I have found that Robert Broeckelmann has great articles on medium.com.

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.

How should I use OpenID to authenticate to WCF Data Services from a Windows Phone 7 app?

I have a Windows Phone application which is reading and writing data from a WCF Data Services service which is hosted in and ASP.NET MVC 3 application.
I can configure both client and server as necessary. I'd like to use OpenID if practical, and once a user is authenticated on the phone they should be able to browse through data which is associated with their OpenID.
How should I configure client and server to make that work?
To use OpenID in your app you should look at using an embedded WebBrowser control which connects to the provider site (or your site which can redirect). When the OpenID provider returns to your site (embedded in the browser control) you'd pass necessary identifiers back to the app.
There's an example of doing this with a twitter app (using OAuth) at http://blog.markarteaga.com/OAuthWithSilverlightForWindowsPhone7.aspx
OpenID is an awkward choice. It sounds like the user already has data associated with their account, which means that the user would have to login to the server at some point in time to set up this data, and then login to the app with the same credentials to access this data. The issue is that of securely verifying that the client app has indeed authenticated the user in question. Assuming that the client app (somehow) has the user's OpenID is not enough because the server can't implicitly trust what the client app tells it.
Off the top of my head, I'd say, what could be done with OpenID is as follows.
First, set up OpenID authentication on the server. Then, when the client app needs to authenticate, it should use the WebBrowser control to point to a server URL that, in turn, lets the user authenticate with their OpenID provider, and points the browser back to the server with the authentication info. At this point, the client app is unaware of the user's authentication status, but the server knows who they are. Now, the server can generate a single-use auth key for the client to use. It can redirect to a special URL with that key in it, at which point the client detects said URL, extracts the key, hides the WebBrowser control, and uses that key to talk to the server. I believe that would be a secure way to do such authentication, but like I said, this is just off the top of my head.

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