In node.js how would I follow the Principle of Least Privilege? - node.js

Imagine a web application that performs two main functions:
Serves data from a file that requires higher privileges to read from
Serves data from a file that requires lower privileges to read from
My Assumption: To allow both files to be read from, I would need to run node using an account that could read both files.
If node is running under an account that can access both files, then a user who should not be able to read any file that requires higher privileges could potentially read those files due to a security flaw in the web application's code. This would lead to disastrous consequences in my imaginary web application world.
Ideally the node process could run using a minimal set of rights and then temporarily escalate those rights before accessing a system resource.
Questions: Can node temporarily escalate privileges? Or is there a better way?
If not, I'm considering running two different servers (one with higher privileges and one with lower) and then putting them both behind a proxy server that authenticates/authorizes before forwarding the request.
Thanks.

This is a tricky case indeed. In the end file permissions are a sort of meta-data. Instead of directly accessing the files, my recommendation would be to have some layer between the files in the form of a database table, or anything that could map the type of user to the file, and stream the file to the user if it exists.
That would mean that the so called web application couldn't just circumvent the file system permissions as easy. You could even set it up so that said files did not have server readable permissions, and instead were only readable by the in between layer. All it could do is make a call, and see if the user with given permissions could access the files. This lets you also share between multiple web applications should you choose. Also because of the very specific nature of what the in between layer does, you can enforce a very restricted set of calls.
Now, if a lower privileged user somehow gains access to a higher privileged user's account, they'll be able to see the file, and there's no way to really get around that short of locking the user's account. However that's part of the development process.

No, I doubt node.js-out of the box-could guarantee least privilege.
It is conceivable that, should node.js be run as root, it could twiddle its operating system privileges via system calls to permit or limit access to certain resources, but then again running as root would defeat the original goal.
One possible solution might be running three instances of node, a proxy (with no special permissions) to direct calls to one or the other two servers run at different privilege levels. (Heh, as you already mention. I really need to read to the end of posts before leaping into the fray!)

Related

NodeJS accessing folders above

I have nodejs running on Centos 7. What bothers me is that any node apps could walk through whole server, changing any files and writing new one. How can I block node app from accessing folders above the level?
This is not specifically a node.js issue, but more a question about how to secure a server from any form of potentially misbehaving program. A massive subject about which whole books have been written.
But to answer your question: any software, including node.js programs, runs in the context of a process that has a user (uid) and group (gid), and standard operating system facilities: file permissions, Access Control Lists (ACLs), etc., determine what a process with a specific uid and gid can access.
If you believe that the node.js program can access the whole server’s file system that suggests that the process is running as the root user, or at least has superuser (su) privileges; which would be considered bad security practice in almost all circumstances.
So run the node.js program as a user with no access outside of an area of the file system to which it has been explicitly granted the minimal possible access.
This CentOS documenation (https://www.centos.org/docs/5/html/5.1/Deployment_Guide/sec-sel-context-checking-processanduser.html) might help a little if you are new to the subject.

Is it (in)secure to give the ApplicationPoolIdentity write access to a folder inside your web application folder?

Recently we implemented a feature which dynamically generates a LESS file in our App_Themes folder. This is done on application start.
This requires us to give the #ApplicationPoolIdentity# write access to the App_Themes folder.
Our system administrator, however, does not want us to give the #ApplicationPoolIdentity# that write access. For security reasons.
Is it insecure to do that? What are the security risks?
If there were any remote code execution vulnerabilities in your application, or within ASP.NET or IIS itself, anyone compromising your system through your application or web server will likely get a command shell, and be logged in as e.g. DefaultAppPool on your server.
If there is write access to a folder, then the attacker could write to this folder themselves.
For example, they could host their own content on your site at example.com/App_Themes/index.html, or they could upload an exploit that allowed priveledge escalation to that of administrator. In the latter case they would probably need executable permissions too, unless they could in someway make the webserver execute it, for example by requesting the URL of the dropped exploit.
Of course, the vulnerability has to be there in the first place for this to happen. Preventing write access too can be viewed as "defence in depth", however if this is needed by your application then it may be an acceptable risk. An alternative is to find another way to implement your desired functionality.

How can I access files of different users and retain permission restrictions in Linux using Node.JS?

I'm trying to reimplement an existing server service in Node.JS. That service can be compared to a classic FTP server: authenticated users can read/create/modify files, but restricted to the permissions given to the matching system user name.
I'm pretty sure I can't have Node.JS run as root and switch users using seteuid() or alike since that would break concurrency.
Instead, can I let my Node.JS process run as ROOT and manually check permissions when accessing files? I'm thinking about some system call like "could user X create a file in directory Y?"
Otherwise, could I solve this by using user groups? Note that the service must be able to delete/modify a file created by the real system user, which may not set a special group just so that the service can access the file.
Running node as root sounds dangerous, but I assume there aren't many options left for you. Most FTP servers run as root too, for the same reason. Though, it means you need to pay a severe attention to the security of the code you are going to run.
Now to the question:
You are asking whether you can reimplement the UNIX permissions control in node.js. Yes you can, but Should Not! It is almost 100% chance you will leave holes or miss edge cases Unix core has already taken care of.
Instead use the process.setuid(id) as you mentioned. It will not defeat concurrency, but you need to think of parallel concurrency rather than async now. That is an extra work, but will release you of an headache of reinventing the Unix security.
Alternatively, if all of the operations you want to carry on filesystem involve shell commands, then you can simply modify them to the following pattern:
runuser -l userNameHere -c 'command'

Why web sites run under less privileged user account (IUSR_ComputerName)?

Usually we define iis web sites which allow anonymous authentication to run under the IUSR_ComputerName account which has very limited privileges. For example we may decide it cannot access the file system. How does that make our web site any more secured? The user cannot run code on it anyway - only our website code runs and we make sure it does not cause any harm.
Edit: I understand why it is good to be on the safe side (e.g. iis exploit). My question is if there is any direct reason. For example, if I would never give a guest account full privileges on a sql server as it would immediately allow him full control over my server. This does not seem to be the case with iis.
we make sure it does not cause any
harm
You can be never sure about it doesn't cause any harm. One day, it might be exploited, and probably the less privileged user would save your data. No offense, but no one writes perfect code, therefore no code is vulnerability free.
If you have any network service you should assume that some random person on the internet has a command prompt on your machine running as that services's owner.
Now ask what damage that user good do?
Typically, you may need to run your web site in a way that is a little less hardened from a security standpoint than, say, a domain server or exchange. For example, you may need to permit FTP access. Obviously, Internet web sites need to be accessed from the Internet so you cannot simply block all access with your firewall.
Because of the higher vulnerability, it is prudent to run your service with an account that has limited permissions. In the case where a malicious user does succeed in copying their own programs to be run on your server, those programs will have severe limitations as to what they can do.
You can run code on the server, for example you can delete files in a directory if the permissions are not set.

initiating a program that has more user privilages in restricted user

I have users with limited access granted to one of my hard drives. Those users are not given the permittion to delete the files in that drive. but I have a application that should allow those users to delete files in the above mentioned drive.
1) How can I do this?
2) When a low priviliaged user loged to my application, can I write a hidden thread/ program that that gives high privileged user authority (only for this application), as in impersonating another user, so that he will be abel to delete files via this appliction in the restricted hard disk?
Thanks
Depending on your OS you can do various things.
In a UNIX like environment you can write a program and use setuid or setguid so that it runs with priviledges of another (more priviledged) user.
Alternatively in Windows or UNIX you can run a service as the more priviledged user and let it take requests from other users/processes to carry out the operation on their behalf. You'd have to look into ways to communicate with the service.
Hope that helps.
Probably the easiest way is to write a service which exposes a named pipe, and create a client application which talks to the pipe and issues instructions to your service. The service runs under LocalSystem or a nominated higher-privilege account, and carries out instructions from the app running under a user account with lower privilege. You'd need some sort of handshake to establish bona-fides when you connect to the pipe, but it's not hard to do. You could use WCF instead of pipes, but I don't think you get much advantage from that in this scenario.

Resources