Sandboxing PHP Phar files - php

i am making an application that has the ability to run plugins, now i wish to sandbox these plugins to only be able to run in their own environment (not able to access files from the installation) and not be able to access configuration settings (such as the database password which are defined by 'define' variables)
What should i use to sandbox my phar plugins?

There are 3 basic ways to add sandboxing functionality to your application.
Use a new PHP process execution environment and use the OS's security mechanisms to create a sandbox. Communication between the application process and the sandboxed process would use some network protocol (as the OS sandboxing would limit IPC and/or pipe communcation). Examples would include chroot environment or docker plus zeromq.
Use a new PHP process and a PHP extension to enable security features like limiting includes and network functionality. Examples include suhosin, suPHP, (to a lesser extent) forking and exec().
Use your existing application process and a PHP extension to enable and then disable secure features before and after executing plugin code. Examples include suhosin
The 3rd option seems to be the easiest, yet weakest, solution because anything that you could turn on with suhosin a malicious plugin could probably turn off.
You must list the requirements of your sandbox, like disallowing environment variables, restricting include paths, restricting network connectivity and restricting database connectivity, then make trade-offs with complexity of the solution and the priority of the desired features.
It sounds like you are already executing the PHAR files in a new process from your application. If you are doing something like "exec('php ./plugin.phar')" you are limited to changing the user, unless your main application is running as root. You could have some sort of plugin manager process constantly running as root and using exec to switch users while executing the external phar plugin, but that wouldn't limit the FS access.

Related

How to enable the Virtual Directory Support php?

I see "Virtual Directory Support" is disabled in phpinfo.php, how can I enable it ?
In short: You can't easily. And you should not.
Longer story: PHP is supposed to provide a shared nothing environment. In this context this means if two scripts are running in parallel they should not interfere. In most cases this is no issue as different scripts use different processes. (Apache module with mod_prefork, FastCGI, fpm etc.)
But in some scenarios people use PHP as a module in a threaded environment. (Microsoft IIS module, Apache mod_mpm module etc.) If that is the case PHP can't rely on the operating system to separate context but has to do it itself.
One relevant area is the current working directory. The option you mentioned is about that and the name is misleading: it is not "Virtual Directory Support" but "Virtual Current Working Directory Support". It is an abstraction for file system operations.
So when having two PHP requests in different threads and code like include "./foo.php";, you want that to be relative to the request's main script and not the global state of the environment. VCWD support does that. As it is only relevant for threaded environments enabling/disabling is bound to the setting whether PHP is built thread safe or not, which is done at compile time. Unless you need to, this is off.
As a user you shouldn't care about it - it is not related to the ability to use streams or something from your PHP script.
Compiling with --enable-maintainer-zts should do it.
But make sure you know what it does, here is an explanation.

Limit PHP Execution?

We are working on making a wordpress type system from scratch with a templating system and am wondering about security. We hope to have a SaaS model where the user will be on the same server as a few other users, but we hope to also give them the tools to modify their own Views files, which means PHP access. We are using Laravel as the framework. As a long time Dreamhost user, I know you can section the same machine off into multiple environments, but not really sure what they were using to do so.
How can I prevent the execution of commands like eval(), system commands, and limit the users access to fopen (I assume that is mostly through the linux user permissions). I would like to give them direct file access to the Views folder and to develop their own solutions instead of forcing them to go through me, but without jeopardizing too much. If there are mysql considerations beyond separate users, feel free to chime in there as well.
There are several layers that you need to protect.
Some of the hosters incorrectly rely on PHP "protections" like open_basedir, safe_mode (older PHPs), disable_functions etc.
Even PHP does NOT consider them being security features - http://php.net/security-note.php
These can be disabled with any exploit for PHP and then the whole system is doomed, do not do that.
How it should be done
the bottom
Separate OS-level/system user for each hosted site
correct permissions (one can't be able to view/edit page of the other one) - also make sure sub-directories have correct permission as they're going to be similar
separate session files (LOT of webhostings put session files of each PHP-hosted site into the same directory, that's bad bad bad!
Apache finally got it's own module for this - Apache MPM-ITK.
Long story short: picture this as you'd give the user a shell on the machine (under his own uid) - he can't be able to do anything to the other hosted sites.
different uid/gid
system permissions
framworks like SELinux, AppArmor and similar
grsecurity if you want to be hardcore.. but the system will be harder to maintain.
going up?
You can get more hard-core. The best I've seen is a shared-library for apache (or whatever you use) - that is used when apache is started using LD_PRELOAD and it implements all the potentially malicious system calls like system(), execve() and basically any other call that you find bad.
I haven't seen a good implementation of this out there yet (other than custom ones somewhere) - correct me if I'm wrong.
Make sure to implement a white-list for this as eg. mail() in PHP executes sendmail by default and that won't work anymore.
conslusion
Add classic disable_functions, open_basedir, etc. into global php.ini, add session.save_path to every vhost - put sessions into user directories. Make sure users don't share anything.
Implement underlaying OS-level separation correctly.
Get hardcore with grsec and LD_PRELOAD lib hooking system calls.
Separation, separation, separation .. soon enough systems like Docker will provide LXC-based containers to separate users on kernel level but it's not quite production ready yet (imho).

What is best PHP Handler for APC [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I utilize APC for opcode in par with 4-cpu license Litespeed.
What is the best PHP handler for this situation in term of performance first, and security later?
Is it suphp / dso / fcgi / cgi ? (i read that DSO can leave a hole if one of the script has a bug) ?
myusername#mybox [~]# /usr/local/cpanel/bin/rebuild_phpconf --available
Available handlers: suphp dso fcgi cgi none
PHP4 SAPI: cgi
PHP5 SAPI: not installed
SUEXEC: available
RUID2: not available
Thank you.
There is a great article on this on Servint Blog: http://blog.servint.net/2011/10/28/the-tech-bench-all-about-php-handlers/
Be sure to visit there site it also has comparison charts.
List of PHP handlers
DSO
Also known as mod_php. While this is an older configuration, its main benefit is speed. It is generally considered the fastest handler. It runs PHP directly from Apache, without having to pass it to a separate service for processing. This means that PHP scripts will run as the Apache user, which by default on our servers is the user ‘nobody’.
DSO has two things to consider before switching to it. First, any files that need to be written to by the webserver have to have write permissions for the ‘nobody’ user, and any file created by the webserver will be owned by ‘nobody’. Websites that need to upload files through PHP may run into permissions issues, since the settings aren’t as clear cut as the other handlers. This is common with WordPress users that upload files through the WordPress interface or utilize the auto-update feature.
A special note about the above: it is a common misconception that files need to have the 777 mode to be writable. This is not true, and generally a bad idea since it means the files are writable by anyone. To make a file writable by the webserver, the highest permissions needed should be 664 and owned by ‘user’ and group ‘nobody’. For directories this would be 775 and user:nobody. This should be enough to allow the webserver to write to the location without making it writable by everyone and introducing a potentially critical security vulnerability.
Also, know that DSO offers a different type of security as opposed to suPHP/FastCGI. Since the server runs it as ‘nobody’ anyone that would be able to exploit a file on your server to gain elevated privileges will have access to any other file that the webserver can directly access. What this simply means is that an intruder could have access to files across multiple accounts, but only those files that are owned by ‘nobody’. Please see the Security section below for more information.
The main advantage of DSO is speed and resource usage. With opcode caching extensions like eAccelerator or APC installed, DSO will run significantly faster and at a lower footprint than the other handlers. It is also the default setting on our servers.
A good rule of thumb is that DSO is best for servers that are running one or two large, high-performance websites where efficiency and speed are a concern.
CGI
CGI handler will run PHP as a CGI module as opposed to an Apache module. The CGI method is intended as a fallback handler for when DSO is not available. This method is neither fast nor secure, regardless of whether or not suEXEC is enabled. ServInt therefore does not recommend using CGI.
suPHP
suPHP runs PHP as a separate service that then passes the compiled code back to Apache for serving. It is technically a CGI module, however it is much different than the CGI handler mentioned above. The main difference, and the advantage of having suPHP, is that with suEXEC enabled it runs the PHP scripts as the user calling them, rather than as the ‘nobody’ user. For example, if an account is owned by the user Spock, all instances of Apache serving that user’s website will run as user Spock. The advantage here is that it makes tracking down websites using excessive resources easier.
Another advantage of running the process as the user is that it simplifies the overall permissions scheme. The webserver will be able to write to files that are owned by the user and not just ‘nobody’. What this means in the long run is that auto-update/install features in many CMS solutions will work more easily, and the general permissions of your file/directories is more clear-cut: 644 and owned by user and group user for files, and similarly 755 and user:user for directories.
The security difference between suPHP and DSO is that suPHP confines an intruder to the particular user that he/she has affected. The exploit can’t cross accounts, however it can affect every single file the user owns as opposed to just the files writable by the webserver. Please see the Security section below for more information.
The main disadvantage of suPHP is speed and CPU load. suPHP runs much slower than the other handlers, and you will see significant increase in your overall CPU load when switched to it. suPHP also cannot work with an opcode caching extension such as eAccelerator or APC, which is part of the reason for the increase in CPU usage. Because of this, it is recommended that you implement a caching plugin if you use this with a CMS, such as W3-Total-Cache for WordPress. This handler is recommended more for the smaller reseller client. This is because it locks down exploits to one affected account, and the CPU load increase will not be that significant with less busy sites or small number of individual cPanel accounts.
FastCGI
FastCGI (aka: mod_fcgid) is similar to suPHP in that it is a separate process that compiles the PHP which is then sent back to Apache. It is also a CGI module, which means with suEXEC enabled PHP runs the process as the user. This allows you the same permissions advantages of suPHP mentioned above. The difference between the two, however, is how they control the PHP processes. suPHP runs each time a PHP process needs to be compiled, whereas FastCGI keeps persistent connections open that can be recalled by the same PHP process. This allows you to use an opcode caching extension such as eAcceleartor or APC with it to increase performance.
The drawback is FastCGI has a high memory usage. Due to the persistent connections mentioned above being stored in memory, you are going to see much more available memory being taken up by FastCGI.
A good analogy of FastCGI and suPHP is to think of a book with several chapters. With suPHP, this book will have no table of contents and no index, so each time you want to find something you have to look through the book to get it. This takes time (increased CPU usage) and is slow. With FastCGI, this book has an extensive index and table of contents, so you can quickly and easily find what you are looking for; however these additional pages make the book much thicker (increased memory usage).

Secure system calls with php for an online Code Checker

While I do know that system calls and security don't go hand in hand, there is a project for which I do need it. I'm writing a small code checker and I need to compile and execute the user submitted code to test against my test cases.
Basically I want to run the code in a sandbox, so that it can't touch any files outside of the temporary directory and any files that it creates can't be accessed by the outside world.
Recently I came across an exploit with with which the user could create a file say shell.php with the following contents.
<?php
echo system($_GET['x']);
?>
This gives the attacker a remote shell and since the owner of the file is apache, the attacker could basically move around my entire /var/www where mysql passwords were stored along with other configuration information.
While I am aware of threats like SQL Injections and have sanitized the user input before any operations that involve the DB, I have no idea as to how I can set up the sandbox. What are the techniques that I can use to disable system calls (right now I'm searching for the word 'system' in the user submitted code and not executing those snippets where it is found) and restrict the access to the files that the user submitted code creates.
As of now my code checker only works for C and I plan to add support for other languages like C++, Java, Ruby and Python after I can secure it. Also I'd like to learn more about this problem that I've encountered so pointers to a place where I could learn more about web security would also be appreciated.
My development machine is running Mac OS Lion and the deployment machine is a linux server so if a solution, that was cross platform would be most appreciated but one that dealt with just the linux machine would do too.
What you will probably want to do is set up a chroot to some random temp directory on your filesystem for the user running your scripts. Here is some reading on setting up a chroot, and some security to-know's.
I would suggest you also install a security module such as suExec or MPM-iTK for Apache. Then, within your Apache's VirtualHost (if you are not running a virtual host, do so!), assign a specific UserID to handle requests for this specific VirtualHost. This separates the request from the Apache default user, and adds a little security.
AssignUserID nonprivilegeduser nonprivilegeduser
Then, harden PHP a little by setting the following PHP options so the user cannot access files outside of the specific directories, and move your tmp_dir and session_save_path within this directory. This will prevent the users access outside of their base directory.
php_admin_value open_basedir /var/www/
php_admin_value upload_tmp_dir /var/www/tmp
php_admin_value session.save_path /var/www/tmp
Along with the lines of PHP, prevent access to specific functions and classes, and read up on PHP's security write-up.
Also, I would have you look into for that user, disabling access to sudo and su, to prevent a script from attempting to access root privileges. Learn more, here.
All in all, you said it nice and clear. There is no way to fully prevent a user from accessing your system if they have the will. The trick is to just make it as difficult as possible, and confusing as possible for them.
There is no way to make this work on a cross-platform basis, period. Sandboxing is inherently highly system-specific.
On Mac OS X, there is the Sandbox facility. It is poorly documented, but quite effective (Google Chrome relies heavily on it). Some enterprising souls have documented parts of it. However, it's only available on Mac OS X, so that probably rules it out.
On Linux, your options are considerably less developed. Some kernels support the seccomp mechanism to prevent processes from using any except a small "safe" set of system calls; however, not all do. Moreover, that "safe" subset doesn't include some calls that you are likely to need in code that hasn't been specifically written to run under seccomp -- for instance, mmap and sbrk are not permitted, so you can't allocate memory. Helper tools like seccomp-nurse may get you somewhere, though.
Here are the things I suggest doing.
1.
Disable system classes and functions in php.ini with
disable_functions="system,curl_init,fopen..."
disable_classes="DirectoryIterator,SplFileObject..."
2.
Run in a read only environment with no important data stored on it. In case anyone ever got into your server you don't want them to access anything. A good way to do this is buy an Amazon AWS EC2 and use a jailed user to run your server and PHP.
3.
Ask people to break it. The only way you can find flaws and loop holes that you are unaware of is to find them. If necessary, get a temporary server with a "test" application that replicates the same type of application your "production" environment will be.
Here are some helpful resources.
List of functions to disable. It can definitely be expanded upon but it's a good start.
Information on to avoid security issues.
The source and README in Viper-7's Codepad
I think what you are looking for is Mandatory Access Control. In Linux, it is available via SeLinux. Using it you can limit who can execute what command. In your case, you can limit the php user (Apache) to execute only limited commands like gcc etc. Also look into AppArmor
Also, look into runkit php virtual environment
You can try to run user submitted code in a container (docker) which are very light weight VMs. They start in less than a second.

Is there a safe way of allowing users to add their own PHP to my server?

I'm developing a platform that allows users to create apps using PHP. Is there any safe way of allowing users to do this? Can you restrict use of functions that could damage existing source code or the server in anyway? I only want them able to use basic functions, and give them access to 1 database. This must be possible, because of the existence of shared servers, ran by many users.
...
Any advice?
You can list all disabled functions in your php.ini. You can set it differently for every vhost
disable_functions = "exec,passthru"
Shared hostings are just doing the same as I stated above.
Other functions that can be considered to diable:
readfile,fopen,fsockopen,popen,file_get_contents, include,stream_context_create,chmod,chown
Complete list can be found here
But if you are using these functions inside your code also, It's better to made all code files readonly to apache user or for all, in this case chown and chmod disabling play great role.
Never did this before, but i think this approach can help you with a sane and secure environment.
If you are on ubuntu (debian based) i recommend you create a jailed chroot. From the link
A chroot is basically a special directory on your computer which
prevents applications, if run from inside that directory, from
accessing files outside the directory. In many ways, a chroot is like
installing another operating system inside your existing operating
system.
You must also install a dedicated instance of PHP that must be used by applications runned from inside of chroot'd directories.
You can configure your php.ini with "max_execution_time", "disable_functions", ... etc
this is exactly what you need actually.
I used to run a shared server using PHP safe mode, but apparently it's deprecated now.
A better solution is to run each user's PHP processes under a different user account, in a chroot jail, and let the OS worry about security. Users will be able to upload and run arbitrary code, but as long as it's properly sandboxed, they won't be able to do much harm.
You can also use disk quota. Use ulimits for per-user memory usage, and consider disallowing network connections (incoming and outgoing).
For the database, just set them up with a single database, with access to only their own, and don't give them privileges to create more.

Categories