As I write this, http://php.net/quickref.php lists 3,917 functions, which account for many language constructs that behave like functions. Rather than distinguish between the two, I have chosen to treat them all as functions.
With such a large list, I can’t possibly begin to recommend the most appropriate and secure use of each. Instead, I have chosen the ones that I think require the most attention. My choices are based upon the frequency with which each is used, the amount of risk (or protection) associated with their use, and my own experience.
For each function listed, I provide a recommendation regarding its use. While making this recommendation, I consider security to be paramount. Adjust this approach as necessary to best fit your own needs.
When a function has the same risks as another, a reference is made to the other function rather than offering a redundant explanation.
The eval() function is used for evaluating a string as PHP. For example:
<?php
$name = 'Chris';
$string = 'echo "Hello, $name";';
eval($string);
?>This executes $string as if it were PHP, so this is equivalent to the following:
<?php
$name = 'Chris';
echo "Hello, $name";
?>While useful, eval() is very dangerous when tainted data is used. For example, if $name is tainted, an attacker can execute arbitrary PHP code:
<?php
$name = $_GET['name'];
eval($name);
?>I recommend that you avoid using eval() when possible and when you cannot ensure that you never use tainted data in the construction of a string to be interpreted as PHP. This function is a good candidate for inspection during a security audit or peer review.
As described in Chapter 6, executing shell commands is a very dangerous operation, and the use of tainted data in the construction of a shell command creates a command injection vulnerability.
Try to avoid using shell command functions, but when you require them, be sure to use only filtered, escaped data in the construction of the command to be executed:
<?php
$clean = array();
$shell = array();
/* Filter Input ($command, $argument) */
$shell['command'] = escapeshellcmd($clean['command']);
$shell['argument'] = escapeshellarg($clean['argument']);
$last = exec("{$shell['command']} {$shell['argument']}", $output, $return);
?>The file() function is one of my favorite ways to read a file. It returns an enumerated array in which each element of the array is a separate line in the file. What makes it particularly convenient is that you don’t have to give it a file handle—you provide the filename, and it takes care of everything else for you:
<?php
$contents = file('/tmp/file.txt');
print_r($contents);
?>Given a file with two lines, this will output something similar to the following:
Array
(
[0] => This is line one.
[1] => This is line two.
)Using fopen() is not particularly risky, but when used in combination with the allow_url_fopen configuration directive enabled, it can read many different types of resources such as the content of a remote web site:
<?php
$contents = file('http://example.org/');
print_r($contents);
?>This outputs the following (output abridged):
Array
(
[0] => <html>
[1] => <head>
[2] => <title>Example Web Page</title>
[3] => </head>
[4] => <body>
...
[11] => </body>
[12] => </html>
)If tainted data is used to construct the filename to be read with file(), the contents must be considered tainted. This is because the tainted data used to construct the filename might cause you to reference a remote resource that returns malicious data. Once you store this data in a variable, the danger increases drastically:
<?php
$tainted = file($_POST['filename']);
?>Every element in the $tainted array is just as dangerous as $_POST['filename']—it is input and must be filtered.
Here, this behavior is likely unintentional—the misuse of $_POST['filename'] can change the behavior of file(), so that it references a remote resource instead of a local one.
See "file().”
As described in Chapter 5, the use of include is common and necessary for an organized and modular software design. However, improper use of include can create one of the most drastic security vulnerabilities—code injection.
It is extremely important that you use only filtered data in an include statement. This function is a good candidate for inspection during a security audit or peer review.
See "exec().”
The phpinfo() function produces a page of information about PHP—which version is running, how it is configured, and so forth. Because the output of phpinfo() is so informative, I recommend restricting access to any resource that uses this function.
If you use the technique described in Chapter 8 to protect your database access credentials, you want to be sure that you never display the output of phpinfo() to the public because it exposes the contents of the $_SERVER superglobal array.
See "exec().”
The preg_replace() function is useful for making string replacements that match a pattern. It can be extremely dangerous when tainted data is used to construct the pattern, however, because the e modifier makes it treat the replacement parameter as PHP code after the substitution.
When used with the e modifier, regardless of whether it is intentional, it carries the same risk as eval(). This function is a good candidate for inspection during a security audit or peer review.
See "exec().”
See "file().”
See "include.”
See "exec().”
See "exec().”