Secure php system calls for online code verification

Although I know that system calls and security do not go hand in hand, there is a project for which I need it. I am writing a small code check, and I need to compile and execute the user-submitted code to test my test cases.

Basically, I want to run the code in the sandbox so that it cannot touch any files outside the temporary directory, and any files that it creates cannot be accessible to the outside world. Recently, I came across an exploit 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 file owner is apache, the attacker can basically move my entire /var/www where mysql passwords are stored along with other configuration information.

While I know about threats such as SQL Injections, and have deactivated user input before any database operations, I donโ€™t know how to configure the sandbox. What are the methods that I can use to turn off system calls (right now I'm looking for the word "system" in the code submitted by the user and do not execute these fragments where it is found) and restricts access to the files that the user generated code.

At the moment, my code check only works for C, and I plan to add support for other languages, such as C ++, Java, Ruby, and Python, after I can protect it. I would also like to know more about this issue that I have encountered, so pointers to a place where I could learn more about Internet security will also be appreciated.

My development machine runs Mac OS Lion, and the deployment machine is a Linux server, so if a solution that was a cross platform would be very useful, but one that only applies to a Linux machine would work too .

+7
source share
5 answers

What you probably want to do is configure chroot in some random temp directory on your file system for the user running your scripts. Here are some of them: configuring chroot , and some security for -know's.

I would advise you to also install a security module such as suExec or MPM-iTK for Apache. Then, in your Apache VirtualHost (if you are not using a virtual host, do it!), Assign a specific UserID to handle requests for that particular VirtualHost. This separates the request from the default Apache user and adds a little security.

  AssignUserID nonprivilegeduser nonprivilegeduser 

Then validate PHP a bit by setting the following PHP options so that the user cannot access files outside of certain directories and move your tmp_dir and session_save_path to this directory. This will prevent users from accessing outside 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 PHP strings, deny access to certain functions and classes , and read the PHP security report .

In addition, I would like you to look into this user by disabling access to sudo and su to prevent the script from trying to gain access to root privileges. Read more ... here .

In general, you said it beautifully and clearly. It is impossible to completely prevent user access to your system if they have a desire. The trick is to make it as complex and confusing as possible for them.

+5
source

It is impossible to complete this work on a cross-platform basis, period. The sandbox is inherently very specific to the system.

Mac OS X has a Sandbox object. It is poorly documented, but quite effective (Google Chrome is highly dependent on it). Some enterprising souls have documented parts of it. However, it is only available on Mac OS X, so this may be a rule out.

On Linux, your options are much less developed. Some kernels support the seccomp mechanism to prevent the use of any process other than a small โ€œsafeโ€ set of system calls; however, not all. Moreover, this โ€œsafeโ€ subset does not include some of the calls that you will most likely need in code that was not specifically written to work under seccomp โ€” for example, mmap and sbrk not allowed, so you cannot allocate memory. Helper tools like seccomp-nurse can get you anywhere.

+1
source

Here is what I propose to do.

1. Disable system classes and functions in php.ini using

 disable_functions="system,curl_init,fopen..." disable_classes="DirectoryIterator,SplFileObject..." 

2. Run in a read - only environment without important data stored on it. In case anyone ever got to your server, you do not want them to have access to anything. A good way to do this is to buy Amazon AWS EC2 and use a jailed user to run your server and PHP.

3. Ask people to break it. The only way to find flaws and loop holes that you don't know about is to find them. If necessary, run a temporary server with a "test" application, which will replicate the same type of application, and your "production" environment will be.

Here are some useful resources.

+1
source

I think you are looking for Mandatory Access Control. On Linux, it is available through SeLinux. Using it, you can limit who can execute which command. In your case, you can restrict the php (Apache) user to execute only limited commands such as gcc, etc. Also see AppArmor

Also consider runkit php virtual environment

+1
source

You can try running the user-submitted code in a container (docker), which is a very lightweight VM. They start in less than a second.

0
source

All Articles