Google Sign-In button - What prevents someone from spoofing another app and stealing a token? - oauth

Using this page: https://developers.google.com/identity/sign-in/web/sign-in
It's really easy to add a button to a page for a client side only login with Google.
On Clicking the button, the user is presented with a screen like this:
There are 2 ux_mode for this button: "popup" and "redirect":
https://developers.google.com/identity/sign-in/web/reference
My question is about ux_mode=popup specifically, where the originating page doesn't change, and all the login flow is handled in a separate popup window.
Imagine a good app is published. It seems like an attacker could clone the app, present it to a user. The user thinking it's good app would login and the attacker would have a way to grab a valid token from the user for good app.
Now I understand that in that mode (popup), the IDP (Google) will reject anything that doesn't come from an Origin that is not part of the explicit list of redirect URIs set in the configuration of the project.
But is that the only thing that prevents this? I have read again and again that one should not rely on CORS for the security. Also I'm not sure but it seems that it can be circumvented with a little bit of crafting.
Is there another aspect of the security of this login flow I am missing?

I do not know google implementation but from OAuth 2 point of view:
1/ "The user thinking it's good app" user should check the address bar and a green lock in his browser. It is considered as a users responsibility.
2/ you registered redirect uris which are checked when client is trying to get access token. So google will reject to generate and redirect users browser to malicious app with the token.
3/ browser will reject any communication between popup window and other webpages since they are not same origin. This is called same origin policy and is considered as important security feature of a browser.
In general: app location/uri/origin/domain (as you want) is what identifys your app and security is based on that.
Hope it helped.

Related

Open web page and bypass login from iPhone - iOS

I want to open, from an iOS app, a web page that requires authentication in order to get to that page.
I googled a little bit and I believe I need to use WebKit and Javascript injection, but I am not sure and I have never done something like this, so every bit of information is welcomed or pointing me in the right direction.
I will give an example that I hope will make things more clear(I don't actually want to open facebook, it's just part of the example):
Is it possible to do the following scenario? And if yes, how?
Open a web page from an iOS app, for example: "https://www.facebook.com/profile" without having to go through the login page? I do have the user credentials(username and password), as the user is already logged in with those credentials in the iOS app, but the requirement is to not go through the login page, but to go straight to the profile page.
In general the answer is: no. Even if the user is already logged in and has a valid authentication token that token may only be valid from within your app and not from within the browser. And the login form may be protected by something like a captche preventing you from automatically logging someone in.
There certainly are situation where it is possible: For example if the tokens are not scoped to your app you can try passing them along. Or there is an actual API that you can call with the token that logs the user into the website on the website, etc. But those depend on the specific target website or wether you can control that target website and can add this functionality.

Via the api, can I force the user to login to reddit?

I am writing a Reddit client that uses OAuth to authenticate the user. One of the features I would like to implement is the ability to use multiple accounts simultaneously. This requires the user to authorize my client on each account they want to use. The problem I'm running into is that if the user is already logged into Reddit in their browser, when I pop a browser to perform the auth, it will have them authenticate my client against their currently logged in user.
Is there a way to force the user to re-enter their credentials? I would rather not have to put some kind of disclaimer on my Add Account screen that says "Please log out of Reddit in any open browser windows".
I tried opening the Reddit login page in a WebView so the request is sandboxed, and while that worked, it gives the user access to the entire login page (including all the links that navigate to elsewhere on the site). I don't mind that experience when I'm popping an external browser, but in an embedded WebView I really just want to present a username and password box along with the OAuth validation prompt.
Note: I do kind of prefer the embedded experience because it doesn't interfere with the users existing browser cookies, I just don't like how cluttered the login page is this way and I'm not sure how to prevent the user from navigating away from login. Also, for completeness, this is a UWP app, though this problem is largely technology independent.
The problem I'm running into is that if the user is already logged into Reddit in their browser, when I pop a browser to perform the auth, it will have them authenticate my client against their currently logged in user.
It may be caused by the authorization server. If so, we can not do anything in our client app.
But if it is not the server issue, in UWP, there is a WebAuthenticationBroker class witch can help you to authorize your app to access the user info from Resource server by getting a token. You can try to use the class to implement OAuth authorization. You don't need to use the in a WebView so that you can authorize your app with multiple users if you can manage all the user with the token properly in your code logic.
See the Web authentication broker topic and the sample to learn more details.

dropbox oauth token flow: redirect without needing to click "allow"?

I am learning to use dropbox APIs and got confused when came up with the token flow.
As guide indicates, the flow should be like this:
the app redirect the user to a Dropbox webpage, i.e. .../oauth2/authorize
user logs in and approves the app
redirect back to the app. At this point, the app gets an access token.
However, when i requested the URL:
.../oauth2/authorize?client_id=xxx&response_type=token&redirect_uri=xxx
I was directly redirect to the destination with
REDIRECT_URI = "#access_token=xxx&token_type=bearer&uid=xxx"
And the "approve step" was skipped, i.e I got an access token without being allowed.
Is it a bug or my fault?
Any help would be appreciated :]
In certain cases, when the user has already approved the app to access their account previously, they will be automatically redirected through the app authorization flow.
If you want, your app can prevent this behavior from happening by using the force_reapprove parameter, documented for the /oauth2/authorize page here:
https://www.dropbox.com/developers/core/docs#oa2-authorize

Best practices in dealing with the abuse of custom URL scheme to make phishing attack ios

The Scenario:
A web application that once a new user completes the registration, an email will be sent, containing a URL that once tapped from within an iOS device, the iOS app will be launched. This scenario is a classic scenario to make users use the mobile app.
While implementing it (using URL scheme), we start wondering how secured is this method? Theoretically - a malicious app could sign up to the same URL scheme, and according to Apple:
Note: If more than one third-party app registers to handle the same URL scheme, there is currently no process for determining which app will be given that scheme.
Implementing Custom URL Schemes by Apple
In such scenario, if a user is tapping the url inside the email, it is unknown which of the two (or more apps) will be launched - ours or the malicious one. Lets say a different app is being launched - if its really malicious, theoretically it could mimic the login page of our app and grab the user's credentials.
Are there any best practices that handles such scenario? I've read many articles regarding the issue, all of them claims that the only solution is to wait for Apple to make these url schemes unique.
example1,
example2
I would love hearing about any solution to the issue if exist,
Thanks in advance!
We have to assume the malicious app can intercept any data included in this url and that it's author has been free to reverse engineer any behavior included in your app so it can imitate your UI and any validation your app attempts to perform. However we can also assume that the malicious app is contained in its own sandbox so your app can communicate with your backend privately. The malicious app can imitate any such communication but this does allow us to construct a secret unknown to the malicious app. That gives us at least an opportunity to design some countermeasures.
One option might be:
As part of registration construct a public/private key pair and store it in your app.
Send the public key to your web backend as part of the registration process.
Encode they payload of your URL using that public key.
Now we've sent data to your app which might be redirected to a malicious app but which the malicious app cannot read. That's a partial solution. We still need to be careful to design a UI which does not encourage a user to fall for a phishing attack since the URL might still launch the imposter.
The encoded data might be a token we can use to authenticate the user and therefore never require them to re-authenticate within the app. Then there is no login screen to imitate (though a clever forgery might still be enough to trick users into divulging their credentials).
An alternative might be to use a similar per-user secret stored on the client as a salt to combine with the user's password. Their password alone might then be insufficient to authenticate so a malicious app capturing their credentials is not immediately able to access their account.
Another design could be to allow the user to customize their experience in a recognizable way. You might show their selected profile image on the sign in screen. If that selection is known only to your app then an imitator shouldn't be able to duplicate it reliably (again, no guarantee that means users will catch the deception).
All of this introduces tradeoffs; users might still be tricked into revealing information to malicious apps no matter how different they appear from your legitimate client, client side secrets can be extracted by other attacks, and you need a plan to support users who switch, lose, or upgrade devices. You have to decide if any of this actually improves the security of your users and if it is worth the cost to implement.
Try something like this:
In your email, state that clicking on the URL will launch the app and log you in for the first time then prompt user to enter their new password. Include a token in the URL which, when handled by your app, does a one-off login and put the user on a "New Password" page.
If a malicious app has also registered your custom URL and steals the link, they should (hopefully) not be able to do much with it. Even if they replicate your interface and prompt the user for a new password, it's not going to achieve anything.
edit: After thinking on this further, as long as you have an active attacker, you're pretty much screwed. The attacker could continue to emulate your app, effectively MITMing you, regardless of what you do, as long as they're able to hijack that initial URL. My solution would only work in the most basic of cases, not really reliable.

Is there a way to skip the "Your domain administrator has approved" page in Apps Marketplace Oauth2?

I have a Google Apps Marketplace (v2) app I am working on setting up Oauth2 for.
I've got everything working, but for some reason when I do a redirect to the authentication page, after, after you select which Google account to use (if like you're me and are testing, you have to pick one of several Google accounts you're currently signed into), I get sent to another page which seems utterly pointless:
This is bizarre and annoying, because I am logging in as the domain administrator!
Does anyone know a way to skip this screen, or what I might be doing to be cursed with this terrible user experience?
I just confirmed that having access_type=offline will always display this page, even with approval_prompt=auto. You will always get back a refresh token as well.
The only way to hide it is to remove access_type=offline on future login requests (ask only on signup).
I believe this shows up only if app requests refresh token for offline access. Also this should only appear first time you access the app after installation.
In order to skip this you need to update app to not request refresh tokens.

Resources