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.
Related
I have an application with the following code:
<?php
if(isset($_GET['function'])){
$_GET['function']();
}
?>
So if i entered this url: http://localhost/?function=phpinfo
I will see the phpinfo function output on the screen.
can i have a way to concatenate 2 function in the url like this example:
http://localhost/?function=shell_exec('ls') AND phpinfo
So i want to see the first function output..
If you may asking why i need this, is because i am pen testing an web application with this situation..
By the way any suggestion to hack this situation will help.
Thanks for the help..
You cannot concatenate functions as it's not code injection per se, ie: you cannot affect the way the parser reads the code. Further more in the example you provided you have no control over any parameters passed to the function, so what you are proposing is not feasible.
You would have to find a way to pass control to a function which performs unsafe operations directly on user supplied input ($_GET, $_POST, etc) in order to leverage this weakness remote code execution. Depending on the complexity of the application you may be able to identify a function which calls system, eval, unserialize, or another dangerous function on user supplied data.
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').
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.
Is it possible for a PHP script to insert a block of code into a database, and then some kind of daemon sees that it was put in, and then runs the code? Kind of like a cron job, or a job queue.
Technically you can do it. The code should be stored in a TEXT column and then you could evaluate it with eval: http://es.php.net/manual/en/function.eval.php
This is not a very good idea for several reasons: code stored in a database is not under version control, and the security implications are pretty severe. Most job queue systems store a "job type" and "job parameters" instead of executable code. The job type could be the name of a file to include, or the name of a class to instantiate in an OOP setting. Then you would call a specific function defined there, passing in the parameters.
The job parameters can be any PHP data structure if you use the serialize function to turn it into a string first. http://es.php.net/manual/en/function.serialize.php
I have a script that has PHP on it, and a link that goes to a new script that alters that PHP. When writing the query and containing variables on the second script, do I need to use the same variables or are the new ones I create completely seperate? or can will the variables from the first script carry over to the second script if used?
If by "link" you mean you use require or include, then any variables that are defined in the same scope as the "link" will already be defined within that file's "global" scope (under most conditions).
If you are linking to another page via a typical HTML anchor tag, then the answer is no. You can, however, pass along information using HTTP GET method or create sessions through manipulations of $_SESSION in php or by setting cookies in the browser. All of the various ways of maintaining informaion across multiple links really depend on your needs. In the case where you would want to use HTTP GET, you could setup the link in script A to link to script B like this:
Click here
Then in script B you would access that data like this:
<?php
$data1 = $_GET['var1'];
$data2 = $_GET['var2'];
And use it however you need. Of course, be sure to perform sanity checks against the data before accepting it as reliable.
You can try and use sessions
As mentioned by everyone else, HTTP is stateless and nothing is shared unless you explicitly store it. Most of the time you will want to store these in the $_SESSION[] super global, but you could also store them in files, cookies, or the database, although the file system and database introduce larger overhead and cookies can easily be manipulated.
PHP is basically "nothing shared". So, when you build your link, you control the state of the $_REQUEST variable using the query parameters (GET or POST) and the hidden parameters (cookies).
The session ($_SESSION) is a convenient cookie/file storage to migrate common data between pages, but it is typically best to keep session lean and free of non-critical state details.