Using Ory/Kratos login/registration API flows - security

In the documentation, there is a large, bright red warning:
Never use API flows to implement Browser applications!
Using API flows in Single-Page-Apps as well as server-side apps opens up several potential attack vectors, including Login and other CSRF attacks.
The documentation does not elaborate on what these attacks are. If I properly secure my application by storing session data on the server, by allowing only the server to access this API, and by implementing my own csrf protection, am I safe? If not, what attacks am I opening myself up to and what additional measures should I take?
Certainly, there must be a way to secure my application without tearing down the running javascript vm then sequentially being redirected three times just to view a login/registration page. For modern apps, I think users may expect this discontinuous transition for successful authentication, but I don't think it's necessarily expected for just viewing the login/registration page.

There are two ways to use Kratos.
From a WebApp (browser)
From a Native app (iOS, Android...)
The first way is using browser redirects and they set csrf tokens.
The second way does not set csrf tokens since there is no browser involved.
That's why there is a warning stating that any sort of "browser" related application should never use the methodology from the native app flows and vice versa!
For example here is how you initialise the login flow for API clients (native apps)
https://www.ory.sh/kratos/docs/reference/api#initialize-login-flow-for-api-clients
And here is an example of how you initialise the login flow for Browser clients
https://www.ory.sh/kratos/docs/reference/api#initialize-login-flow-for-browsers
The selfservice configurations are for your browser redirect flows (so Browser clients).
All credit for this answer goes to https://github.com/Benehiko.

For more details about the warning, please visit the kratos channel.

Related

Is it insecure to include your login page in your single page application?

My understanding is that, if you include your login page in your SPA, then the user is receiving all of your code before they're even authenticated. And yet, it seems to be a very common practice. Isn't this incredibly insecure?? Why or why not?
An SPA would have all the page structures (html and javascript code for the design of pages), but obviously not data. Data would be downloaded in subsequent ajax requests, and that is the point. To download actual data, a user would have to be authenticated to the server, and all security would then be implemented server-side. An unauthorized user should not be able to access data from the server. But the idea is that how pages look is not a secret, anybody can have a look at pages of the SPA without data, and that's fine.
Well, and here comes the catch that people often overlook. Html is one thing, but there is all the javascript in an SPA that can access all the data. Basically the code of the SPA is an API documentation if you like, a list of possible queries that the backend can handle. Sure, it should all be secure server-side, but that's not always the case, people make mistakes. With such a "documentation" that an SPA is, it can be much easier for an attacker to evaluate server-side security and find authorization / access-control flaws in server-side code which may enable access to data that should not be accessible to the attacker.
So in short, having access to how pages look (without data) should be ok. However, giving away how exactly the API works can in certain scenarios help an attacker, and therefore adds some risk, which is inherent to SPAs.
It must be noted though that it should not matter. As security by obscurity should not be used (ie. it should not be a secret how things work, only things like credentials should be secrets), it should be fine to let anyone know all the javascript, or the full API documentation. However, the real world is not always so idealistic. Often attackers don't know how stuff works, and it can be of real help to be able to for example analyze an SPA, because people that write the backend code do make mistakes. In other cases the API is public and documented anyway, in which case having an SPA presents no further risk.
If you put the SPA behind authentication (only authenticated users can download the SPA code), that complicates CDN access a lot, though some content delivery networks do support some level of authentication I think.
Yet there is a real benefit of having a separate (plain old html) login page outside the SPA. If you have the login page in the SPA, you can only get an access token (session id, whatever) in javascript, which means it will be accessible to javascript, and you can only store it in localStorage, or a plain non-httpOnly cookie. This may easily result in the authentication token being stolen via cross-site scripting (XSS). A more secure option is to have a separate login page, which sets the authentication token as a httpOnly cookie, inaccessible to any javascript, and as such, safe from XSS. Note though that this brings the risk of CSRF, which you wil lhave to deal with then, as opposed to the token/session id being sent as something like a request header.
In many cases, having the login in the SPA and storing the authentication token in localStorage is acceptable, but this should be an informed decision, and you should be aware of the risk (XSS, vs CSRF in the other case).
It's clear that data loaded into an SPA must be secured behind an API through authn. But I think you can also secure layout so it is "less ok" having access to how pages look. With metamodel-driven development, you can serve layout configuration from a secured API. I am not talking about serving HTML (that's SSR), I am talking about serving JSON. That layout configuration is nothing but a JSON file on the server defining the content of your screen (fully or partially). Then your SPA code turns into a generic interpreter/render of that metamodel that parses the payload, renders components and binds data. If your API is L3, voilĂ , you get a fully working API-driven app.

is authentication with client side rendered app and sessions possible?

No matter how I reason about it, it seems as if there is no secure way of implementing a client side rendered single-page-application that uses/accesses information on sessions for authentication, either via cookies, without severe compromise in security. I was mainly looking to building a React app, but it seems as if I will need to build it with SSR for a relatively secure version of authentication.
The use case that I'm especially thinking of is where the user logs in or registers and then gets a cookie with the session id. From there, in a server side implementation, I can simply set up conditional rendering depending on whether the server stored session has an associated user id or not and then pull the user information from there and display it.
However, I can't think of a client-side rendered solution where the user can use the session id alone on the cookie that isn't easily spoofable. Some of the insecure implementations would include using browser storage (local/session). Thanks.
I think the major issue here is that you are mixing the two parts of a web page (at least according to what HTML set out achieve) and treating them both as sensitive information.
You have two major parts in a web page - the first being the display format and the second being the data. The presumption in client side rendering / single page applications is that the format itself is not sensitive, and only the data needs to be protected.
If that's the case you should treat your client-side redirect to login behavior as a quality of life feature. The data endpoints on your server would still be protected - meaning that in theory an unauthenticated user could muck about the static HTML he is being served and extract page layouts and templates - but those would be meaningless without the data to fill them - which is the protected part.
In practice - your end product would be a single page application that makes requests to various API endpoints to fetch data and fill in the requested page templates. You wouldn't even need to go as far as storing complex session states - a simple flag notifying the client if it is authenticated or not would suffice (that is beyond what you would normally use for server-side authentication such as cookies or tokens)
Now let's say I'm a malicious user who is up to no good - I could "spoof" - or really just open the browser dev tools and set the isAuthenticated flag to true letting me skip past the login screen - now what would I do? I could theoretically navigate to my-service/super-secret without being redirected locally back to the login page on the client side - and then as soon as the relevant page tries to load the data from the server with the nonexistent credentials it would fail - best case displaying an error message, worst case with some internal exception and a view showing a broken template.
So just to emphasize in short:
A. If what you want to protect is your TEMPLATE then there is no way to achieve this clientside.
B. If what you want to protect is your DATA then you should treat gating/preventing users from navigating to protected pages as a quality of life feature and not a security feature, since that will be implemented on the server when serving the data for that specific page.

How to secure server API in order to reject fake-client calls?

I'm developing both server and client side of a web application and it is almost finish. Now, it is time to secure it.
I read lots of articles and Q-A sites to understand the principles of the concept. But there are still question marks on my mind.
There is a similar question here:
How do I secure REST API calls?
They suggested to use token-based security system, which is very common and practical way. Also services like Firebase, Auth0 are providing this security system.
And this is about "how and where to store token": https://auth0.com/docs/security/store-tokens
If so, how can token protect server from fake-calls while we are storing it in the browsers local storage?
Explaining it with an example in order to be clear:
My client-side code has a form with options. One of the option can be selected via drop down option and there are only "1,2,3,4" in those options. So that, client can never send a form with "5" value to the server. But what if someone use a API tool (for example postman) to send a form with a value of 5? Attacker still can add a token to that request. First login to system as normal user. Than open the developer console of the browser, copy your token and paste to the header of your fake-request.
Not allowing the cross origin calls may solve the problem. But I am not sure if this means server and client should run on the same domain (or host)?
Bonus from stackoverflow: Stackoverflow's use of localstorage for Authorization seems unsafe. Is this correct else how do we strengthen it?
They are also discussing the similar question from another aspect. (Not for the server security but for the user's security.)
Not related but in case of need: front-end is developed with Angular 5, server is developed with Java and Spring Framework.

NodeJS/express - security for public API endpoint

I'm developing my web-site project based on NodeJs/Express, and for some UI parts I'm using Jquery ajax request to fetch secondary data.
How can we handle some basic control on our Rest API end-points that are used for ajax calls by the browser?
I was thinking about some kind of token authorization , but it can be also used by other clients (scripts etc.) once it has been intercepted , so how can we protect our server from unwanted requests? What other controls should be used in this cases (recognize too many request from same client, clients black list,etc)?
There are three main topics Authentication, Authorization, Security. I will give links and only shortly answers. Subject is enough big to write few books.
Authentication - who is the one who is making request. There are many 'strategies' to authentication user. Please check most pupular module for this : http://passportjs.org/docs.
Of course you can inplement one or more of this strategies alone.
For stateless authentication jwt tokens are very convenient. If you want to code it yourself (Passport has this strategy) check this link (one of many in web) https://scotch.io/tutorials/authenticate-a-node-js-api-with-json-web-tokens.
How to prevent from token interception? Use always https and set token expiration time short.
Where to store your token client side? for detail look at this https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/ In short don't store in web storage because of XSS attacks. Use cookies, when they are correctly configured they are safe (more in attached link), if not configured they are very exposed to threats.
Authorization : we know user, but he has access only to some resources. Please check https://github.com/OptimalBits/node_acl
There is gist with node_acl and passport : https://gist.github.com/danwit/e0a7c5ad57c9ce5659d2
In short passport authenticate user. We now who want what. We setup roles and resources and define roles and resources relation. Then we set for each user roles. Module will check for us user permission.
Security: please look for this subject in documentation of sails framework http://sailsjs.org/documentation/concepts/security they describes attacks and how framework prevent form them. I write about express:
DDOS: (part of your question "too many request from same client") "At the API layer, there isn't much that can be done in the way of prevention". This is subject most for servers admins. In short use load balancer. If it is one IP (not hundreds) then blacklist or deley response (for start look at this https://www.npmjs.com/package/delayed-request but I thing that solution must be more sophisticated).
CSRF: "type of attack which forces an end user to execute unwanted actions on a web application backend". Look at this module https://www.npmjs.com/package/csrf
XSS: "type of attack in which a malicious agent manages to inject client-side JavaScript into your website" don't trust any data from user. Always validate, filter, santize. Look at this https://www.npmjs.com/package/xss
In documentation of sails, there is more attack types but above are most popular.
Use express session + passport (http://passportjs.org/)
Basically you should have a login to the website and than only authenticated users can call the REST apis.
now... if you don't want a login, than you can't really protect the APIs as the website by design is open.
You didn't specify much info so it is hard to say more than that.
Also DoS attacks can't be protected by your code, and usually its not the responsibility of the app server (in your case node.js express) to provide such protection. If someone wants your website down by doing DoS attacks, than without other layers (see https://en.wikipedia.org/wiki/Denial-of-service_attack#Defense_techniques) which mostly mean it is up to a router/switch/so on... to implement.

SPA security using Backbone.js, Require.js and Laravel

I'm currently searching the best way for developing my next webapplication. I'm thinking about using Backbone.js and build a single page application. But I really can't imagine how to secure my app since nearly everything is done on client side. Of course I just could prevent the users from accessing my RESTful Api so they would not have access to my data. But all the view/model/collection/template js files are still accessible.
Or is there a known way to serve the js files with php (laravel), which would allow me to only serve the files I need for the respective user.
I just couldn't find a solution by searching the Web. But I just don't think that I am the lonely person who needs a clean and secure authentication method including different user rights.
Thank you in advance!
Your backend application will fetch data from a backend (= API), and probably send back some changes.
This code can't have "security holes / leaks" as long as your backend is secured.
If you are afraid of people stealing your code, you can always minify the JS (check grunt.js and almond.js for this)
To secure your backend you can make use of Laravel's auth class, and the auth filter as mentioned before.
Besides normal auth, you could implement roles, that you can assign to specific users, giving them more or less access to certain resources in your backend.
Here's the method I would try :
Separate the application in two parts.
One part - login via regular Laravel Auth on a separate page, and then when the user is logged in serve the single page app in a different view.
Wouldn't this work?
Web Services are no different than any other web application you build. At the end of the day you are exposing functionality to the client (which is also the attacker). It doesn't matter what the client is implemented in, if you expose dangerous functionality you will be hacked.
Have a session state, keep track of the user id and make sure that the user is only accessing resources they have been allowed to access.
I do not think that what JS/template files are exposed really matters. Essentially, you should only be allowing data interaction to authenticated users. Think of this as two separate applications.
The front-end application logs in, and a cookie is stored (or some other persistence is used).
The back-end application then uses the persistent authentication to validate every single user request for data, and every user action.
This way you don't have to worry about the security, the client can only fetch the data that the server allows it to, and, likewise, it can only interact with the data insofar as the server allows it. You shouldn't be relying on the client side for security anyway, even logged in, otherwise some malicious user could, conceivably, save all your frontend code and use it against you without authentication.

Resources