CSRF in Ionic with multi tenant and multiple domain JHipster backend - ionic-framework

I have a JHipster multi tenant backend with domains like tenant[.env].domain.ltd with csrf enabled.
We are making a mobile app with Ionic and this app can store authentications on several tenants.
In this mobile app we set <preference name="Hostname" value="domain.ltd" />.
How to deal with the csrf token ?
The backend sends to the mobile app an XSRF-TOKEN cookie for .tenant[.env].domain.ltd that is not accessible on the client side because the domains doesn't match and thus the client cannot set the given token in the request's headers.
Should we disable csrf for the mobile app ? What's the best approach to do so ? On which value should we filter to disable csrf if it's the only solution ?

Ok, I finally managed to get it working. At xsrf token cookie generation I just test if the request is from the mobile app. If so I set the cookie domain to .domain.ltd.
The only point I'm not sure about is the way I should determine that it's a mobile request. I actually use the Origin header.

Related

How to communicate frontend with microservice architecture?

I'm struggling with setting up reliable and performant solution to communicate frontend with different microservices. I do not really now how to maintain (maybe not need) CSRF between my frontend and end services
Solutions stack: PHP, Laravel Passport, JWT, oAuth 2.0, Axios
Current approach:
Actually I've started up with approach from Laravel's passport
https://laravel.com/docs/5.4/passport#consuming-your-api-with-javascript
Using oAuth 2.0 to authorize user from website A to service B.
JWT token is returned for further communication.
Token is saved in cookie within website A
Once user is authorized website A uses JWT token to manage requests without additional to oAuth server, by sending JWT token as cookie using HTTP headers (withCredentials) to authorize user.
For each website A's request there was CSRF token created from service B since user is authorized and cookie could be applied by another unauthorized website to access service B. That was killing my performance since it has to retrieve CSRF for each request made. (that what I actually assume from laravel passport approach and need to create CSRF with JWT token - maybe that was mistake)
My concerns:
Regarding to of James Ward post:
http://www.jamesward.com/2013/05/13/securing-single-page-apps-and-rest-services
The easiest way to do authentication without risking CSRF
vulnerabilities is to simply avoid using cookies to identify the user.
Cookies themselves are not the cause of CSRF vulnerabilities. It’s
using the cookies on the server to validate a user that is the cause
of CSRF. Just putting an authentication token into a cookie doesn’t
mean it must be used as the mechanism to identify the user.
From my understanding setting JWT with website A's cookie with its domain set could not be accessed via any other site from outside. Since that there is no possible way to make request to service B without accessing JWT.
So do we really need CSRF then to secure potential attack to service B while using JWT?
If so, how could I achieve the best (in term of performant) way to generate CSRF through different services to be sure that communication would not be vulnerable for attack from different sites?
Any advice will be appreciated!

Use LinkedIn JSAPI credentials cookie to authenticate a user

We would like to implement "Sign-in with LinkedIn" in our app. Since the app has JS fronted and RESt-based backend, we decided to exchange JSAPI tokens for REST API OAuth tokens as described here.
If a user successfully signs in, the frontend sends credentials cookie with client-side bearer token and member ID to the backend. On the backend we check if a user with such a member ID already exists and if not, we exchange JSAPI token for REST API OAuth token, retrieve user details from LinkedIn a store it in our database.
Now the question is if we can use that cookie to authenticate each user's request to our REST backend. After a user successfully signed in via JSAPI, the cookie should be automatically passed to our backend on all subsequent requests so we can check member ID. Are there any drawbacks that we missed? Or is this idea as a whole wrong?
Should we rather authenticate a user only once by means of the cookie and then issue our own authentication token and send it back to the client?
The way cookies work in general is they are passed on every request to the domain they belong to. LinkedIn is setting a credentials cookie to your domain.
As long as you are validating those credentials on every request it's perfectly acceptable to use their tokens as authentication.
Personally I don't find that to be a great idea and would prefer to validate their credentials once and create my own auth token to use from there on out. You can always set that token to expire at some-point and re-validate the LinkedIn credentials (which will still be getting sent on every request anyway). This limits the amount of times you're checking with LinkedIn and should increase the responsiveness of your app.
Either way could work.
If you are using the LinkedIn cookie to validate a user by member id, you should validate the cookie's signature on each request per section 2 of the doc you linked and question 2 of the FAQ.
Using your own token could make it easier to implement an account which belongs to your app and is not necessarily connected to LinkedIn, assuming there's the potential to either connect solely with some other service(s) or no 3rd part(y/ies). Still should validate any time you trust the member id in the cookie though.
The doc provides a validation example in PHP, and if you're interested in improving a ruby version, I have a shameless plug.
The flow that you've outlined in your latest comment of going straight for the OAuth tokens is the best way to go if you were only signing in to convert the JSAPI tokens to OAuth tokens and then not using the JSAPI further. If you were planning to actually use both the JSAPI tokens within your front-end app and the OAuth tokens on your back-end, then it's better to take the conversion route.

How do I handle iPhone requests to a Ruby on Rails backend?

We are creating mobile support for our ruby on rails website, and ran into the problems of handling authenticity tokens.
As previous articles have mentioned, authenticity tokens are created on the rails server when a form is created then placed on a form page to prevent tampering.
Understanding the Rails Authenticity Token
Now we can handle the requests from a mobile phone by disabling the csrf
protect_from_forgery
My question is what is the best way of secure external mobile post interfaces to our ruby on rails instance?
You could use OAuth. The app would present the server with a key and secret, that the server could validate. In response, the server gives the app a token. All subsequent requests made by the client must include the token in an Authentication header.
This would ensure, that only authorized clients access your server. And to be authorized, a client would have to acquire a token using a known-only-to-the-client-and-server key and secret.
I am sure there are other solutions too, but you get the idea.

Use Plone to authenticate users from mobile devices

I'm starting to create an iPhone/Android app that will need to use Plone users (i.e. register on the website and then enjoy the app on your mobile).
What's the best approach on doing this? I've seen some apps using OAuth or other techniques, which ones currently supports Plone4 (4.0.3 exactly).
I have the users on a LDAP server (OpenLDAP) but even that I still have to log them on Plone to be able to send and retrieve data from there to the mobile phone.
You have 3 options, and what you choose is dependent on what your skills are and how much time you are willing to invest:
Basic auth
Have your user enter a username and password into the app, and just use HTTP BasicAuth headers to access the site. Plone supports Basic auth authentication out of the box.
This is not the most secure method; passwords are basically sent base64-encoded, so you may want to use HTTPS to communicate with the server. A good idea in any case for authentication anyway.
Cookie authentication
Send a POST request with __ac_name and __ac_password items to '/login_form' on your Plone site, and capture the Set-Cookie header on the response, containing the __ac cookie. That's a tk-auth authentication token you can use on any subsequent request. This is a secure cookie, but any attacker sniffing the HTTP communication stream could re-use this, so again HTTPS is the secure way to communicate.
OAuth
Plone does not (yet) support OAuth out of the box, but integrating with python-oauth should be trivial. This would most likely require a PluggableAuthSystem (PAS) plugin to be written.

How to allow either a) HTTP auth without CSRF token + SSL or b)require CSRF token with devise?

I have a Rails 3 app configured with user registration using devise running on a server. I am allowing people to login to the server through the website and also allowing people to create accounts and login using an Iphone App.
When people are using the Iphone app, I'd like to support these two actions:
a) Signup for account without CSRF (does this cause any security issues)?
b) Log in with http auth secured by SSL
c) Any POST requests to the server after logging in to be secured with http auth with SSL.
When the user is on the website, I want to require CSRF tokens on all actions (so that the user does not type username and password each time).
Thank you for your help.
You can selectively disable the CSRF token on a controller or individual action methods.
class StatsController < ApplicationController
skip_before_filter :verify_authenticity_token
...
end
I'm actually looking to do something similar, I'll have the iPhone use a different domain name and selectively disable the :verify_authenticity_token filter based on a couple of conditions. This is only to hold us over until we can get our OAUTH2 implementation up and running.