Handling permission in redux - node.js

Using a node-redux stack. We have action creators on the client side and reducers + redux state on the back end.
I have the following proposal to implement permissions:
Actions are created client side, these may be malicious, even from authenticated users.
Actions are sent to the server.
The request is authenticated server-side and the users permissions ascertained.
The actions pass through the redux middleware which lives inside the node server.
Middleware checks the users permissions against permission specified for the action type.
If the user has the correct permissions for the action then the reducers create a new redux state (which also lives on the server).
Problem:
Each action type is coupled to a set of permissions, this means that we need to take great care creating our reducers so that we never allow an action to do more than it should. With multiple devs on the team and a large application I am not convinced this is sufficient.
Questions:
Is there a good resource/link with a good discussion on handling permissions with redux.
Is redux sufficient for handling complex permissions?
If we check permissions as outlined above are there any problems that I have not mentioned and is there a better way of approaching this while still using redux?

Redux is "permission agnostic". Redux is just a framework for coordinating actions that update the application state; it contains no opinions or recommendations on how to approach permitting those actions.
Answers
Is there a good resource/link with a good discussion on handling permissions with
redux.
Here is one.
Authorization is a very difficult thing to make general proclamations about, since it very much depends on the business needs. Are you using roles? Are you just requiring authentication? Can users have multiple roles, or just one? How do multiple roles interact? These are not questions with one answer.
Is redux sufficient for handling complex permissions?
This is like asking if JavaScript is sufficient for handling complex permissions. It doesn't really make sense.
From one perspective, is it "possible" to handle complex permissions: yes. Redux will not restrict any permissions scheme you wish to implement at the action level, since actions are just functions that call dispatch (another function). You can use actions to stop the dispatch call for any reason.
From another perspetive, does redux provide an out-of-the-box mechanism that can handle complex permissions without any additional patterns or tools: no. Redux does not even attempt to address this concern, it is entirely up to you.
If we check permissions as outlined above are there any problems that I have not mentioned and is there a better way of approaching this while still using redux?
There are most certainly problems you have not mentioned, since you have not completely outlined your implementation. As they say, the devil is in the details. How you accomplish what you have described will determine what other problems you encounter.
Is there a better way? "Better" is about as vague as you can get. What are your parameters for "better"? In a trade-off between development speed and run-time performance, which would you prefer? In a trade-off between number of server calls and permission granularity, which would you prefer?
All you have said is that you are checking actions on the server. Without knowing what your authorization model is, its impossible to say if a better way exists, even when you precisely define "better", because we don't know what you are doing.
However, given the information you have, and assuming that doing the check server side is both necessary and time-saving (another big assumption), I would say (as weakly as I possible can) yes, there will be additional problems. To name a few:
Latency. Redux expects the entire app state, including the value of input fields. Your model checks the server on each action, so developing in a stricly redux manner every keystroke will go to the server to ensure that it is allowed to update the input. This will make user interaction very slow, and very frustrating.
Bandwidth. This is going to consume a lot of bandwidth, for the reason as above.
CPU. This is going to be very server CPU intensive, for the reason above.
A big win in client-side applications is that the server only does the work it absolutely has to: serving data (in a minimal format like json), and verifying requests to update data. You are going to be taking on the additional work of running all of your clients. This is a questionable tradeoff to reducing the boiler-plate of writing a REST api.
This will also lock you into your action api, and redux. A REST api has the advantage of being client-agnostic. If you change from redux, or just reorganize your actions, the REST api on the server wont need to change (or at least, wont need to change as much). This is going to make refactoring, even if you stick with redux, painful. Whether or not this overcomes the pain of writing a REST api is impossible to say, but its something to consider.

Related

Does Microsoft have a recommended way to handle secrets in headers in HttpClient?

Very closely related: How to protect strings without SecureString?
Also closely related: When would I need a SecureString in .NET?
Extremely closely related (OP there is trying to achieve something very similar): C# & WPF - Using SecureString for a client-side HTTP API password
The .NET Framework has class called SecureString. However, even Microsoft no longer recommends its use for new development. According to the first linked Q&A, at least one reason for that is that the string will be in memory in plaintext anyway for at least some amount of time (even if it's a very short amount of time). At least one answer also extended the argument that, if they have access to the server's memory anyway, in practice security's probably shot anyway, so it won't help you. (The second linked Q&A implies that there was even discussion of dropping this from .NET Core entirely).
That being said, Microsoft's documentation on SecureString does not recommend a replacement, and the consensus on the linked Q&A seems to be that that kind of a measure wouldn't be all that useful anyway.
My application, which is an ASP.NET Core application, makes extensive use of API Calls to an external vendor using the HttpClient class. The generally-recommended best practice for HttpClient is to use a single instance rather than creating a new instance for each call.
However, our vendor requires that all API Calls include our API Key as a header with a specific name. I currently store the key securely, retrieve it in Startup.cs, and add it to our HttpClient instance's headers.
Unfortunately, this means that my API Key will be kept in plaintext in memory for the entire lifecycle of the application. I find this especially troubling for a web application on a server; even though the server is maintained by corporate IT, I've always been taught to treat even corporate networks as semi-hostile environments and not to rely purely on corporate firewalls for application security in such cases.
Does Microsoft have a recommended best practice for cases like this? Is this a potential exception to their recommendation against using SecureString? (Exactly how that would work is a separate question). Or is the answer on the other Q&A really correct in saying that I shouldn't be worried about plaintext strings living in memory like this?
Note: Depending on responses to this question, I may post a follow-up question about whether it's even possible to use something like SecureString as part of HttpClient headers. Or would I have to do something tricky like populate the header right before using it and then remove it from memory right afterwards? (That would create an absolute nightmare for concurrent calls though). If people think that I should do something like this, I would be glad to create a new question for that.
You are being WAY too paranoid.
Firstly, if a hacker gets root access to your web server, you have WAY bigger problems than your super-secret web app credentials being stolen. Way, way, way bigger problems. Once the hackers are on your side of the airtight hatchway, it is game over.
Secondly, once your infosec team detects the intrusion (if they don't, again, you've got WAY bigger problems) they're going to tell you and the first thing you're going to do is change every key and password you know of.
Thirdly, if a hacker does get root access to your webserver, their first thought isn't going to be "let's take a memory dump for later analysis". A dumpfile is rather large (will take time to transfer over the wire, and the network traffic might well be noticed) and (at least on Windows) hangs the process until it's complete (so you'd notice your web app was unresponsive) - both of which are likely to raise some red flags.
No, hackers are there to grab as much valuable information in the least amount of time, because they know their access could be discovered at any second. So they're going to go for the low-hanging fruit first - usernames and passwords. Then they'll move on to trying to find out what's connected to that server, and since your DB credentials are likely in a config file on that server, they will almost certainly switch their attentions to that far more interesting target.
So all things considered, your API key is pretty darn unlikely to be compromised - and even if it is, it won't be because of something you did or didn't do. There are far more productive ways of focusing your time than trying to secure something that already is (or should be) incredibly secure. And, at the end of the day, no matter how many layers of security you put in place... that API or SSL key is going to be raw, in memory, at some stage.

node.js api gateway implementation and passport authentication

I am working on implementing a microservices-based application using node.js. While searching for examples on how to implement the api gateway, I came across the following article that seems to provide an example on implementing the api gateway: https://memz.co/api-gateway-microservices-docker-node-js/. Though, finding example for implementing the api gateway pattern in node.js seems to be a little hard to come by so far, this article seemed to be a really good example.
There are a few items that are still unclear and I am still have issues finding doc. on.
1) Security is a major item for the app. I am developing, I am having trouble seeing where the authentication should take place (i.e. using passport, should I add the authentication items in the api gateway and pass the jwt token along with the request to the corresponding microservice as the user's logged in information is needed for certain activities? The only issue here seems to be that all of the microservices would need passport in order to decrypt the jwt token to get the user's profile information. Would the microservice be technically, inaccessible to the outside world except through the api gateway as this seems to be the aim?
2) How does this scenario change if I need to scale to multiple servers with docker images on each one? How would this affect load balancing, as it seems like something would have to sit at a higher level to deal with load balancing?
I can tell that much depends on your application requirements. Really.
I'm now past the 5 years of experience in production microservices using several languages going from medium to very large scale system.
None of them shared the same requirements, and without having a deep understanding of what you need and what are your business (product) requirements it would be hard to know what's the right answer, by the way I'll try to share some experience to help you get it right.
Ideally you want the security to be encapsulated in an external service, so that you can update and apply new policies faster. Also you'll be able to deprecate all existing tokens should you find a breach in your system or if someone in your team inadvertedly pushes some secret key (or cert) to an external service.
You could handle authentication on each single service or using an edge newtwork tool (such as the API Gateway). Becareful choosing how to handle it because each one has it's own privileges:
Choosing the API Gateway your services will remain lighter and do not need to know anything about the authentication steps, but surely at some point you'll need to know who the authenticated user is and you need some plain reference to it (a JSON record, a link or ID to a "user profile" service). How you do it it's up to your requirements and we can even go deeper talking about different pros and cons about each possible choice applicable for your case.
Choosing to handle it at the service level requires you (and your teams) to understand better about the security process taking place (you can hide it with a good library) and you'll need to give them support from your security team (it's may also be yourself btw you know the more service implementing security, the more things you'll have to think about to avoid adding unnecessary features). The big problem here is that you'll often end up stopping your tasks to think about what would help you out on this particular service and you'll be tempted to extend your authentication service (and God, unless you really know what you're doing, don't add a single call not needed for authentication purposes).
One thing is easy to be determined: you surely need to think about tokens (jwt, jwe or, again, whatever your requirements impose).
JWT has good benefits, but data is exposed to spoofing, so never put in there sensitive data or things you wouldn't publicly share about your user (e.g. an ID is probably fine, while security questions or resolution to 2FA would not). JWE is an encrypted form of the spec. A common token (with no meaning) would require a backend to get the data, but it works much like cookie-sessions and data is not leaving your servers.
You need to define yourself the boundaries of your services and do yourself a favor: make each service boundaries clean, defined and standard.
Try to define common policies and standardize interactions, I know it may be easier to add a queue here, a REST endpoint there, a RPC there, but you'll soon end up with a bunch of IPC you will not be able to handle anymore and it will soon catch your attention.
Also if your business solution is pretty heavy to do I don't think it's a good idea to do yourself the API Gateway, Security and so on. I'd go with open source, community supported (or even company-backed if you have some budget) and production-tested solutions.
By definition microservice architectures are very dynamic, you'll fight to keep it immutable between each deployment version, but unless you're a big firm you cannot effort keeping live thousands of servers. This means you'll discover bugs that only presents under certain circumstances you cannot spot in other environments (it happens often to not be able to reproduce them).
By choosing to develop the whole stack yourself you agree with having to deal with maintenance and bug-discovery in your whole stack. So when you try to load a page that has 25 services interacting you know it may be failing because of a bug in: your API Gateway, your Security implementation, your token parser, your user account service, your business service A to N, your database service (if any), your database load balance (if any), your database instance.
I know it's tempting to do everything, but try to keep it flat and do what you need to do. By following this path you'll think about your product, which I think is what's the most important think to do now.
To complete my answer, about the scaling issues:
it doesn't matter. Whatever choice you pick it will scale seamlessly:
API Gateway should be able to work on a pool of backends (so from that server you should be able to redirect to N backend machines you can put live when you need to, you can even have some API to support automatic registration of new instances, or even simples put the IP of an Elastic Load Balancer or HAproxy or equivalents, and as you add backends to them it will just work -you have moved the multiple IPs issue from the API Gateway to one layer down).
If you handle authentication at services level (and you have an API Gateway) see #1
If you handle authentication at services level (without an API Gateway) then you need to look at some other level in your stack: load balancing (layer 3 or layer 7), or the DNS level, you can use several features of DNS to put different IPs to answer from, using even advanced features like Anycast if you need latency distribution.
I know this answer introduced a lot of other questions, but I really tried to answer your question. The fact is that you need to understand and evaluate a lot of things when planning a microservice architecture and I'd not write a SLOC without a very-written-plan printed on every wall of my office.
You'll often need to go mental focus and exit from a single service to review the global vision and check everything is going fine.
I don't want to scare you, I'm rather trying to make you think to succeed.
I just want you to make sure you correctly evaluated all of the possibilities before to decide to do everything from scratch.
P.S. Should you choose to act using an API gateway be sure to limit services to only accept requests through it. On the same machine just start listening on localhost, on multiple machines you'll need some advanced networking rule depending on your operating system.
Good Luck!

How safe is cross domain access?

I am working on a personal project and I have being considering the security of sensitive data. I want to use API for accessing the Backend and I want to keep the Backend in a different server from the one the user will logon to. This then require a cross domain accessing of data.
Considering that a lot of accessing and transaction will be done, I have the following questions to help guide me in the right path by those who have tried and tested cross domain access. I don't want to assume and implement and run into troubles and redesign when I have launched the service thereby losing sleep. I know there is no right way to do many things in programming but there are so many wrong ways.
How safe is it in handling sensitive data (even with https).
Does it have issues handling a lot of users transactions.
Does it have any downside I not mentioned.
These questions are asked because some post I have read this evening discouraged the use of cross-domain access while some encouraged it. I decided to hear from professionals who have actually used it in a bigger scale.
I am actually building a Mobile App, using Laravel as the backend.
Thanks..
How safe is it in handling sensitive data (even with https).
SSL is generally considered safe (it's used everywhere and is considered the standard). However, it's not any less safe by hitting a different server. The data still has to traverse the pipes and reach its destination which has the same risks regardless of the server.
Does it have issues handling a lot of users transactions.
I don't see why it would. A server is a server. Ultimately, your server's ability to handle volume transactions is going to be based on its power, the efficiency of your code, and your application's ability to scale.
Does it have any downside I not mentioned.
Authentication is the only thing that comes to mind. I'm confused by your question as to how they would log into one but access data from another. It seems that would all just be one application. If you want to revise your question, I'll update my answer.

How do BAAS solutions both allow custom code and keep things secure?

Baas, backend-as-a-service, solutions like Parse.com and StackMob allow application developers to add and use custom code to run server-side business logic. I'm interested in learning how you could add functions to the app server without disruptions to other applications and keep malicious code from accessing the system or data they shouldn't.
I've searched for any posts or disclosures of how Parse or StackMob might have built up their architectures and have come up empty.
Take a look at how Kii Cloud provides custom server side code that you can add to the backend. It basically runs in a sandbox with some access to the server side API (but it's well defined, the user can only access what they are intended to access). An there are also resource limitations such as time constraints (a piece of server code can take do processing forever).
This is not exactly the internals of Kii but I think server side code in most MBaaS providers reflects on what's the correct way to add server side logic on a running system without disrupting the system.
Please head to community.kii.com if you want to discuss internals with the engineers (we're happy to chat with you).

Should my service layer work for any user, or restrict itself to the currently authenticated user?

This is a fundamental design question about the service layer in my application, which forms the core application functionality. Pretty much every remote call reaches a service sooner or later.
Now I am wondering if
every service method should have a User argument, for which the operation should be performed
or if the service should always query the security implementation, which User is currently logged in, and operate on that user
This is basically a flexibility vs security decision, I guess.. What would you do?
There is also a DoS aspect to consider.
One approach is to offer (depending on your context) a publicly available instance / entry point to the services, on a well throttled set-up; and a less restricted instance to an internal trusted environment.
In a similar vein, if you identify where traffic originates you can (or should) be able to provide better QoS to trusted parties.
So, I would possibly keep the core system (the services you write) fairly open / flexible, and handle some of the security related stuff elsewhere (probably in the underlying platform).
Just because you write one set of services doesn't mean you can only expose those in one place and all at the same time (to the same clients).
I think you should decide which methods will need a user argument and which will need a logged in user. You'll get the following method types as a result for this:
1.) Type1: Method is best to have a User argument.
2.) Type2: Method is best to not have a User argument.
3.) Type3: A combination of 1.) and 2.)
The solution of 1.) and 2.) is simple, because they are trivial cases.
The solution of 3.) is to overload the method to have a version of 1.) type and another version of 2.) type.
I try to look at security as an aspect. User argument is required for things other than authentication as well. But, I think control should reach the service layer's more important methods only if the user has been authenticated by some other filter. You can't have every method in the service layer querying the security module before proceeding.

Resources