HTTPS on localhost for OAuth for a desktop application - javascript

I am creating a desktop application that using Spotify's oauth api. I am using the implicit grant flow described here: https://developer.spotify.com/web-api/authorization-guide/#implicit_grant_flow
My idea is to have an "Authenticate" button, that you click and it opens your browser. You login/approve the connection with Spotify. Then it sends you to a redirect url.
I want to set this redirect url to 127.0.0.1:58212 or some port on the loopback device.
My question is, should I use https for this?
I am leaning towards yes. One because the access token needs to be secure, and I believe other users on the system could potentially read the message when it is sent, and two because in the time it took the user to log in, someone could have taken over the port.
So I want SSL for encryption of the message, and I want to ensure I am actually talking to my app.
How do I generate certificates in this situation? I think each instance of the application needs to have its own certificate, and I need to somehow inform the computer to trust that certificate during the lifetime of the application.
I could also generate the certificate during installation, and do some step during installation that makes the system trust that certificate.
Am I thinking about this the correct way, or am I going about this all wrong?
I am using electron and express in JavaScript to write my application.
Thanks for any advice.

The best way to securely use Oauth with installed applications such as desktop applications is to use the Oauth 2 flow for installed applications. But this option would have to be implemented by the service provider. Google provides for this option.
https://developers.google.com/api-client-library/python/auth/installed-app
Unfortunately, many services do not implement OAuth2.
To use Oauth 1.0 with installed applications, instead of returning to a callback_url, the service provider displays the auth code to the user which the user can then copy and paste to the desktop application. Check out Trello Ouath integration which allows for this.
The Web Api flow that you are trying to achieve will not work in the case of desktop apps. The redirect uri 127.0.0.1:port is your local uri. The service provider will need, at the very least, your public ip to redirect the flow back to your system.

AFAIK, for a Desktop or a native app it is much better to implement the Oauth authorization code flow. The implicit grant is intended to be used on a device browser and not on a Web View.
If your app uses a Web Service to connect, your Web Service needs a redirect URL that uses https. Luckily most hosting platforms like Heroku provide this to you for free (otherwise you need to buy an SSL certificate which might be a lot of work).
On the authorization code flow, a token doesn't need to see the client, it is all stored in the backend.
Most services allow you to test on localhost with http.
I wrote a tutorial that could give you some guidance on the flow.

Related

The best way to store "app secret" in a mobile web application?

I want to develop a "responsive mobile web application (iOS / Android)" with JavaScript to interact with Smart Contract and blockchain.
I decided to develop a hybrid mobile web application. However, the question is how to store the App Secret safe in case of developing a mobile web application with JavaScript ? Since, we do not want to store it in the mobile and blockchain because of security.
I want to develop a "responsive mobile web application (iOS / Android)" with JavaScript to interact with Smart Contract and blockchain.
Is not clear for me if you are referring to write the Mobile Application as a web site that is full responsive in mobile or if you are considering to write it using a framework like Ionic, React Native or others.
If is a responsive website than please ignore the rest of my answer once there is no secure way of securing secrets on them, as far as I am aware.
Now if is a cross platform Mobile App done with any of the many available frameworks, than keep reading because a possible solution exists to solve the problem of secrets on them.
However, the question is how to store the App Secret safe in case of developing a mobile web application with JavaScript ?
Anything running on the client side will be vulnerable to reverse engineering with tools like Xposed or Frida.
Since, we do not want to store it in the mobile and blockchain because of security.
As already pointed out by you the Mobile or Blockchain are not good places to store the App Secret.
A Possible Solution
To harden the communication between your Mobile App and the API server you should use a Mobile App Attestation service, that will guarantee at run-time that your App was not modified or is not running in a jail broken or rooted device, by using an SDK integrated in you App and a service running in the cloud.
The cloud service on successful attestation of the App integrity issues a JWT token that is signed with a secret that only the API server and the cloud service are aware and on failure the JWT token is signed with a fake secret that the API server does not know. This approach will allow for the API server to only serve requests when it can verify the signature in the JWT token and refuse them when it fails the verification.
Once the secret used by the cloud attestation service is not known by the Mobile App it is not possible to reverse engineer it at run-time, even when the App is tampered, running in a rooted device or communicating over a connection that is being the target of a Man in the Middle Attack.
On this article you can walk through example of how a Mobile App Attestation service in the cloud is used to authenticate a React Native App.
Disclaimer: I work at Approov
Xposed
Xposed is a framework for modules that can change the behavior of the system and apps without touching any APKs. That's great because it means that modules can work for different versions and even ROMs without any changes (as long as the original code was not changed too much). It's also easy to undo. As all changes are done in the memory, you just need to deactivate the module and reboot to get your original system back. There are many other advantages, but here is just one more: Multiple modules can do changes to the same part of the system or app. With modified APKs, you to decide for one. No way to combine them, unless the author builds multiple APKs with different combinations.
Frida
Dynamic instrumentation toolkit for developers, reverse-engineers, and security researchers.
JWT Token
Token Based Authentication
JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

Proper OAuth2 flow for public first-party clients

I'm a regular reader here at stack overflow but this is my first question.
I'm developing an authorization-server using the OAuth2 specs. And I just got stuck with how do I ensure the first-party client authenticity while using the password flow. I read many forums and this is what I got:
Javascript single-page clients
This blog post by Alex Bilbie, he states that to avoid the client_secret problem we should just:
It’s simple; proxy all of your API calls via a thin server side component. This component (let’s just call it a proxy from here on)
will authenticate ajax requests from the user’s session. The access
and refresh tokens can be stored in an encrypted form in a cookie
which only the proxy can decrypt. The application client credentials
will also be hardcoded into the proxy so they’re not publicly
accessible either.
But now this proxy can be accessed by someone impersonating my
angular app. And then I came across this blog post from Andy
Fielder: How Secure is the OAuth2 Resourc Owner Password Flow
for Single Page Apps. He basically says to rely on CORS to
avoid impersonating JS clients.
It is a good idea to use both approaches to secure my JS app?
Native Apps (Desktop and Mobile)
In the case of mobile apps, I only found cases for Authorization
Code and Implicit flows. This is not what I want, as the redirects
will compromise the user experience. So my thoughts on this is:
I will use the ROP flow and then register the client with a
client_id generated for this particular installation and attach it
to the user account, receiving the access_token and a
client_secret as response. Any other token request made by this
client MUST carry this credentials (as the client_id is specific
for the installation, I will be able to check if this client is
already authenticated). This way if someone uses any credential for
impersonating a client, or even registers a bogus client, I can take
mesures to revoke the user and client access.
I know that this can be overthinking, and I also know that some of this matters doesn't avoid anything. I just feel that is my job to protect my API as much as I can.
I would really appreciate your thoughts about this matters! Am I really overthinking? Should I just use the concept of a 'public client' and carry on?
Thank you all and happy coding!
First of all, this problem is not a common priority because most applications are developed first with website, and after with the API. This is probably the reason because no one knows how to deal first clients with oauth2, because everyone have developed other ways to do that and oauth2 is needed only to grant user access to third party applications.
Even if you have develop the oauth2 authorization server only for your first clients applications (thinking about a single authentication mechanism instead of developing many), you should try to develop the authorization code or implicit grant types. You will realize that you need a way to check what user is actually logged in.
The two common methods are:
user session (based on Cookies)
user access from localStorage (based javascript)
In either ways you need to check your application security, user session is vulnerable to CSRF, localStorage are vulnerable to XSS. There are a lot of articles about how to secure your website against either, so I will not suggest anything here, you just need to know that they exist.
Now that you choose your authentication method we can start to do some consideration about:
Javascript single pages applications
Proxy
Having a proxy that filter all requests in my opinion is like to have a door with the keys always inserted. It's useless even build the door.
However, for session based authentication it's the only way to do it. Allowing session authentication on your Rest API will open to CSRF security issues, so you need to have a proxy layer that get the user session, retrieve the access token from the session and do the request to the Rest API adding the Authorization header.
CORS
With this method you need to store the user access token in the localStorage, because the token is retrieved from the Js client directly.
Using CORS you are sure that other websites cannot do requests to your Rest API from a browser. But your first client need to be public (ie: it does not have a client_secret).
Native Apps (Desktop and Mobile)
In my first application I tried to use the same mechanism that you suggest to secure the auth flow. However that type of mechanism require that you identify every user client in an unique way. This is not possible in iOS for privacy reasons and with some probability it will denied in the future releases of Android. So you should rely on a public client and add only the client_id in your native application code.
This means that your native app client/your js client can be impersonalized? Yes, and there is no way to prevent this with oAuth2 resource owner password credentials grant type.
The main reason about this is because oAuth2 is not for authentication, only for third-party authorization, and that grant type was added only for specific third-party applications trusted enought to use directly the user password. You could read more about this argument here and here.
At the end
You still need a way to auhorize your user, and I think that the best you can achieve using oAuth2 is what Auth0 did.
Essentially this Saas manage your users with an oAuth2 server + OpenID connect, so you are always managing your users like its a third-party application and everything works fine.
Indeed, you can see on this page that for mobile applications they suggest to use a browser based login form, because the native one can be impersonalized by everyone that decompile your application, but if you wrap it into an authorization code flow it works fine.

Secure Website in Chrome Kiosk Mode

I have a little Node app on heroku. It's embedded in a Chrome kiosk app.
I would like the app to only be accessible on the Chromebooks that have it installed in kiosk mode.
I've tried HTTP authentication, but after I put in my password and username, the app never loads. However this is also not ideal in the first place, as I would like to avoid requiring a password on the Chromebook.
Any ideas?
If you provision the chromebooks yourself, you might be able to use TLS client authentication.
You would install an ssl certificate on the chromebook once which you can then use to authenticate to the web server. A nodejs example can be found here http://nategood.com/nodejs-ssl-client-cert-auth-api-rest
There is also a passport.js module for this https://github.com/ripjar/passport-client-cert
In theory a user can install the certificate on his own, he would get a message asking him to confirm the installation of the certificate, hit okay and that's it.
But be aware, that the certificate can easily be extracted from the chromebook via the settings.
If I understand correctly, you want to make your website only accessible from the chromebooks you configured. Please clarify if this is not what you meant.
Then you can have a landing page (can require authentication) that generates a random token for your chromebooks on first run only. Store this token in a cookie or local storage, and send it every time the app runs to verify on the server.

Android accessing secure REST services

I have exposed the functionality over REST services, which only authenticated user can access. My clients are JavaScript based code running on browser and Android clients.
Code is using google+ based authentication ( for both JavaScript and Android). Now with browser client it is quite easy. As REST server can determine easily with passed access token, whether browser client is already authenticated or not.
However for android client; how REST server would know, that it is already authenticated. Is there any way to get the access code in android once user as has signed it. JavaScript client get access token, is there any token in case of android which can be used.
Yes I can implement oAuth (https://developers.google.com/accounts/docs/OAuth2UserAgent) for android client without going with google+ sign-in directly. That would solve the problem, just wanted to check whether I can do without. Appreciate any help with this..

Facebook API: How to authenticate a web app

I am attempting to write a plugin for a webapp that integrates it with facebook using the Javascript API. The application is installed by our customers on their own servers each with their own site names. This poses a problem to me as Facebook wants me to specify a site url for the application. This url is going to be different for every customer. Creating a new application for each customer is not an option.
In my research of this problem it seems that I have to pretend to be a desktop app and follow that authentication path. I cannot figure out how to do this.
Anyone have any idea how this can be done?
Are you going to host the app as a canvas app or outside facebook?
Is the url important to you? There is a strict one-to-one relation between base-url and application.
What many apps do is host the apps as directories in their domain. For example http://crazy-fb-app.com/customername
That's your options basically if you want to use Javascript SDK.
If you're going to be using server side technology you could have the user authorize the application while requesting permission to access user's data while he's offline. in that case you will receive a non-expiring (or long-expiring) authentication token which you can use from the server to make Graph API calls on behalf of the user. For some stuff you can obtain an Application Auth token (which is shorter and non-user-specific) to make calls to the graph.
Rotem

Categories