Skip to content

Commit

Permalink
Merge pull request from GHSA-cwvp-j887-m4xh
Browse files Browse the repository at this point in the history
  • Loading branch information
cedric-anne authored Jul 3, 2024
1 parent 6e49a5b commit fc4cbb2
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 0 deletions.
38 changes: 38 additions & 0 deletions src/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ class Plugin extends CommonDBTM
*/
const OPTION_AUTOINSTALL_DISABLED = 'autoinstall_disabled';

/**
* Plugin key validation pattern.
*/
private const PLUGIN_KEY_PATTERN = '/^[a-z0-9]+$/i';

public static $rightname = 'config';

/**
Expand Down Expand Up @@ -206,6 +211,34 @@ public static function getAdditionalMenuOptions()
return false;
}

public function prepareInputForAdd($input)
{
$input = $this->prepareInput($input);

return $input;
}

public function prepareInputForUpdate($input)
{
$input = $this->prepareInput($input);

return $input;
}

private function prepareInput(array $input)
{
if ($this->isNewItem() || array_key_exists('directory', $input)) {
if (preg_match(self::PLUGIN_KEY_PATTERN, $input['directory'] ?? '') !== 1) {
Session::addMessageAfterRedirect(
__s('Invalid plugin directory'),
false,
ERROR
);
return false;
}
}
return $input;
}

/**
* Retrieve an item from the database using its directory
Expand Down Expand Up @@ -1904,6 +1937,11 @@ public function getPluginOption(string $plugin_key, string $option_key, $default
*/
private function loadPluginSetupFile(string $plugin_key): bool
{
if (preg_match(self::PLUGIN_KEY_PATTERN, $plugin_key) !== 1) {
// Prevent issues with illegal chars
return false;
}

foreach (PLUGINS_DIRECTORIES as $base_dir) {
if (!is_dir($base_dir)) {
continue;
Expand Down
90 changes: 90 additions & 0 deletions tests/functional/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -1008,4 +1008,94 @@ public function testGetPluginOptionsOnUnexistingPlugin()
$plugin = new \Plugin();
$this->array($plugin->getPluginOptions('thisplugindoesnotexists'))->isEqualTo([]);
}

protected function pluginDirectoryProvider(): iterable
{
yield [
'directory' => 'MyAwesomePlugin',
'is_valid' => true,
];

yield [
'directory' => 'My4wes0mePlugin',
'is_valid' => true,
];

yield [
'directory' => '',
'is_valid' => false,
];

yield [
'directory' => 'My-Plugin', // - is not valid
'is_valid' => false,
];

yield [
'directory' => 'мійплагін', // only latin chars are accepted
'is_valid' => false,
];

yield [
'directory' => '../../anotherapp',
'is_valid' => false,
];
}

protected function inputProvider(): iterable
{
foreach ($this->pluginDirectoryProvider() as $specs) {
$case = [
'input' => [
'directory' => $specs['directory']
],
];
if ($specs['is_valid']) {
$case['result'] = $case['input'];
} else {
$case['result'] = false;
$case['messages'] = ['Invalid plugin directory'];
}

yield $case;
}
}

protected function addInputProvider(): iterable
{
yield from $this->inputProvider();

yield [
'input' => [
],
'result' => false,
'messages' => [
'Invalid plugin directory',
],
];
}

/**
* @dataProvider addInputProvider
*/
public function testPrepareInputForAdd(array $input, /* array|false */ $result, array $messages = []): void
{
$this->variable($this->newTestedInstance()->prepareInputForAdd($input))->isEqualTo($result);

if (count($messages) > 0) {
$this->hasSessionMessages(ERROR, $messages);
}
}

/**
* @dataProvider inputProvider
*/
public function testPrepareInputForUpdate(array $input, /* array|false */ $result, array $messages = []): void
{
$this->variable($this->newTestedInstance()->prepareInputForAdd($input))->isEqualTo($result);

if (count($messages) > 0) {
$this->hasSessionMessages(ERROR, $messages);
}
}
}

0 comments on commit fc4cbb2

Please sign in to comment.