71 lines
2.1 KiB
Plaintext
71 lines
2.1 KiB
Plaintext
== 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.
|
|
|
|
|