I want to execute a PHP file with exec, to handle a process in the background, where 1234567 is an id I wish to call from a database to get some information about what I am about to process.
exec('/var/www/somescript.php 1234567 > /dev/null &');
Are there any potential security issues or problems I may run into?
Should I use escapeshellarg() on the parameter I am passing in?
I'm sure this depends on if this should be called via a web user and if the arguement or executed command is created by the user.
Using escapeshellarg() in my opinion should always be called as you wouldn't use the MYSQL_ function and not escape any of the input due to risk of SQL injection. Using the exec function is a similar issue, you wouldn't use the script without escaping the input. However, escaping the input doesn't necissarily stop people abusing the script.
You do need to make sure validation has been done for any arguments sent over to the script for example you don't want anyone to comment out your script and in the arguement section inject a completely different script to maybe add a user (this shouldn't be allowed to happen given propper permissions).
I would use this as the last resort, if the issue can't be solved any other way rather then using an exec.
Related
This question already has answers here:
PHP: How To Disable Dangerous Functions
(6 answers)
Closed 6 years ago.
I want to allow users to create own apps with php on my webpage. The problem is they have access to some dangerous commands like chmod(). I'm not sure what to do.
I want to run their apps with eval(), but I don't know much dangerous commands and I want to prevent from using any of them. So maybe anyone can make a function to run die() when there is dangerous content in the code? Or maybe give a list of commands that users shouldn't be able to run?
EDIT: I don't want to disable eval(). I want to prevent users from using functions that can be endanger the site.
EDIT: I don't own access to php.ini as I'm working on subdomain and there is one php.ini for whole domain. And I don't want to disable commands for whole site, just for one eval...
Don't. There is no way to do this safely.
PHP was not designed for this application. It has no way to filter function calls at runtime.
Filtering user-generated code is unlikely to be effective either. There are a lot of subtle ways to bypass all of the obvious approaches to filtering -- for instance, a function call can be concealed by using indirect function call syntax:
$fn = "system";
$fn("evil command");
or by using commands which you may not realize are equivalent to eval, such as assert, create_function, or even preg_exec in some versions of PHP.
In general eval() is not the best choice, for most cases one should try something else (When is eval evil in php?).
With the above in mind, it's possible to create an (almost) safe environment.
You should create a user with very low privileges and give him the permissions only to read/write in specific folders. Then run the users' php code as this user: this will not prevent bad functions, but limit them in a sort of sandbox.
But, as duskwuff pointed out, php is not made with that in mind, so be careful!
I said almost because running arbitrary code on a machine is not safe, it could not be safe.
EDIT 1: check out this link: https://github.com/Corveda/PHPSandbox
EDIT 2: other link: Is there a way to execute php code in a sandbox from within php
I'm building a web application and I'm concern with security.
Is it a way to make a "php injection", in the same way it is possible to make "SQL injection" ? That means client can send some php code which will be executed on the server.
Until we don't use the "eval" function, I would like to say "no" because when we get a value by $_GET and $_POST, all the data are treated as simple string... But maybe I don't see an obvious attack.
In general, not unless you evaluate it with something that might parse and execute PHP. You already mentioned eval, but there are other functions that have eval-like properties (e.g. preg_replace, if the attacker manages to inject the /e modifier) or can otherwise allow unwanted levels of access (e.g. system()).
Also, if an attacker can upload a file and get it interpreted as PHP, he can run PHP code. nginx can be easily misconfigured in a way that allows attackers to execute PHP code in image files. The same goes for getting your web site to include() his code - possibly by overwriting your files with his uploads, or changing the include() arguments to point to a remote site (if that is not disabled in php.ini).
There are a number of ways in which you could, potentially, have a "PHP injection". eval is one of them. shell_exec and related functions are a risk too (always use escapeshellarg!) But the common theme is putting user input somewhere it can be executed. This is the case with SQL injections, where the query is a string that contains user input and is then executed on the MySQL server.
One slightly more obscure example is file uploads. If you allow uploading of files to your server, do NOT allow unfettered access to them! Someone could upload a PHP file, then access it and get full control of your site, so... yeah, be careful with uploads!
You would call it PHP injection if the PHP script ”constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment”[1].
So for PHP as the processor, any function, whose parameter are being interpreted as PHP, directly or indirectly, may be prone to PHP injection. This includes obviously the eval function, but also functions like create_function, and preg_replace with PREG_REPLACE_EVAL modifier.
Furthermore, this also includes routines that generate PHP code for being written to file like configuration files during an application setup. Or routines that execute PHP via php -r …, even when escaped via escapeshellarg.
Have a look at the observed examples for CWE-94: Improper Control of Generation of Code ('Code Injection').
Well, header says it all.
in php, how do I reverse escapeshellarg()?
To be more precise, what is the built-in function (if there is one) that will reverse it.
Most thorough route would be to find out exactly what escapeshellarg() does and do the opposite. In a linux environment, it looks like it's just taking care of single quotes. In a Windows environment, it's doing a bit more. Your reverse function should take that into account as well.
Regarding a built-in function:
The short answer is "there isn't one." The long answer is: there isn't one because escaped shell arguments aren't ever intended to get parsed by PHP (why escape them in the first place?) so nobody ever wrote one and submitted it as a patch to PHP. If you're passing arguments into a CLI PHP application, you don't need to unescape things as that was done already by the interpreter.
Usecase:
When creating a command, all args have to be properly escaped. But when using PS to find if that command is executing, the quotes are stripped. So a comparison is difficult.
In the case where the only programs to check are the ones started by php saving the PID is ok, but if we have to take into account processes which have been started from other means, it is more difficult
I want to take the user's input, respond to them, and then update some stuff in the database. But the response doesn't need the stuff from the database, so I don't want the user to have to wait for it. Is there a way to say "I'm all done. Go ahead and send this to the user." but then keep executing more PHP code?
Take a look at exec() in php http://php.net/manual/en/function.exec.php. Just before the end of processing of your php page, you can fire a command with exec() like running a php script cli: http://php.net/manual/en/features.commandline.php (basically runs in the background.). Be sure to note (for exec()):
If a program is started with this function, in order for it to continue running in the background, the output of the program must be redirected to a file or another output stream. Failing to do so will cause PHP to hang until the execution of the program ends.
You can use flush, which will send the data, however it may not have the effect you're looking for (the page will still be loading).
http://us2.php.net/flush
It's used when you've got an admin type script that produces iterative output but might take a while to run.
I want to be able to execute PHP via command line with a $_GET variable. I understand I can do this with exec, but I'd like to understand more of the security risk and what things I should look out for. The parameter I want to pass is a MySQL auto_incremented ID returned from MySQL, so I'm not concerned with user input. But by merely allowing this to happen what things should be considered in regards to security?
The script will accept an order ID and send the customer an email invoice. This allows me to perform this function from multiple sections of the site only maintaining the code in 1 location.
I don't think you really need to execute this from command line. Create a PHP function and include it in your multiple sections instead: it will be faster. Per example:
function sendInvoice($orderId) {
// do something
}
Then call it:
include_once('send_invoice.inc.php');
sendInvoice(42);
This still allows code reuse and a single place where to maintain the code.
Why can't you use argv/argc?
$id = isset($argv[1]) ? (int)$argv[1] : (int)$_REQUEST['id'];
For cmdline scripts $argv is the answer. But you can indeed inject $_GET variables as well. Just pre-define the QUERY_STRING environment variable accordingly:
putenv("QUERY_STRING=id=$id");
exec("php script.php");
Regarding security, cmdline php scripts could be more worriesome on shared hosting servers if they initiate administrative actions. But there is not much you can do about that. Keep strictly cmdline scripts out of the document_root, and apply file or directory permission if anyhow possible.