54 lines
1.5 KiB
Plaintext
54 lines
1.5 KiB
Plaintext
== How to fix it in Core PHP
|
|
|
|
=== Code examples
|
|
|
|
include::../../common/fix/code-rationale.adoc[]
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,php,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
$command = $_GET['cmd'];
|
|
exec($command, $output, $ret); // Noncompliant
|
|
|
|
echo ($ret == 0 ? "OK" : "KO");
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,php,diff-id=1,diff-type=compliant]
|
|
----
|
|
$allowedCommands = [["/bin/ping","-c","1","--"],["/usr/bin/host","--"]];
|
|
$cmd = $allowedCommands[$_GET["cmdId"]];
|
|
$cmd[] = $_GET["host"];
|
|
|
|
$process = proc_open($cmd, [], $pipes);
|
|
$ret = proc_close($process);
|
|
|
|
echo ($ret == 0 ? "OK" : "KO");
|
|
----
|
|
|
|
=== How does this work?
|
|
|
|
include::../../common/fix/introduction.adoc[]
|
|
|
|
include::../../common/fix/pre-approved-list.adoc[]
|
|
|
|
In the example compliant code, a static list of allowed commands is used.
|
|
Users are only allowed to provide a command index that will be used to access
|
|
this list. The command resulting from the list access can be considered
|
|
trusted.
|
|
|
|
:sanitizationLib: proc_open
|
|
include::../../common/fix/sanitize-meta-characters.adoc[]
|
|
|
|
In the example compliant code, the `proc_open` function is used in place of
|
|
the less safe `exec` alternative. Moreover, the `command` parameter of this
|
|
function is set to an array. That way, the function will properly escape all
|
|
the array elements and concatenate them to form the command line to execute.
|
|
|
|
include::../../common/fix/shell_integration.adoc[]
|
|
|
|
In the example compliant code, using the `proc_open` function with an array of
|
|
arguments as a parameter disables shell integration.
|