NodeJS accessing folders above - node.js

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.

Related

How to give root access to linux application

I am making a Linux application using Python3 and Qt5. When user will install this application, It will create some files in /usr/share folder. To create the files the application needs to have root access.
I plan on having the application show a prompt box to user and user will enter the root password to give root access to the application. But I don't know that how can I give root access to the application by using that password?
This is a world of pain. It's certainly possible to have an application that runs as a normal user carry out certain actions as a privileged user, but I always feel that the need to do this suggests that installation and maintenance hasn't been thought through properly.
To elevate privileges, and assuming the "sudo" isn't appropriate (it probably won't be in this case), you will either need to use an operating system tool that does the job (prompting for credentials and then running something), or implement a helper for your program that has suid attributes on its executable.
I expect all Linux systems have access to "su", but the standard su doesn't have a graphical interface, which is a drag for GUI programs. You can collect the user credentials in your application, and then pass them to su (which is fiddly), or you can use one of the various graphical su-type utilities such as gksu. Of course, that only works if those utilities are available on your platform.
If you go the route of providing your program with a suid part that handles the work that needs elevated privileges, you need to be inordinately careful about security -- how you collect the credentials, how you verify that intruders can't do things they shouldn't, etc.
Frankly, it's a can of worms. I would think that it's nearly always better to provide your application with an installation or maintenance module that has to be run as root. That way all the hard work gets done by the platform.

How to let users run arbitrary source code on my server

I want to automate testing of my users' source code files by letting them upload c++,python, lisp, scala, etc. files to my linux machine where a service will find them in a folder and then compile/run them to verify that they are correct. This server contains no important information about any of my users, so there's no database or anything for someone to hack. But I'm no security expert so I'm still worried about a user somehow finding a way to run arbitrary commands with root privileges (basically I don't have any idea what sorts of things can go wrong). Is there a safe way to do this?
They will. If you give someone the power to compile, it is very hard not to escalate to root. You say that server is not important to you, but what if someone sends you an email from that server, or alters some script, to obtain some info on your home machine or another server you use?
At least you need to strongly separate you from them. I would suggest linux containers, https://linuxcontainers.org/ they are trendy these days. But be careful, this is the kind of service that is always dangerous, no matter how much you protect yourself.
Read more about chroot command in Linux.
This way you can provide every running user program with separate isolated container.
You should under no circumstances allow a user to run code on your server with root privileges. A user could then just run rm –rf / and it would delete everything on your server.
I suggest you make a new local user / group that has very limited permissions, e.g. can only access one folder. So when you run the code on your server, you run it in that folder, and the user can not access anything else. After the code has finished you delete the content of the folder. You should also test this vigorously to check that they really cant destroy / manipulate anything.
If you're running on FreeBSD you could also look at Jails, which is sort-of a way of virtualization and limiting a user / program to that sandbox.

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'

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

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!)

best approah (security) to do some admin work through web page in Linux?

I want to build a web based admin tools that allow the system admin to run pre-configured commands and scripts through a web page (simple and limited webmin), what is the best approach?
I already started with Ubuntu installing LAMP and give the user www-data root's privileges !!!
as I learned (please check the link) this is a really bad move !!!, so how to build such web-based system without the security risk?
cheers
I did something like this a couple of years ago. It was (I like think) fairly secure and only accessible to a limited number of pre-vetted, authenticated users, but it still left me with an uneasy feeling! If you can avoid doing it, I'd recommend you do :)
I had a database sitting between the frontend web-tier and the script which was actually executing actions. The relevant table contained a symbolic command name and an optional numeric argument, which was sufficient for my needs. This allows you to audit what's been executed, provides a quick and dirty way to have a non-www user do things, and means if the website is compromised they're constrained by the DB structure (somewhat) and the script which pulls data from it.
The data from the DB can be read by a daemon running in a separate, unprivileged account. The daemon pulls and sanitises data from the DB and maps the 'command' to an actual executable (with a hard-coded map, so commandA executes A, commandB executes foo, and anything else would get flagged as an error). The account can be locked down using AppArmor (or SELinux, I imagine) to prevent it from executing, reading or writing anything you don't expect it to. Have a system in place to alert you of any errors from either the daemon or AppArmor/SELinux.
The executables which the daemon runs can be setuid'd if appropriate, or you can use the sudoers mechanism to allow the unprivileged account to execute them without a password.
I already started with Ubuntu installing LAMP and give the user www-data root's privileges
Don't do this.
If you really want to execute some very specific scripts under root privileged. Create such predefined very limited scripts, allow their password-less execution with sudo for specific user and then run them via script and don't forget authentication.
Generally this is bad idea.
SSH is your best friend.

Resources