1<?php 2 3/* 4 * This file is part of Twig. 5 * 6 * (c) 2009 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 12/** 13 * Represents a security policy which need to be enforced when sandbox mode is enabled. 14 * 15 * @final 16 * 17 * @author Fabien Potencier <fabien@symfony.com> 18 */ 19class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterface 20{ 21 protected $allowedTags; 22 protected $allowedFilters; 23 protected $allowedMethods; 24 protected $allowedProperties; 25 protected $allowedFunctions; 26 27 public function __construct(array $allowedTags = array(), array $allowedFilters = array(), array $allowedMethods = array(), array $allowedProperties = array(), array $allowedFunctions = array()) 28 { 29 $this->allowedTags = $allowedTags; 30 $this->allowedFilters = $allowedFilters; 31 $this->setAllowedMethods($allowedMethods); 32 $this->allowedProperties = $allowedProperties; 33 $this->allowedFunctions = $allowedFunctions; 34 } 35 36 public function setAllowedTags(array $tags) 37 { 38 $this->allowedTags = $tags; 39 } 40 41 public function setAllowedFilters(array $filters) 42 { 43 $this->allowedFilters = $filters; 44 } 45 46 public function setAllowedMethods(array $methods) 47 { 48 $this->allowedMethods = array(); 49 foreach ($methods as $class => $m) { 50 $this->allowedMethods[$class] = array_map('strtolower', is_array($m) ? $m : array($m)); 51 } 52 } 53 54 public function setAllowedProperties(array $properties) 55 { 56 $this->allowedProperties = $properties; 57 } 58 59 public function setAllowedFunctions(array $functions) 60 { 61 $this->allowedFunctions = $functions; 62 } 63 64 public function checkSecurity($tags, $filters, $functions) 65 { 66 foreach ($tags as $tag) { 67 if (!in_array($tag, $this->allowedTags)) { 68 throw new Twig_Sandbox_SecurityNotAllowedTagError(sprintf('Tag "%s" is not allowed.', $tag), $tag); 69 } 70 } 71 72 foreach ($filters as $filter) { 73 if (!in_array($filter, $this->allowedFilters)) { 74 throw new Twig_Sandbox_SecurityNotAllowedFilterError(sprintf('Filter "%s" is not allowed.', $filter), $filter); 75 } 76 } 77 78 foreach ($functions as $function) { 79 if (!in_array($function, $this->allowedFunctions)) { 80 throw new Twig_Sandbox_SecurityNotAllowedFunctionError(sprintf('Function "%s" is not allowed.', $function), $function); 81 } 82 } 83 } 84 85 public function checkMethodAllowed($obj, $method) 86 { 87 if ($obj instanceof Twig_TemplateInterface || $obj instanceof Twig_Markup) { 88 return true; 89 } 90 91 $allowed = false; 92 $method = strtolower($method); 93 foreach ($this->allowedMethods as $class => $methods) { 94 if ($obj instanceof $class) { 95 $allowed = in_array($method, $methods); 96 97 break; 98 } 99 } 100 101 if (!$allowed) { 102 $class = get_class($obj); 103 throw new Twig_Sandbox_SecurityNotAllowedMethodError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, $class), $class, $method); 104 } 105 } 106 107 public function checkPropertyAllowed($obj, $property) 108 { 109 $allowed = false; 110 foreach ($this->allowedProperties as $class => $properties) { 111 if ($obj instanceof $class) { 112 $allowed = in_array($property, is_array($properties) ? $properties : array($properties)); 113 114 break; 115 } 116 } 117 118 if (!$allowed) { 119 $class = get_class($obj); 120 throw new Twig_Sandbox_SecurityNotAllowedPropertyError(sprintf('Calling "%s" property on a "%s" object is not allowed.', $property, $class), $class, $property); 121 } 122 } 123} 124