title: Correct and secure way to have PHP execute a shell script
body: <p>I'm working on an application where people (anyone) can upload code (Java and possibly C(++) to start with) that will be compiled and run on the server. This is of course a huge security risk and it will be necessary that all this is sandboxed properly. <strong>This sandboxing is out of the scope of this question though.</strong> Assume that is have been taken care of.</p>
  
  <p>Next to this, there will be functions in the system that will rely on shell commands and PHP's exec(), shell_exec(), etc. functions. The commands that will need to be executed aren't very many, mainly java(c), gcc, g++, etc. It would be fairly easy to make a list of the commands that we would need, if necessary. It will not be possible for a user to execute other commands than the once we decide. For example, someone uploads some java code and asks the server to compile it. Then the server will run javac. The user's input can only change javac's parameters (that are escaped using escapeshellarg()). </p>
  
  <p>I'm wondering what security precautions I should still take. I was planning to use PHP's safe mode, so that only files in the <code>safe_mode_exec_dir</code> could be executed. I was also planning to have the ownership of the shell files set to <code>root:www-data</code> so that www-data cannot change permissions or ownership, and furthermore to have the permissions something like <code>rwxr-xr--</code> so that www-data cannot modify the file. However, <strong>safe mode has been removed from PHP as of 5.4.0</strong>. What is the current way to do stuff like this?</p>
  
  <p>Would it be safer to have these shell commands run by an entirely different user, that doesn't even have access to any other directories than <code>safe_mode_exec_dir</code>? How would I then go about that?</p>
  
  <p>Another option would be to have PHP only maintain a list of things that need to be done, and let a cronjob run every minute or so, by a restricted user, to walk through the list and perform the necessary operations. Would that be a safer approach? Because of the up-to-one-minute delay, I would prefer to do this from PHP directly.</p>
  
  <p>I have full access to my server but <strong>due to policies I am not allowed to use virtualisation.</strong></p>