Chris@0: TRUE. Chris@16: * Chris@16: * @var array Chris@0: */ Chris@16: protected $whitelisted_methods; Chris@0: Chris@0: /** Chris@0: * An array of whitelisted method prefixes -- any method starting with one of Chris@0: * these prefixes will be allowed. Chris@16: * Chris@16: * @var array Chris@0: */ Chris@16: protected $whitelisted_prefixes; Chris@0: Chris@0: /** Chris@0: * An array of class names for which any method calls are allowed. Chris@16: * Chris@16: * @var array Chris@0: */ Chris@16: protected $whitelisted_classes; Chris@0: Chris@0: /** Chris@0: * Constructs a new TwigSandboxPolicy object. Chris@0: */ Chris@0: public function __construct() { Chris@0: // Allow settings.php to override our default whitelisted classes, methods, Chris@0: // and prefixes. Chris@0: $whitelisted_classes = Settings::get('twig_sandbox_whitelisted_classes', [ Chris@0: // Allow any operations on the Attribute object as it is intended to be Chris@0: // changed from a Twig template, for example calling addClass(). Chris@0: 'Drupal\Core\Template\Attribute', Chris@0: ]); Chris@0: // Flip the arrays so we can check using isset(). Chris@0: $this->whitelisted_classes = array_flip($whitelisted_classes); Chris@0: Chris@0: $whitelisted_methods = Settings::get('twig_sandbox_whitelisted_methods', [ Chris@0: // Only allow idempotent methods. Chris@0: 'id', Chris@0: 'label', Chris@0: 'bundle', Chris@0: 'get', Chris@0: '__toString', Chris@0: 'toString', Chris@0: ]); Chris@0: $this->whitelisted_methods = array_flip($whitelisted_methods); Chris@0: Chris@0: $this->whitelisted_prefixes = Settings::get('twig_sandbox_whitelisted_prefixes', [ Chris@0: 'get', Chris@0: 'has', Chris@0: 'is', Chris@0: ]); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function checkSecurity($tags, $filters, $functions) {} Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function checkPropertyAllowed($obj, $property) {} Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function checkMethodAllowed($obj, $method) { Chris@0: foreach ($this->whitelisted_classes as $class => $key) { Chris@0: if ($obj instanceof $class) { Chris@0: return TRUE; Chris@0: } Chris@0: } Chris@0: Chris@0: // Return quickly for an exact match of the method name. Chris@0: if (isset($this->whitelisted_methods[$method])) { Chris@0: return TRUE; Chris@0: } Chris@0: Chris@0: // If the method name starts with a whitelisted prefix, allow it. Chris@0: // Note: strpos() is between 3x and 7x faster than preg_match in this case. Chris@0: foreach ($this->whitelisted_prefixes as $prefix) { Chris@0: if (strpos($method, $prefix) === 0) { Chris@0: return TRUE; Chris@0: } Chris@0: } Chris@0: Chris@0: throw new \Twig_Sandbox_SecurityError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, get_class($obj))); Chris@0: } Chris@0: Chris@0: }