Android accessing secure REST services - javascript

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..

Related

Trusted Web Device Client

I have a public web API for a SaaS. We do not have user accounts for the users except for the admin, simply because the users who are using the system are often non-permanent workers or staff.
Instead we have a client/customer number and a PIN which is used to authenticate and setup the browser client. The authenticated JWT is stored in the browser like any other access token and is sent back to the server together with every API request. This works fine, although we do understand that a malicious actor could potentially extract this JWT and use it to illicitly authenticate as well.
Now we want to add two extra layers of security: IP whitelist and trusted devices.
First we have introduced an IP whitelist. This is straight-forward, we simply check the remote IP against a whitelist created by the admin which is bound to the client number.
Now the problem is with the trusted list of devices. For each client number, there should be a way to trust a device for that specific client number. So the client/customer should be able to use the web API only on the devices it has in the office. The ideal scenario would be that the admin can issue a "trusted device" certificate with a digital signature which sign something like "client number+year+client pin". Then the local manager individual needs to import this certificate/secret manually on the device that should be trusted.
Then for each request our web client app (via javascript) also sends this signature with each request in a HTTP header. I understand this could potentially be spoofed as well but together with the IP whitelist we assess and believe it should be secure enough for this application.
The problem is now, how to implement that? As far as I understand:
I cannot store such a secret in the browser because it might be cleared.
I cannot read the filesystem with javascript. Store the secret in a text file?
I cannot access the device certificate store.
How can I manage (import, store and read from javascript) this digital signature/certificate/secret in the client device? The web client can be anything from a iPad and Android phone to a Windows, Linux, iOS desktop. All web calls are done with SSL. We are not running any native app on the client device, only browser.

HTTPS on localhost for OAuth for a desktop application

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.

Facebook Javascript SDK security issue?

I am trying to embed facebook auth into my application.
My initial effort was to login in browser and obtain code. I pass this code back to my api and obtain access token (that stays with the server) and route all my requests to FB Api through my server. Seemed totally secure to me as my client has no information to be able to make authorized calls to FB as my app.
I however have been looking at FB Javascript SDK to avoid writing code for dialog opening and closing and noticed that it allows me to getLoginStatus and returns me the access token. Also, I went over FB auth flows in their documentation and they say that client-server hybrid flow is okay to do where server actually gives "Long lived access token" back to the client and advises me to use HTTPS (fair).
Now all this gets me thinking if this is a security concern. Can't I as a potential hacker inject some javascript into the user's webpage that could either a) make a getLoginStatus and get the access token or b) just get the access token by making a request to my api server and get the access token and then use that to post (assuming that user authorized my app to do so) to facebook as if my app was doing it?
I am a security newbie and maybe overlooking a bunch of stuff here but could someone help me understand what I'm missing?
Thanks in advance!
PS: I do know I can enable further security to ensure that I need the app secret every time I want to make a request which the client can't do as that information will never be available on client side.
I am not a security expert, just some thoughts: in your question, you are assuming that the hacker somehow injects the script into the webpage in the user browser using malware and that script then interacts with the data you have client-side.
Now, if we imagine this actually happened and the evil script has full access to the web-page data, even if you don't have the access token on the client, what prevents the evil script to make requests to your server and interact with facebook through your server?
Moreover, if the user opens facebook itself and authorizes there, the evil script could be injected into facebook page and do any actions on behalf of the user, just sending the requests to facebook server.
This way, it looks for me that if the situation you describe happened, it would not really matter if you storing the access token client side or not - anyway the evil script will be able to do it's job.
Practically, if you are worried about security - first carefully check all the facebook docs related to authentication and security and follow their recommendations. Second - search for common known attack vectors and recommendations of how to avoid security risks in your application.
If the user already has malware on his computer which is able to alter browser behavior (like inject additional scripts into pages), you probably can't do much about it.
You can only get your access token if you have a valid redirect URI which equivalent to your Site URL on your facebook application settings..
also, it needs permissions before you can post using the facebook access_token.
You can check the API calls at https://developers.facebook.com/tools/explorer/

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.

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