CVE-2018-1000533: Improper Input Validation (CWE-20)
value: klaussilveira GitList version <= 0.6 contains a Passing incorrectly sanitized input to system function vulnerability in `searchTree` function that can result in Execute any code as PHP user. This attack appear to be exploitable via Send POST request using search form. This vulnerability appears to have been fixed in 0.7 after commit 87b8c26b023c3fc37f0796b14bb13710f397b322.
CWE description: The product receives input or data, but it does
        not validate or incorrectly validates that the input has the
        properties that are required to process the data safely and
        correctly.
CVSS v3 base score: 9.8
Published: 2018-06-26T16:29Z
Repository: https://github.com/klaussilveira/gitlist
Language: PHP
Files changed: src/Git/Repository.php, tests/RepositoryTest.php
Commit date: 2018-04-24 11:16:32 -0400
Commit message: Fixed RCE in git grep.

A specific option in git grep could be added inside the
pattern to be searched for, resulting in possible RCE.

Thanks to Kacper Szurek (https://security.szurek.pl) for
catching this one!

Diff: diff --git a/src/Git/Repository.php b/src/Git/Repository.php
index 4435b11..136907c 100644
--- a/src/Git/Repository.php
+++ b/src/Git/Repository.php
@@ -320,19 +320,21 @@ class Repository extends BaseRepository
     {
         if (empty($query)) {
             return null;
         }
 
+        $query = preg_replace('/(--?[A-Za-z0-9\-]+)/', '', $query);
         $query = escapeshellarg($query);
 
         try {
-            $results = $this->getClient()->run($this, "grep -i --line-number {$query} $branch");
+            $results = $this->getClient()->run($this, "grep -i --line-number -- {$query} $branch");
         } catch (\RuntimeException $e) {
             return false;
         }
 
         $results = explode("\n", $results);
+        $searchResults = [];
 
         foreach ($results as $result) {
             if ($result == '') {
                 continue;
             }
diff --git a/tests/RepositoryTest.php b/tests/RepositoryTest.php
new file mode 100644
index 0000000..65cf9f5
--- /dev/null
+++ b/tests/RepositoryTest.php
@@ -0,0 +1,28 @@
+<?php
+
+use GitList\Git\Client;
+use GitList\Git\Repository;
+use PHPUnit\Framework\TestCase;
+use Prophecy\Argument;
+
+class RepositoryTest extends TestCase
+{
+    public function testIsSanitizingSearchWithPager()
+    {
+        $client = $this->prophesize(Client::class);
+        $client->run(Argument::type(Repository::class), "grep -i --line-number -- '=sleep 5;' master")->shouldBeCalled();
+
+        $repository = new Repository('/tmp', $client->reveal());
+        $repository->searchTree('--open-files-in-pager=sleep 5;', 'master');
+        $repository->searchTree('-O=sleep 5;', 'master');
+    }
+
+    public function testIsSanitizingSearchWithAnyOption()
+    {
+        $client = $this->prophesize(Client::class);
+        $client->run(Argument::type(Repository::class), "grep -i --line-number -- 'foobar  =bar;' foo")->shouldBeCalled();
+
+        $repository = new Repository('/tmp', $client->reveal());
+        $repository->searchTree('foobar --bar --foo=bar;', 'foo');
+    }
+}

Vulnerable code:             $results = $this->getClient()->run($this, "grep -i --line-number {$query} $branch");
Fixed code:         $query = preg_replace('/(--?[A-Za-z0-9\-]+)/', '', $query);
            $results = $this->getClient()->run($this, "grep -i --line-number -- {$query} $branch");
        $searchResults = [];
<?php

use GitList\Git\Client;
use GitList\Git\Repository;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;

class RepositoryTest extends TestCase
{
    public function testIsSanitizingSearchWithPager()
    {
        $client = $this->prophesize(Client::class);
        $client->run(Argument::type(Repository::class), "grep -i --line-number -- '=sleep 5;' master")->shouldBeCalled();

        $repository = new Repository('/tmp', $client->reveal());
        $repository->searchTree('--open-files-in-pager=sleep 5;', 'master');
        $repository->searchTree('-O=sleep 5;', 'master');
    }

    public function testIsSanitizingSearchWithAnyOption()
    {
        $client = $this->prophesize(Client::class);
        $client->run(Argument::type(Repository::class), "grep -i --line-number -- 'foobar  =bar;' foo")->shouldBeCalled();

        $repository = new Repository('/tmp', $client->reveal());
        $repository->searchTree('foobar --bar --foo=bar;', 'foo');
    }
}