Preventing from using my REST APIs from outside my own client JS app - security

I built an AngularJS application calling some REST API's belonging to my own backend (using Play! 2.2).
I'm using Facebook OAuth client in order to authenticate my users.
As being a Javascript App, my Facebook App Token cannot be "hidden".
Thus, anybody who picked up the Facebook App Token, by just reading the Javascript code could grab a user access token in a "legally" way and therefore use my REST API's.
How could I prevent it?
What is the best practice?
One way would be, I think, to use the server side Facebook's OAuth mechanism, rather than the Facebook Javascript SDK.
In this case, the Facebook app secret would be stored on my server and unreachable from the outside.
But as being a Single Page Application on client-side, I really want to avoid page redirection and benefit of the "popup" feature that comes with Facebook Javascript SDK.

There are a couple of things you can do.
Using the server side ("code") OAuth flow for facebook auth is much more secure. You can still avoid redirects by opening your own popup to initiate the login sequence, similar to what the Facebook JS does (only it goes to your server first).
Enabling HTTPS on your application is usually a good practice...
And if you're worried about cross site forgeries you can implement something like an anti forgery state token. See http://blog.codinghorror.com/preventing-csrf-and-xsrf-attacks/ and also google's instructions here https://developers.google.com/accounts/docs/OAuth2Login#createxsrftoken .

Related

How you organize the interaction between Angular app and Xero OAuth2.0?

I am building Angular app that should interact with Xero API. Xero doesn't provide any SDK for Typescript (https://developer.xero.com/documentation/libraries/overview), but Node JS SDK seems to be the most useful lib for my task. But I am in stuck in how to organize the workflow between my app and their https://github.com/XeroAPI/xero-node-oauth2-app . I mean - I'd like to have some advises from the person who has already made similar apps (Angular + Xero) on following questions:
1) in this guide https://developer.xero.com/documentation/oauth2/auth-flow they say that user should open the page with URL like https://login.xero.com/identity/connect/authorize?... - but is there any way to make user log in without UI? If not -
2) how this process can be made in my case? In my Angular app I can make a button 'Log in to Xero' that will open new window:
window.open(xeroUrl, 'xeroAuth', 'location=yes,height=770,width=620,scrollbars=yes,status=yes');
where User log in, provide access to his organisation. The session tokens are created on the backend. But what next? How can I pass those tokens to my Angular app from that new window and then use them to make calls to Xero API?
3) Is the way to open new window for loggin in to Xero suitable for this case or maybe there is a better way to log in to Xero and get session tokens?
Thanks in advance for help.
Unfortunately, SPAs are not compatible with the Xero API.
You'll need a web server to manage your local session (OAuth flow, storage of Xero API tokens), and for your interactions with the Xero API.
While SPAs are a tempting option (they are convenient from a deployment point of view), there are changes coming to how browsers handle cross-site cookies, which break how SPAs perform session management.
I'd suggest reading https://leastprivilege.com/2020/03/31/spas-are-dead/ for more information and a discussion of the implications. The authors of the article created OIDC Client JS which is a great library for doing PKCE-based SPA auth in the browser, though it's only useful for same-domain applications now thanks to the impending browser cookie changes.
Further to this, the Xero API does not support CORS, so even once you complete the OAuth flow, the browser would be prevented from performing API requests from your Angular SPA.
To answer the specific questions:
1) The user will need to log in to Xero and grant consent for your app the first time they use your application. If you're storing server-side refresh tokens after the initial consent, your user will only need to log in to your local session, either via Xero SSO or another mechanism (user/password).
2) To create the initial Authorisation Request, it's best to use the node.js starter app. It will manage the OAuth redirect flow for you (it uses the excellent openid-client open source package for this).

Facebook authentication through express server for Unity3D application

I want to use express server with passport-facebook to authenticate facebook users. the client side is Unity3D application. I have no problem authenticating users if it was javascript client, since if the authentication was successful, it redirects to the index page. However, since I'm using Unity3D as client, I was wondering what will be the redirect function.
I haven't had a chance to implement this myself yet, but I was just reading about it.
You are gonna have to use the Facebook Unity SDK and login in the unity app. The SDK provides all the functionality you would expect. As for using the authentication in Express, you would be implementing somewhat of a Reverse OAuth Flow. I don't believe Facebook wants your app doing this, but once authenticated in Unity you could send the temporary access tokens to the Express API at which point you should be able to use the Node.js Facebook SDK.

Is there a way to use CSRF protection and JWT in a sails app together but not at the same time?

I'm working on an application using sails. web and mobile.
I want to use CSRF protection that sails provides when the app is visiting on the web. And if a request is send by the mobile app. send with the payload a jwt.
On the sails' documentation I found a property csrf.routesDisabled that disabled the CSRF for some routes. But that is not what I want. I'm trying to find a way to for example, check if the parameter jwt is send in the post request. And if the parameter was send then check and validate it. else, check for _csrf value of the form. Is this possible?
or the csrf protecction works before any information is send to the server?
my better choose is use jwt in the web app too?
any other good idea for solving this problem is welcome
thanks
Sounds like you've built the web app with SailsJS and you're trying to reuse the controller actions as REST endpoints for external applications.
Really what you should do, is decouple the data access from the front-end. Have an isolated REST API - using token authentication - which is used by both a web front-end (and any other applications).
For example, I'm currently working with a SailsJS REST API, used by an EmberJS front-end and an iOS app. Both front ends login using user credentials, in order to receive an authentication token. This token is then used for any future requests. A policy locks down all but the login authentication endpoint, to validate the token

User Registration and Authentication/Authorization with MEAN Stack

I need to register users with my AngularJS app. I would like hashing with salt to take place when storing the password into MongoDB. Then I would like the same user to authenticate and authorize for some of the actions he/she could take.
I come from Java/JavaEE background and have never done any registration/authentication/authorization work for a JavaScript app using MEAN stack.
Is there any reference/sample MEAN app I could refer to for understanding registration/authentication/authorization?
Should I be using Cookies or tokens for authentication?
Is there any reference/sample MEAN app I could refer to for
understanding registration/authentication/authorization?
I preffer passport.js. Plugs to express, Supports both Tokens and Cookies, it is easy to work with Angular.js via ajax.
Should I be using Cookies or tokens for authentication?
Take your own decision, but read this and this and this
I come from Java/JavaEE background and
Not clear but if you are new to web development, may be you should read this excellent post

The "right" way to do oAuth from a mobile client

I am building a cross platform mobile application (using the Xamarian tools, MonoTouch / MonoDroid). I am trying to work through the authentication workflow and am running into a stumbling block. I have searched all over for a clear answer and have yet to find it.
Here is an overview of my current setup.
I have a web site built in nodejs.
I use passport.js to do oAuth login on the web site. This works great, users can login to my site using Twitter or Facebook.
Now I want to extend this same login functionality to my mobile clients.
I see 2 options
Embed the app id and app secret's in the mobile clients and make direct oAuth calls to FB or Twitter from the mobile app
Proxy the oAuth calls through my existing nodejs web server (keeping the secret keys on the server)
Option 2 appears to be the preferred way (as it avoids having to "ship" the secret in the mobile apps).
I have the proxy approach mostly working.
I open a WebView in my mobile client and point it at http://mysever/auth/twitter
This runs through my existing passport.js code and redirects the mobile WebView over to the Twitter login page.
The user then enters their creds on the twitter webpage on the device.
Twitter then calls my oAuth callback URL (which is my nodejs web server).
My server and Twitter handle the back a fourth handshake of obtaining the user profile information (As I understand it, this is the key to this approach, my server and twitter handle the handshake, the mobile client doesn't have to do anything or pass any tokens during this process)
Here is my problem:
It is this last step that stumps me. Once the handshake is complete on my server I have the user information I need on the server and need to send it back to the mobile client application
I can't figure out any way in the WebView control to grab the response object and grab a cookie, or header value (for instance) (this seems true for Android and iOS). I don't think it is platform specific. I think I am trying to do something that a WebView widget in mobile platforms just don't suport. It makes me think I am missing something obvious.
The only thing I have figured out is to have my web server "redirect" the mobile client browser to a fake URL that has the user info in the querystring. Something like myapp://info?userid=1234
Then in the mobile app I can hijack the URL loading and grab this url and get the data I need. I can then stash this userinfo, close the WebView control and move on to a native screen in my mobile application and user the userinfo in any subsequent REST calls to my nodejs server as a means of identifying the user.
This is massively kludgy for multiple reasons. The biggest of which is that the url is sent over the wire unencrypted and has all the data in plain text.
There has to be a better way to get the data from the web server back to the mobile client?
Or am I doing it all wrong?
The most straightforward way to implement oauth for Xamarin, both for iOS and Android, is using Xamarin.Auth. The starter documentation for the client is here. I think it should maintain everything securely and you will not have to worry about having to use your node server as a proxy.
You will need to provide your Application ID as part of the calls, but I don't there are too many or any security issues to worry about there.
I know this is going against what you already have implemented, but maybe this could help simplify things a bit.
This is the same dilemma that I have been dealing with.
This is how I currently deal with it.
In my app the client can come directly or via another service such as facebook which is my main one and hence the one which I have concentrated on.
Facebook can either redirect via a POST (desk apps) or a GET (mobile).
I check the initial request so see if has a service identifier - here is the facebook GET for example.
app.get('/', function(req, res) {
var paraUrl = URL.parse(req.url,true).query;
//The fb_source is shown -
//i need to go striaght to the facebook authorization since
//its coming from
//from a mobile device.
if (paraUrl.fb_source){
res.redirect('/auth/facebook'); //this is the passport part
return;
}
res.sendfile('index.html');
}
The facebook POST is slightly different in that you get an access token encode in base64url. The GET gives you a code which you can exchange for an access token but I had problems with it and just opted for tying into the passport system.
If a client comes direct I check for the session or a encrypted cookie which ties into the local strategy. This then checks the db for an access token which can used to access the facebook api for example.
If a client is unrecognised they are given the option to authenticate via facebook, google etc.
The main thing is that only 2 pieces of information are stored with the client, the passport session id and my app user id
connect.sid - encypted cookie
userId - encypted cookie
I would be interested to find out how other people are dealing with issue

Resources