Security fixes for v1.0.469

Introduces sandbox policy to block extendable methods allowing arbitrary code execution
This commit is contained in:
Samuel Georges 2020-09-04 13:02:01 +10:00
parent d49266ad90
commit 4c650bb775
3 changed files with 67 additions and 0 deletions

View File

@ -15,6 +15,7 @@ use SystemException;
use BackendAuth;
use Twig\Environment as TwigEnvironment;
use Twig\Cache\FilesystemCache as TwigCacheFilesystem;
use Twig\Extension\SandboxExtension;
use Cms\Twig\Loader as TwigLoader;
use Cms\Twig\DebugExtension;
use Cms\Twig\Extension as CmsTwigExtension;
@ -23,6 +24,7 @@ use System\Models\RequestLog;
use System\Helpers\View as ViewHelper;
use System\Classes\CombineAssets;
use System\Twig\Extension as SystemTwigExtension;
use System\Twig\SecurityPolicy;
use October\Rain\Exception\AjaxException;
use October\Rain\Exception\ValidationException;
use October\Rain\Parse\Bracket as TextParser;
@ -608,6 +610,7 @@ class Controller
$this->twig = new TwigEnvironment($this->loader, $options);
$this->twig->addExtension(new CmsTwigExtension($this));
$this->twig->addExtension(new SystemTwigExtension);
$this->twig->addExtension(new SandboxExtension(new SecurityPolicy, true));
if ($isDebugMode) {
$this->twig->addExtension(new DebugExtension($this));

View File

@ -19,6 +19,7 @@ use System\Classes\UpdateManager;
use System\Twig\Engine as TwigEngine;
use System\Twig\Loader as TwigLoader;
use System\Twig\Extension as TwigExtension;
use System\Twig\SecurityPolicy as TwigSecurityPolicy;
use System\Models\EventLog;
use System\Models\MailSetting;
use System\Classes\CombineAssets;
@ -27,6 +28,7 @@ use October\Rain\Support\ModuleServiceProvider;
use October\Rain\Router\Helper as RouterHelper;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Facades\Schema;
use Twig\Extension\SandboxExtension;
class ServiceProvider extends ModuleServiceProvider
{
@ -297,6 +299,7 @@ class ServiceProvider extends ModuleServiceProvider
App::singleton('twig.environment', function ($app) {
$twig = new TwigEnvironment(new TwigLoader, ['auto_reload' => true]);
$twig->addExtension(new TwigExtension);
$twig->addExtension(new SandboxExtension(new TwigSecurityPolicy, true));
return $twig;
});

View File

@ -0,0 +1,61 @@
<?php namespace System\Twig;
use Twig\Markup;
use Twig\Template;
use Twig\Sandbox\SecurityPolicyInterface;
use Twig\Sandbox\SecurityNotAllowedMethodError;
use Twig\Sandbox\SecurityNotAllowedPropertyError;
/**
* SecurityPolicy globally blocks accessibility of certain methods and properties.
*
* @package october\system
* @author Alexey Bobkov, Samuel Georges
*/
final class SecurityPolicy implements SecurityPolicyInterface
{
protected $blockedProperties = [];
protected $blockedMethods = [
'addDynamicMethod',
'addDynamicProperty'
];
public function __construct()
{
$this->setBlockedMethods($this->blockedMethods);
}
public function setBlockedMethods(array $methods)
{
foreach ($this->blockedMethods as $i => $m) {
$this->blockedMethods[$i] = strtr($m, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
}
}
public function checkSecurity($tags, $filters, $functions)
{
}
public function checkMethodAllowed($obj, $method)
{
if ($obj instanceof Template || $obj instanceof Markup) {
return;
}
$blockedMethod = strtr($method, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
if (in_array($blockedMethod, $this->blockedMethods)) {
$class = get_class($obj);
throw new SecurityNotAllowedMethodError(sprintf('Calling "%s" method on a "%s" object is blocked.', $method, $class), $class, $method);
}
}
public function checkPropertyAllowed($obj, $property)
{
if (in_array($property, $this->blockedProperties)) {
$class = get_class($obj);
throw new SecurityNotAllowedPropertyError(sprintf('Calling "%s" property on a "%s" object is blocked.', $property, $class), $class, $property);
}
}
}