== How to fix it in Core PHP

=== Code examples


include::../../common/fix/code-rationale.adoc[]

Other standard PHP functions are susceptible to the same vulnerable behavior.
Especially, the `mail` function accepts, as its fifth argument, parameters that
will be appended to the configured mail-sending program command line. This might
lead to a similar exploitation scenario.

==== Noncompliant code example

[source,php,diff-id=1,diff-type=noncompliant]
----
$arg=$_GET['file'];
echo "<h1>File search results:</h1><br/>";
$cmd=escapeshellcmd('find /tmp/images -iname ' . $arg);
passthru($cmd);
----

[source,php,diff-id=2,diff-type=noncompliant]
----
$arg=$_GET['arg'];
echo "<h1>Sending test mail.</h1><br/>";
mail("mail@example.org", "example subject", "Example", [], $arg);
----

==== Compliant solution

[source,php,diff-id=1,diff-type=compliant]
----
$arg=$_GET['file'];
echo "<h1>File search results:</h1><br/>";
$cmd='find /tmp/images -iname ' . escapeshellarg($arg);
passthru($cmd);
----

[source,php,diff-id=2,diff-type=compliant]
----
$arg=$_GET['arg'];
echo "<h1>Sending test mail.</h1><br/>";

$allowed_args_mapping = ["-n","-v"];
if (! in_array($arg, $allowed_args_mapping, true)) {
	$arg = "";
}
mail("mail@example.org", "example subject", "Example", [], $arg);
----

=== How does this work?

include::../../common/fix/introduction.adoc[]

When building a system command from user-submitted data is unavoidable, using
the `escapeshellarg` sanitizing function should be preferred. It ensures that
the provided data will be considered a single argument and prevents the
injection of subsequent ones.

It is also important not to combine both `escapeshellarg` and `escapeshellcmd`.
Indeed, a call to `escapeshellcmd` on a complete command line will void any
escaping previously added with `escapeshellarg`.

Therefore, it is impossible to prevent an argument injection issue in the
`mail` function with `escapeshellarg`. Indeed, `mail` internally relies on
`escapeshellcmd` for escaping purposes. In that case, an allowlist of
explicitly trusted additional arguments should be used.


