Skip to content

Commit

Permalink
Prevent new lines and variables in settings values
Browse files Browse the repository at this point in the history
  • Loading branch information
sedan07 committed Aug 27, 2021
1 parent 59f2e85 commit 6442976
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 18 deletions.
22 changes: 22 additions & 0 deletions app/Bus/Exceptions/Setting/InvalidSettingValueException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

/*
* This file is part of Cachet.
*
* (c) FiveAI Ltd
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace CachetHQ\Cachet\Bus\Exceptions\Setting;

use Exception;

/**
* This is the invalid setting value exception.
*/
class InvalidSettingValueException extends Exception implements SettingExceptionInterface
{
//
}
22 changes: 22 additions & 0 deletions app/Bus/Exceptions/Setting/SettingExceptionInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

/*
* This file is part of Cachet.
*
* (c) FiveAI Ltd
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace CachetHQ\Cachet\Bus\Exceptions\Setting;

use CachetHQ\Cachet\Bus\Exceptions\ExceptionInterface;

/**
* This is the setting exception interface.
*/
interface SettingExceptionInterface extends ExceptionInterface
{
//
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
namespace CachetHQ\Cachet\Bus\Handlers\Commands\System\Config;

use CachetHQ\Cachet\Bus\Commands\System\Config\UpdateConfigCommand;
use CachetHQ\Cachet\Bus\Exceptions\Setting\InvalidSettingValueException;
use Dotenv\Dotenv;
use Dotenv\Exception\InvalidPathException;
use Illuminate\Filesystem\Filesystem;

/**
* This is the update config command handler class.
Expand All @@ -22,6 +23,29 @@
*/
class UpdateConfigCommandHandler
{
/**
* @var string
*/
protected $dir;

/**
* @var string
*/
protected $file;

/**
* @var string
*/
protected $path;

public function __construct(Filesystem $filesystem)
{
$this->dir = app()->environmentPath();
$this->file = app()->environmentFile();
$this->path = "{$this->dir}/{$this->file}";
$this->filesystem = $filesystem;
}

/**
* Handle update config command handler instance.
*
Expand All @@ -34,6 +58,38 @@ public function handle(UpdateConfigCommand $command)
foreach ($command->values as $setting => $value) {
$this->writeEnv($setting, $value);
}

if (app()->configurationIsCached()) {
$this->filesystem->delete(app()->getCachedConfigPath());
}
}

/**
* Replicate phpdotenv's nested variable resolution to identify if a given
* value contains such sequences.
*
* @param string $value
*
* @return string
*/
protected function resolveNestedVariables($value)
{
if (strpos($value, '$') !== false) {
$value = preg_replace_callback(
'/\${([a-zA-Z0-9_.]+)}/',
function ($matchedPatterns) {
$nestedVariable = env($matchedPatterns[1]);
if ($nestedVariable === null) {
return $matchedPatterns[0];
} else {
return $nestedVariable;
}
},
$value
);
}

return $value;
}

/**
Expand All @@ -46,23 +102,23 @@ public function handle(UpdateConfigCommand $command)
*/
protected function writeEnv($key, $value)
{
$dir = app()->environmentPath();
$file = app()->environmentFile();
$path = "{$dir}/{$file}";

try {
(new Dotenv($dir, $file))->load();

$envKey = strtoupper($key);
$envValue = env($envKey) ?: 'null';

file_put_contents($path, str_replace(
"{$envKey}={$envValue}",
"{$envKey}={$value}",
file_get_contents($path)
));
} catch (InvalidPathException $e) {
throw $e;
if (strstr($key, "\n") !== false || strstr($value, "\n") !== false) {
throw new InvalidSettingValueException('New setting key or value contains new lines');
}

(new Dotenv($this->dir, $this->file))->safeLoad();

$envKey = strtoupper($key);
$envValue = env($envKey) ?: 'null';

if ($this->resolveNestedVariables($value) !== $value) {
throw new InvalidSettingValueException("New setting key $envKey contains a nested variable");
}

file_put_contents($this->path, str_replace(
"{$envKey}={$envValue}",
"{$envKey}={$value}",
file_get_contents($this->path)
));
}
}

0 comments on commit 6442976

Please sign in to comment.