1<?php 2 3/* 4 * This file is part of Twig. 5 * 6 * (c) Fabien Potencier 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Twig\Extension; 13 14use Twig\NodeVisitor\SandboxNodeVisitor; 15use Twig\Sandbox\SecurityNotAllowedMethodError; 16use Twig\Sandbox\SecurityNotAllowedPropertyError; 17use Twig\Sandbox\SecurityPolicyInterface; 18use Twig\Source; 19use Twig\TokenParser\SandboxTokenParser; 20 21final class SandboxExtension extends AbstractExtension 22{ 23 private $sandboxedGlobally; 24 private $sandboxed; 25 private $policy; 26 27 public function __construct(SecurityPolicyInterface $policy, $sandboxed = false) 28 { 29 $this->policy = $policy; 30 $this->sandboxedGlobally = $sandboxed; 31 } 32 33 public function getTokenParsers() 34 { 35 return [new SandboxTokenParser()]; 36 } 37 38 public function getNodeVisitors() 39 { 40 return [new SandboxNodeVisitor()]; 41 } 42 43 public function enableSandbox() 44 { 45 $this->sandboxed = true; 46 } 47 48 public function disableSandbox() 49 { 50 $this->sandboxed = false; 51 } 52 53 public function isSandboxed() 54 { 55 return $this->sandboxedGlobally || $this->sandboxed; 56 } 57 58 public function isSandboxedGlobally() 59 { 60 return $this->sandboxedGlobally; 61 } 62 63 public function setSecurityPolicy(SecurityPolicyInterface $policy) 64 { 65 $this->policy = $policy; 66 } 67 68 public function getSecurityPolicy() 69 { 70 return $this->policy; 71 } 72 73 public function checkSecurity($tags, $filters, $functions) 74 { 75 if ($this->isSandboxed()) { 76 $this->policy->checkSecurity($tags, $filters, $functions); 77 } 78 } 79 80 public function checkMethodAllowed($obj, $method, int $lineno = -1, Source $source = null) 81 { 82 if ($this->isSandboxed()) { 83 try { 84 $this->policy->checkMethodAllowed($obj, $method); 85 } catch (SecurityNotAllowedMethodError $e) { 86 $e->setSourceContext($source); 87 $e->setTemplateLine($lineno); 88 89 throw $e; 90 } 91 } 92 } 93 94 public function checkPropertyAllowed($obj, $property, int $lineno = -1, Source $source = null) 95 { 96 if ($this->isSandboxed()) { 97 try { 98 $this->policy->checkPropertyAllowed($obj, $property); 99 } catch (SecurityNotAllowedPropertyError $e) { 100 $e->setSourceContext($source); 101 $e->setTemplateLine($lineno); 102 103 throw $e; 104 } 105 } 106 } 107 108 public function ensureToStringAllowed($obj, int $lineno = -1, Source $source = null) 109 { 110 if ($this->isSandboxed() && \is_object($obj) && method_exists($obj, '__toString')) { 111 try { 112 $this->policy->checkMethodAllowed($obj, '__toString'); 113 } catch (SecurityNotAllowedMethodError $e) { 114 $e->setSourceContext($source); 115 $e->setTemplateLine($lineno); 116 117 throw $e; 118 } 119 } 120 121 return $obj; 122 } 123} 124 125class_alias('Twig\Extension\SandboxExtension', 'Twig_Extension_Sandbox'); 126