Significant differences between Cookies and JWT for native mobile apps - ios

I have been using Cookies for authentication and session control in my web apps, and am content with its functionalities.
I was introduced by an iOS app developer that the new hot thing is JWT (JSON Web Token). He told me that JWT is the way of doing authentication and sessions for native mobile apps, and without giving specific examples, he suggested that both iOS and Android apps have various problems with Cookies.
So I looked up JWT, e.g. http://angular-tips.com/blog/2014/05/json-web-tokens-introduction/ and https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/, and I failed to see why it is significant better (or even that different) than Cookies, and more specifically, why it does better in native mobile apps. It seems that, at least iOS, handles Cookies just fine (Persisting Cookies In An iOS Application?).
So my question is, for a native mobile app that interacts with a server-side API, what are the specific advantages and associated use cases for using JWT over Cookies for authentication and sessions? Please highlight the ones that Cookies simply cannot do or does it much worse.

We software developers (sometimes) have the tendency to apply the new hot thing everywhere we look; it's possibly a variation of the saying if all we have is an hammer, everything looks like a nail where in this case we just feel a desperate urge to use this new thing we learned about.
One interesting point about this comparison is that neither JWT or Cookies are in fact authentication mechanisms on their own; the first just defines a token format and the second is an HTTP state management mechanism. Only this is sufficient to give us an indication that advocating that one is better than the other is wrong.
It's true however that both are vastly used in authentication systems.
Traditional server-side web application have used cookies to keep track of an authenticated user so that they were not forced to provide their credentials at every request. Normally, the content of the cookie would be an (hopefully) random generated unique identifier that the server would use to find session data stored on the server.
However, for a new type of web application - the API - it's more much more common to accept a token (in JWT format most of the times) as a way for the server to decide if it should grant access to who's making the request. The reason for this is possibly because while a traditional web application had one major type of client, the web browser, which has full support for cookies, the API's are generally used by much simpler HTTP clients that don't natively support cookies.
I think this is also why we could possibly argue that token based authentication makes more sense for native mobile applications. These applications generally depend on a server-side Web API and we've seen that if the API supports tokens it will increase the range of clients that can use it, so it's just the most practical thing to do.
In conclusion and to try to answer your concrete question, I would say JWT's do have an advantage over cookies on native mobile applications just because of the fact they are currently in very common use, this means more learning resources, SDK's, known pitfalls (mostly because someone else already did it and failed), etc.
Nonetheless, only use them if they give you the security assurances you need and end up simplifying your scenario. If you haven't gone through it already, I think you'll also appreciate Cookies vs Tokens: The Definitive Guide.

I cannot speak for Android but on iOS cookies work with URLSession as good as headers. Once you can utilize the (standard) API right (e.g. dedicated, properly configured session with cookie storage per web app...), iOS should be a rather negligible factor to this decision.

Related

New single page app needs to authenticate to legacy app using Shibboleth

I am creating a new React SPA. Users of a legacy app need be able to use the new app without re-authenticating. So I need to support SSO.
It's important to note that it is also required that users of other (currently unspecified) apps should also be able to use the new app without re-authenticating, so whatever approach I take needs to be sufficiently decoupled to potentially allow this.
The legacy app supports authentication via Shibboleth, the new app currently has no authentication method, but uses JWT for authorisation.
I'm wondering if anyone has any experience of such a scenario? It seems to me that I probably need to be create an OAuth2 authorisation server for the new app to talk to and I need to somehow bring Shibboleth into the mix for the authentication, maybe with the authorisation service acting as a Shibboleth Service Provider. Googling around hasn't revealed much useful info.
Is what I've described along the right lines? I know it's very high level and woolly, but I'm really not sure of the approach to take. Any advice, information or experience in this area would be gratefully received!
GOALS
It's a little bit of a subjective question, but the main goals are usually as follows:
Focus on building your UI and API security in a future facing manner
Also provide good Login Usability
Also deliver on non functional requirements such as availability / reliability
AUTHORIZATION SERVER
On the first point, the modern option is to integrate UIs and APIs with an Authorization Server - perhaps as in My Tutorial. Your architecture is then good, but the migration is not trivial.
FEDERATING TO SHIBBOLETH
The Authorization Server can then redirect to Shibboleth and talk SAML2.0 to achieve Single Sign On, as you suggest. It is a complex solution though, and may be a backwards step in some ways.
AVAILABILITY
This is usually a big concern, and most companies use a cloud provider such as Azure / AWS due to its high availability / low maintenance / low cost. Would this be a better option for you?

Browser applications and auth tokens again

I've been reviewing how we should handle OAuth authentication in our browser application (SPA), and there's a whole bunch of articles out there that makes it all really confusing... I'm really missing something concrete and best practice guidance for a very simple setup.
We have this ASP.NET Web API 2 that's protected using tokens issued by IdSvr3. So far so good. Works with native clients and server apps.
Now to the browser stuff... Looking at a sample such as JavaScriptImplicitClient which uses the oidc-client-js library to retrieve tokens using the implicit flow. The token is stored in the browser which is accessible using JavaScript and there by open to XSS attacks.
In order to avoid that, suggestions indicates storing the token in a cookie and then setup a mechanism to prevent CSRF attacks.
Seems simple, but what sets that cookie?
Is it the IdSvr? Doesn't make sense since it's the API that needs the cookie.
Is it the API? During Implicit Flow login, are the user then redirected to the API which sets up the session and then redirects the user back to the SPA with a Set-Cookie header? Then the cookie will be present to the API on subsequent requests.
Third solution? Some is mentioning creating a second 'API' that proxies requests to the 'real' API, but sets the auth header.
Do you have any samples of such a setup, or can you maybe provide some hints about how you'd do it?
Personally, most of the times the avoidance of Web Storage for tokens due to XSS seems to be exacerbated a bit. There is one important question, if your application is vulnerable to XSS, will the impact of this vulnerability be significantly increased because you also leaked tokens or you already got totally pwned even if you didn't store tokens there and you're in the same type of trouble.
I made a comparison of the pros and cons of a few approaches to store access tokens in web browser application which you can check in this answer to a related question.
In the end each case ends up having their own specifics which may tip the balance between one approach versus the other (cookies or web storage). Just don't ignore any option from the start and look at all of them based on your requirements.
I bet that there are implementations out there that store them in HTTP-Only cookies to avoid the XSS issue with Web Storage and then end-up using a CSRF mitigation strategy that is vulnerable in the face of XSS.

Sharing AccessToken to clients (say browser) is a security concern?

We have a MVC application, in which we are making web api calls from browser to get the data and display it in browser. Since our application is Claims aware, the client need to pass AccessToken in order to access the web api.
Since the browser is not a trusted client (server does not have much control over browser), is it advisable for clients (browser) to store AccessToken? are there any better design patterns here without compromising security?
You'll have to trust the browser to some degree, otherwise your web application won't be of much use. Before tokens and API's, traditional server-side applications trusted that session identifiers could be stored by the browsers in cookies.
With tokens, the principle is the same, but the devil is on the details. First of all, assume HTTPS needs to be used, otherwise you might as well give up. Having HTTPS in-place, you can assume to some extent that sending the access token and/or cookies to the browser is secure.
After that, you need to worry about the characteristics of the storage the browser will use. For that I would recommend to read the Where to Store Tokens? section of the Cookies vs Tokens: The Definitive Guide article.
The real problem is that there are a sufficient number of other small details that is almost impossible to provide a definitive list and even though they are small details they can have very big impact on the overall security of the system. The only honest recommendation is that if you want to roll your own authentication system you need to be prepared so spend significant time and resources learning all these details.

Authenticating Requests from iPhone with Framework API Token

So I'm creating an iOS framework that will be a static library that developers will add to their project, when they create an account on our site I'd like to give them a unique token that they put in their app to use my static library.
For iOS dev's, think TestFlight, you sign up, get an App ID and then run [TestFlight takeOff:<#some-key#>];
I'd like to authenticate the requests that the framework makes to my REST webservice (using https).
Is there anything I can do to prevent people from "breaking into the app code" and stealing the developers api token and using it to make requests? My api endpoints will not be public information, at least for now. and I can't authenticate the user because it's a framework and that would be an awful UX.
The question is, is there anything I can do to prevent this sort of behavior? Should I even care? I will charge the developer per X requests eventually so I was hoping to authenticate this so we don't have spammers racking up a bill for the developer.
How do other iOS frameworks handle this?
Any design ideas and criticism welcome.
I'm not sure what you're trying to do is ever possible. If the text is in the client code, it can be pulled out. SSL-pinning won't really help you here either because the cert is in the client binary as well.
One way you might be able to get close is to use the developer's authentication system. Say a user logs in into the developer's auth system, then server side you generate a short-lived key for that user. Then the client code can be passed (over SSL-pinning) that short-lived key and use that to make your API calls. However, this requires the developer to actually have a secure auth system, and without SSL-pinning, they're vulnerable to a simple man-in-the-middle attack which will reveal the short-lived key.
You can try to minimize the damage by throttling API calls on your end, or trying using per-app heuristics to approximate what normal API usage would look like. Anything out of the norm will get flagged as potentially hacker based. That might be enough to flush out most of the wanna-be-hackers. The true hackers will learn of the throttling and be clever about circumventing it...
Your safest bet is to make it a server-side library instead of a client-side library. However, that's certainly not a super-sexy solution either. Not all apps have a server side component... and even if they do, once the developer's server is compromised (ie. gets spammed or hacked, etc) it's game over once again. But, in the end, the nice thing about a server-side solution is that you're at least less vulnerable to an attack and you put the responsibility of securing the system on the developer.
What's really lacking here is some form of Apple-based verification for network calls originating from Apple devices.... but that probably won't ever happen. :)

Restrict access to web service to only allow mobile clients

I'm currently building a mobile application (iOS at first), which needs a backend web service to communicate with.
Since this service will be exposing data that I only want to be accessed by my mobile clients, I would like to restrict the access to the service.
However I'm in a bit of a doubt as to how this should be implemented. Since my app doesn't require authentication, I can't just authenticate against the service with these credentials. Somehow I need to be able to identify if the request is coming from a trusted client (i.e. my app), and this of course leads to the thought that one could just use certificates. But couldn't this certificate just be extracted from the app and hence misused?
Currently my app is based on iOS, but later on android and WP will come as well.
The web service I'm expecting to develop in nodejs, though this is not a final decision - it will however be a RESTful service.
Any advice on best practice is appreciated!
Simple answer: You cannot prevent just anybody from acecssing your web site from a non-mobile client. You can, however, make it harder.
Easy:
Send a nonstandard HTTP header
Set some unique query parameter
Send an interesting (or subtly non-interesting) User Agent string
(you can probably think of a few more)
Difficult:
Implement a challenge/response protocol to identify your client
(Ab)use HTTP as a transport for your own encrypted content
(you can probably think of a few more)
Of course anybody could extract the data, decompile your code, replay your HTTP requests, and whatnot. But at some point, being able to access a free Web application wouldn't be worth the effort that'd be required to reverse-engineer your app.
There's a more basic question here, however. What would be the harm of accessing your site with some other client? You haven't said; and without that information it's basically impossible to recommend an appropriate solution.

Resources