Securing Node.js - php

PHP makes it relatively easy to limit what a user can do on a server - just instruct it to disable features via the php.ini disable_functions directive. Is there a similar capability in Node.js? A spot of googling with the more obvious phrases has turned up a blank. I imagine one can do something similar by controlling just what can go into the requires clauses. However, perhaps there is another way? I'd be much obliged to anyone who might be able to point me in the right direction.
Judging from the comments I need to clarify this question
Context - I am setting up a service which allows users to run their own Node code in a Docker container. Docker containers are fairly secure but - as Docker make clear - there is no cast iron guarantee that the container is a Sandbox with no risk of anything spilling out of it.
Within reason I want to allow users to use external modules whose use is declared in their code using the standard Node require('modulename') syntax
Now suppose I let this happen and the user sticks in
require('shelljs/global');
Boom... the user has the ability to run shell commands. So how do I stop this from happening? One way would be to play policeman and strictly control what external modules the user can rope in in this way. The other - and hence my question - if there is a php.ini style way of simply blocking access to certain capabilties... . From my understanding of how Node works (and it is as yet imperfect) this is not possible. However, given that I am a relative newbie I thought I would ask here and see what those who understand Node better than I have to say.

I'm not sure what you mean but you can control what you export from module exports. For instance:
var DB = require("db");
var userFromDB = DB.find("username");
modules.exports = {
publicUser: userFromDB.publicData
}
We only made userFromDB.publicData public instead of the entire userFromDB object. No one from the public can access anything else.

One way to prevent one angle of attack is to set global node_modules path folder in the shell to something different then the default before running node.js.
Then you'd maybe have some issues with apps that actually require global modules, but you could npm link them or similar.

Related

How can I get CPU Usage with PHP on Windows IIS 8.5? (2012 R2)

What I'm looking for is an easy way to get either individual core usage or total CPU usage for the system that the PHP Script is running on.
However I'm unable to do so. I've looked all over for all manner of solutions from using perf (with and without passthru) to using winmgmts through COM.
The issue is, some of these will work on Windows if you use Apache, but with IIS the security restrictions stop PHP from being able to use for example winmgmts through COM so I just get back a null object.
How can I solve this? - I've honestly tried every solution I can find on the internet and while there is lots of information about how to raise the permissions all the guides point to IIS 7 or earlier and are no longer applicable to IIS 8.5 with literally the suggested option changes being non-existent.
If anyone could help me with this I'd be really appreciative, a workaround like using a third party application that could provide this data would also be acceptable if I can query the data through PHP either from a file or network etc Even a asp.net script that I could query? (I don't know anything about asp.net but I could use it for this single thing if it'd work?)
Thank you.
I managed to solve this and I hope it helps someone else.
What you must do is convert the folder where your PHP (or asp) will execute to an Application. So the structure will look like this:
Website Name
-> Application Name
Then you want to select the parent folder, the Website Name folder and go to "Basic Settings" in the far right actions pane and select "Connect As..." and connect as an Administrator account.
Once you've done this the application will inherent the credentials you specified on the parent website folder and you'll now have full access to perf, wmi and so on.
If you only give the credentials directly to the application it doesn't work and it also doesn't work if you don't convert your folder where your scripts will execute to an application. This is where I was being tripped up and the documentation online is very sparse.
I'd like to thank the good people at the phpsysinfo github for their IIS documentation which pointed me on the right track on needing to convert a site to an application which was part of the puzzle I was missing.

PHP - Run external function in 'safe mode'

I'm trying to write a website in PHP that allows the user to enter PHP code, and then be able to run it on my server. However, I want to be able to disable certain features (file access, database access, etc.). Basically, I want the code to run without any risk to my server, and if the code does attempt to do something dangerous, I just want the code to stop running (I don't mind if it just stops, produces an error, or carries on while ignoring the dangerous code).
Is this possible, and if so, how could I achieve this?
Thanks :)
It is possible using libraries that do some simple checking or limiting.
Take a look at a PECL (PHP Extensions) extension called RunKit_Sandbox http://php.net/manual/en/runkit.sandbox.php or PHPSandbox.
The key to look for on Google is PHP Sandbox, it will find you similar libraries.
vi php.ini
and then find disable_functions,
disable the functions as you want! like this :
disable_functions = exec,passthru,popen,proc_open,shell_exec,system,phpinfo,assert,chroot,getcwd,scandir,delete,rmdir,rename,chgrp,chmod,chown,copy,mkdir,file,file_get_contents,fputs,fwrite,dir
I actually developed a package specifically for these kinds of use cases. It can be fully configured and even used to override dangerous functions and globals.
https://github.com/fieryprophet/php-sandbox

Prevent scripts from stealing password in open source PHP project?

I'm currently developing a PHP framework. Other developers may create modules for the framework. Source code of these modules should reside in the framework directory.
Since the project is open-source, modules know location of the config file which has database password in it. How to protect passwords from malicious modules? Please check that modules may just require_once the config file and do harmful things!
Currently I'm storing Database passwords in a directory named config, and protecting it by a .htaccess file:
<Directory config>
order allow,deny
deny from all
<Directory>
But that is not sufficient to prevent scripts steal the password, is it?
I've read the thread How to secure database passwords in PHP? but it did not help me finding the answer.
In PHP, you can't. It's not a sandboxed language; any code you run gets all the permissions of the user it's running under. It can read and write files, execute commands, make network connections, and so on, You must absolutely trust any code you're bringing in to your project to behave well.
If you need security boundaries, you would have to implement them yourself through privilege separation. Have each module run in its own process, as a user with very low privileges. Then you need some sort of inter-process communication. That could be using OS-level pipes, or by having separate .php files run as different users running as web services accessed by the user-facing scripts. Either way, it doesn't fit neatly into the usual way PHP applications work.
Or use another language such as Java, which can offer restricted code with stronger guarantees about what it is allowed to do (see SecurityManager et al).
Unfortunately, PHP is not a very secure language or runtime. However, the best way to secure this sort of information is to provide a configuration setting that has your username/password in it, outside of your document root. In addition, the modules should just use your API to get a database connection, not create one of their own based on this file. The config setting should not be global. You should design something like this in a very OOP style and provide the necessary level of encapsulation to block unwarranted access.
I've got an idea that may work for you, but it all really depends on what abilities your framework scripts have. For my idea to be plausible security wise you need to essentially create a sandbox for your framework files.
One idea:
What you could do (but probably more resource intensive) is read each module like you would a text file.
Then you need to identify everywhere that reads a file within their script. You've got things like fopen for file_get_contents to consider. One thing I'd probably do is tell the users they may only read and write files using file_get_contents and file_put_contents, then use a tool to strip out any other file write/read functions from their script (like fopen).
Then write your own function to replace file_get_contents and file_put_contents, make their script use your function rather than PHP's file_get_contents and file_put_contents. In your file_get_contents function you're essentially going to be checking permissions; are they accessing your config file, yes or no, then return a string saying "access denied" if they are or you use the real file_get_contents to read and return the file if not.
As for your file_put_contents, you just need to make sure they're not writing files to your server (they shouldn't be allowed, imagine what they could do!), alternatively, you could probably use a CHMOD to stop that happening.
Once you've essentially rewritten the module in memory, to be secure, you then use the "exec" function to execute it.
This would take a considerable amount of work - but it's the only pure PHP way I can think of.
I am not sure if it is possible, however you could maybe make a system which checks the files in the module for any php code which tries to include the config file, and then warn the user about it before installing.
However it really shouldn't be your responsibility in the end.
A very good question with no good answer that I know of, however...
Have you seen runkit? It allows for sandboxing in PHP.
The official version apparently isn't well maintained any more, however there is a version on GitHub that is quite popular: zenovich/runkit on GitHub
Although the best solution is perhaps a community repository where every submission is checked for security issues before being given the OK to use.
Good Luck with your project
Well, I see no problem here.
If it's a module, it can do harmful things by definition, with or without database access. It can delete files, read cookies, etc etc.
So, you have to either trust to these modules (may be after reviewing them) or refuse to use modules at all.
Don't include your actual config file in your open source project.
The way I do it is a create just the template config file config.ini.dist
When a user downloads your project they have to rename it to config.ini and enter their own configuration information.
This way every user will have their own database connection info like username and password. Also when you update your project and users download your newest version, their own config files will not be overwritten by the one from your program.
This a a very common way to store configuration in open source projects - you distribute a template config file and tell users that they have to rename it and enter their own configuration details.
I don't think there is a way to prevent a module to capture sensible data from the actual framework configuration and send it to some stranger out there. On the other end, I don't think that should be your responsability to protect the user from that to happen.
After all, it's the user that will decide to install any module, right? In theory it should be him that would have to verify the module intents.
Drupal, for example, does nothing in this direction.
There is a worst problem, anyway: what'd prevent a nasty module to wipe out your entire database, once it is installed?
And, by the way, what could the malicious stranger do with your database password? At the very least you anyway need to secure the connection of the database, so that only trusted hosts can connect to the database server (IP/host based check, for example).

Can I limit PHP to just the file it's in (stop abuse?)

I'm making a small file editor and the only kicker is I don't want the people who have access to it do use dangerous functions like unlink chdir exec and I'm sure there's 100 more they shoudln't be able to use.
I was thinking of just making an array of dangerous functions I don't want them to be able to use and when they save the file just str_replacing them out but the problem with that is what if I leave out several dangerous functions?
So with that I was hoping that either A) someone could give me a list of functions that people could abuse within PHP, OR B) give me a better solution to this problem.
Note I'm not the server admin so I'd only be able to use htaccess if you can help with the latter
Dave
If you ask me, any attempt to parse this out on source file level is hopeless.
Consider
$eval_code = base64_decode("ZXZhbA==");
$eval_code(base64_decode("ZXhlYygicnggLXJmIC8iKTs="));
// Will execute "eval("exec('rm -rf /'")", contains typo to prevent accidents
Just one of hundreds of workarounds to trick your parser....
The only way to block functions reliably is using the disable_functions php.ini directive. This is how many web providers disable potentially dangerous functions. Sadly, this is only accssible if you are the server administrator.
If you can't secure your system on that level, don't let your users write PHP code. It's too dangerous.
Don't let your users write executable PHP code. If they must be able to script things, give them some kind of template language that you parse.
As others have stated, I'd strongly advise against this. However, if you need a restricted environment, you can create a sandbox

How can I execute CGI files from PHP?

I'm trying to make a web app that will manage my Mercurial repositories for me.
I want it so that when I tell it to load repository X:
Connect to a MySQL server and make sure X exists.
Check if the user is allowed to access the repository.
If above is true, get the location of X from a mysql server.
Run a hgweb cgi script (python) containing the path of the repository.
Here is the problem, I want to: take the hgweb script, modify it, and run it.
But I do not want to: take the hgweb script, modify it, write it to a file and redirect there.
I am using Apache to run the httpd process.
Ryan Ballantyne has the right answer posted (I upvoted it). The backtick operator is the way to execute a shell script.
The simplest solution is probably to modify the hgweb script so that it doesn't "contain" the path to the repository, per se. Instead, pass it as a command-line argument. This means you don't have to worry about modifying and writing the hgweb script anywhere. All you'd have to do is:
//do stuff to get location of repository from MySQL into variable $x
//run shell script
$res = `python hgweb.py $x`;
You can run shell scripts from within PHP. There are various ways to do it, and complications with some hosts not providing the proper permissions, all of which are well-documented on php.net. That said, the simplest way is to simply enclose your command in backticks. So, to unzip a file, I could say:
`unzip /path/to/file`
SO, if your python script is such that it can be run from a command-line environment (or you could modify it so to run), this would seem to be the preferred method.
As far as you question, no, you're not likely to get php to execute a modified script without writing it somewhere, whether that's a file on the disk, a virtual file mapped to ram, or something similar.
It sounds like you might be trying to pound a railroad spike with a twig. If you're to the point where you're filtering access based on user permissions stored in MySQL, have you looked at existing HG solutions to make sure there isn't something more applicable than hgweb? It's really built for doing exactly one thing well, and this is a fair bit beyond it's normal realm.
I might suggest looking into apache's native authentication as a more convenient method for controlling access to repositories, then just serve the repo without modifying the script.

Categories