Overview

Packages

  • CONTENIDO
  • Core
    • Authentication
    • Backend
    • Cache
    • CEC
    • Chain
    • ContentType
    • Database
    • Debug
    • Exception
    • Frontend
      • Search
      • URI
      • Util
    • GenericDB
      • Model
    • GUI
      • HTML
    • I18N
    • LayoutHandler
    • Log
    • Security
    • Session
    • Util
    • Validation
    • Versioning
    • XML
  • Module
    • ContentRssCreator
    • ContentSitemapHtml
    • ContentSitemapXml
    • ContentUserForum
    • NavigationTop
    • ScriptCookieDirective
  • mpAutoloaderClassMap
  • None
  • Plugin
    • ContentAllocation
    • CronjobOverview
    • FormAssistant
    • FrontendLogic
    • FrontendUsers
    • Linkchecker
    • ModRewrite
    • Newsletter
    • Repository
      • FrontendNavigation
      • KeywordDensity
    • SearchSolr
    • SmartyWrapper
    • UrlShortener
    • UserForum
    • Workflow
  • PluginManager
  • Setup
    • Form
    • GUI
    • Helper
      • Environment
      • Filesystem
      • MySQL
      • PHP
    • UpgradeJob
  • Smarty
    • Cacher
    • Compiler
    • Config
    • Debug
    • PluginsBlock
    • PluginsFilter
    • PluginsFunction
    • PluginsInternal
    • PluginsModifier
    • PluginsModifierCompiler
    • PluginsShared
    • Security
    • Template
    • TemplateResources
  • Swift
    • ByteStream
    • CharacterStream
    • Encoder
    • Events
    • KeyCache
    • Mailer
    • Mime
    • Plugins
    • Transport

Classes

  • Swift_FailoverTransport
  • Swift_LoadBalancedTransport
  • Swift_MailTransport
  • Swift_Plugins_Loggers_ArrayLogger
  • Swift_Plugins_Loggers_EchoLogger
  • Swift_SendmailTransport
  • Swift_SmtpTransport
  • Swift_Transport_AbstractSmtpTransport
  • Swift_Transport_Esmtp_Auth_CramMd5Authenticator
  • Swift_Transport_Esmtp_Auth_LoginAuthenticator
  • Swift_Transport_Esmtp_Auth_PlainAuthenticator
  • Swift_Transport_Esmtp_AuthHandler
  • Swift_Transport_EsmtpTransport
  • Swift_Transport_FailoverTransport
  • Swift_Transport_LoadBalancedTransport
  • Swift_Transport_MailTransport
  • Swift_Transport_SendmailTransport
  • Swift_Transport_SimpleMailInvoker
  • Swift_Transport_StreamBuffer

Interfaces

  • Swift_Plugins_Logger
  • Swift_Plugins_Pop_Pop3Exception
  • Swift_Transport
  • Swift_Transport_Esmtp_Authenticator
  • Swift_Transport_EsmtpHandler
  • Swift_Transport_IoBuffer
  • Swift_Transport_MailInvoker
  • Swift_Transport_SmtpAgent
  • Swift_TransportException
  • Overview
  • Package
  • Function
  • Todo
  • Download
  1: <?php
  2: /**
  3:  * Smarty plugin
  4:  *
  5:  * @package    Smarty
  6:  * @subpackage Security
  7:  * @author     Uwe Tews
  8:  */
  9: 
 10: /*
 11:  * FIXME: Smarty_Security API
 12:  *      - getter and setter instead of public properties would allow cultivating an internal cache properly
 13:  *      - current implementation of isTrustedResourceDir() assumes that Smarty::$template_dir and Smarty::$config_dir are immutable
 14:  *        the cache is killed every time either of the variables change. That means that two distinct Smarty objects with differing
 15:  *        $template_dir or $config_dir should NOT share the same Smarty_Security instance,
 16:  *        as this would lead to (severe) performance penalty! how should this be handled?
 17:  */
 18: 
 19: /**
 20:  * This class does contain the security settings
 21:  */
 22: class Smarty_Security
 23: {
 24:     /**
 25:      * This determines how Smarty handles "<?php ... ?>" tags in templates.
 26:      * possible values:
 27:      * <ul>
 28:      *   <li>Smarty::PHP_PASSTHRU -> echo PHP tags as they are</li>
 29:      *   <li>Smarty::PHP_QUOTE    -> escape tags as entities</li>
 30:      *   <li>Smarty::PHP_REMOVE   -> remove php tags</li>
 31:      *   <li>Smarty::PHP_ALLOW    -> execute php tags</li>
 32:      * </ul>
 33:      *
 34:      * @var integer
 35:      */
 36:     public $php_handling = Smarty::PHP_PASSTHRU;
 37:     /**
 38:      * This is the list of template directories that are considered secure.
 39:      * $template_dir is in this list implicitly.
 40:      *
 41:      * @var array
 42:      */
 43:     public $secure_dir = array();
 44:     /**
 45:      * This is an array of directories where trusted php scripts reside.
 46:      * {@link $security} is disabled during their inclusion/execution.
 47:      *
 48:      * @var array
 49:      */
 50:     public $trusted_dir = array();
 51:     /**
 52:      * List of regular expressions (PCRE) that include trusted URIs
 53:      *
 54:      * @var array
 55:      */
 56:     public $trusted_uri = array();
 57:     /**
 58:      * This is an array of trusted static classes.
 59:      * If empty access to all static classes is allowed.
 60:      * If set to 'none' none is allowed.
 61:      *
 62:      * @var array
 63:      */
 64:     public $static_classes = array();
 65:     /**
 66:      * This is an array of trusted PHP functions.
 67:      * If empty all functions are allowed.
 68:      * To disable all PHP functions set $php_functions = null.
 69:      *
 70:      * @var array
 71:      */
 72:     public $php_functions = array(
 73:         'isset', 'empty',
 74:         'count', 'sizeof',
 75:         'in_array', 'is_array',
 76:         'time',
 77:         'nl2br',
 78:     );
 79:     /**
 80:      * This is an array of trusted PHP modifiers.
 81:      * If empty all modifiers are allowed.
 82:      * To disable all modifier set $php_modifiers = null.
 83:      *
 84:      * @var array
 85:      */
 86:     public $php_modifiers = array(
 87:         'escape',
 88:         'count'
 89:     );
 90:     /**
 91:      * This is an array of allowed tags.
 92:      * If empty no restriction by allowed_tags.
 93:      *
 94:      * @var array
 95:      */
 96:     public $allowed_tags = array();
 97:     /**
 98:      * This is an array of disabled tags.
 99:      * If empty no restriction by disabled_tags.
100:      *
101:      * @var array
102:      */
103:     public $disabled_tags = array();
104:     /**
105:      * This is an array of allowed modifier plugins.
106:      * If empty no restriction by allowed_modifiers.
107:      *
108:      * @var array
109:      */
110:     public $allowed_modifiers = array();
111:     /**
112:      * This is an array of disabled modifier plugins.
113:      * If empty no restriction by disabled_modifiers.
114:      *
115:      * @var array
116:      */
117:     public $disabled_modifiers = array();
118:     /**
119:      * This is an array of trusted streams.
120:      * If empty all streams are allowed.
121:      * To disable all streams set $streams = null.
122:      *
123:      * @var array
124:      */
125:     public $streams = array('file');
126:     /**
127:      * + flag if constants can be accessed from template
128:      *
129:      * @var boolean
130:      */
131:     public $allow_constants = true;
132:     /**
133:      * + flag if super globals can be accessed from template
134:      *
135:      * @var boolean
136:      */
137:     public $allow_super_globals = true;
138: 
139:     /**
140:      * Cache for $resource_dir lookup
141:      *
142:      * @var array
143:      */
144:     protected $_resource_dir = null;
145:     /**
146:      * Cache for $template_dir lookup
147:      *
148:      * @var array
149:      */
150:     protected $_template_dir = null;
151:     /**
152:      * Cache for $config_dir lookup
153:      *
154:      * @var array
155:      */
156:     protected $_config_dir = null;
157:     /**
158:      * Cache for $secure_dir lookup
159:      *
160:      * @var array
161:      */
162:     protected $_secure_dir = null;
163:     /**
164:      * Cache for $php_resource_dir lookup
165:      *
166:      * @var array
167:      */
168:     protected $_php_resource_dir = null;
169:     /**
170:      * Cache for $trusted_dir lookup
171:      *
172:      * @var array
173:      */
174:     protected $_trusted_dir = null;
175: 
176:     /**
177:      * @param Smarty $smarty
178:      */
179:     public function __construct($smarty)
180:     {
181:         $this->smarty = $smarty;
182:     }
183: 
184:     /**
185:      * Check if PHP function is trusted.
186:      *
187:      * @param  string $function_name
188:      * @param  object $compiler compiler object
189:      *
190:      * @return boolean                 true if function is trusted
191:      * @throws SmartyCompilerException if php function is not trusted
192:      */
193:     public function isTrustedPhpFunction($function_name, $compiler)
194:     {
195:         if (isset($this->php_functions) && (empty($this->php_functions) || in_array($function_name, $this->php_functions))) {
196:             return true;
197:         }
198: 
199:         $compiler->trigger_template_error("PHP function '{$function_name}' not allowed by security setting");
200: 
201:         return false; // should not, but who knows what happens to the compiler in the future?
202:     }
203: 
204:     /**
205:      * Check if static class is trusted.
206:      *
207:      * @param  string $class_name
208:      * @param  object $compiler compiler object
209:      *
210:      * @return boolean                 true if class is trusted
211:      * @throws SmartyCompilerException if static class is not trusted
212:      */
213:     public function isTrustedStaticClass($class_name, $compiler)
214:     {
215:         if (isset($this->static_classes) && (empty($this->static_classes) || in_array($class_name, $this->static_classes))) {
216:             return true;
217:         }
218: 
219:         $compiler->trigger_template_error("access to static class '{$class_name}' not allowed by security setting");
220: 
221:         return false; // should not, but who knows what happens to the compiler in the future?
222:     }
223: 
224:     /**
225:      * Check if PHP modifier is trusted.
226:      *
227:      * @param  string $modifier_name
228:      * @param  object $compiler compiler object
229:      *
230:      * @return boolean                 true if modifier is trusted
231:      * @throws SmartyCompilerException if modifier is not trusted
232:      */
233:     public function isTrustedPhpModifier($modifier_name, $compiler)
234:     {
235:         if (isset($this->php_modifiers) && (empty($this->php_modifiers) || in_array($modifier_name, $this->php_modifiers))) {
236:             return true;
237:         }
238: 
239:         $compiler->trigger_template_error("modifier '{$modifier_name}' not allowed by security setting");
240: 
241:         return false; // should not, but who knows what happens to the compiler in the future?
242:     }
243: 
244:     /**
245:      * Check if tag is trusted.
246:      *
247:      * @param  string $tag_name
248:      * @param  object $compiler compiler object
249:      *
250:      * @return boolean                 true if tag is trusted
251:      * @throws SmartyCompilerException if modifier is not trusted
252:      */
253:     public function isTrustedTag($tag_name, $compiler)
254:     {
255:         // check for internal always required tags
256:         if (in_array($tag_name, array('assign', 'call', 'private_filter', 'private_block_plugin', 'private_function_plugin', 'private_object_block_function',
257:                                       'private_object_function', 'private_registered_function', 'private_registered_block', 'private_special_variable', 'private_print_expression', 'private_modifier'))
258:         ) {
259:             return true;
260:         }
261:         // check security settings
262:         if (empty($this->allowed_tags)) {
263:             if (empty($this->disabled_tags) || !in_array($tag_name, $this->disabled_tags)) {
264:                 return true;
265:             } else {
266:                 $compiler->trigger_template_error("tag '{$tag_name}' disabled by security setting", $compiler->lex->taglineno);
267:             }
268:         } elseif (in_array($tag_name, $this->allowed_tags) && !in_array($tag_name, $this->disabled_tags)) {
269:             return true;
270:         } else {
271:             $compiler->trigger_template_error("tag '{$tag_name}' not allowed by security setting", $compiler->lex->taglineno);
272:         }
273: 
274:         return false; // should not, but who knows what happens to the compiler in the future?
275:     }
276: 
277:     /**
278:      * Check if modifier plugin is trusted.
279:      *
280:      * @param  string $modifier_name
281:      * @param  object $compiler compiler object
282:      *
283:      * @return boolean                 true if tag is trusted
284:      * @throws SmartyCompilerException if modifier is not trusted
285:      */
286:     public function isTrustedModifier($modifier_name, $compiler)
287:     {
288:         // check for internal always allowed modifier
289:         if (in_array($modifier_name, array('default'))) {
290:             return true;
291:         }
292:         // check security settings
293:         if (empty($this->allowed_modifiers)) {
294:             if (empty($this->disabled_modifiers) || !in_array($modifier_name, $this->disabled_modifiers)) {
295:                 return true;
296:             } else {
297:                 $compiler->trigger_template_error("modifier '{$modifier_name}' disabled by security setting", $compiler->lex->taglineno);
298:             }
299:         } elseif (in_array($modifier_name, $this->allowed_modifiers) && !in_array($modifier_name, $this->disabled_modifiers)) {
300:             return true;
301:         } else {
302:             $compiler->trigger_template_error("modifier '{$modifier_name}' not allowed by security setting", $compiler->lex->taglineno);
303:         }
304: 
305:         return false; // should not, but who knows what happens to the compiler in the future?
306:     }
307: 
308:     /**
309:      * Check if stream is trusted.
310:      *
311:      * @param  string $stream_name
312:      *
313:      * @return boolean         true if stream is trusted
314:      * @throws SmartyException if stream is not trusted
315:      */
316:     public function isTrustedStream($stream_name)
317:     {
318:         if (isset($this->streams) && (empty($this->streams) || in_array($stream_name, $this->streams))) {
319:             return true;
320:         }
321: 
322:         throw new SmartyException("stream '{$stream_name}' not allowed by security setting");
323:     }
324: 
325:     /**
326:      * Check if directory of file resource is trusted.
327:      *
328:      * @param  string $filepath
329:      *
330:      * @return boolean         true if directory is trusted
331:      * @throws SmartyException if directory is not trusted
332:      */
333:     public function isTrustedResourceDir($filepath)
334:     {
335:         $_template = false;
336:         $_config = false;
337:         $_secure = false;
338: 
339:         $_template_dir = $this->smarty->getTemplateDir();
340:         $_config_dir = $this->smarty->getConfigDir();
341: 
342:         // check if index is outdated
343:         if ((!$this->_template_dir || $this->_template_dir !== $_template_dir)
344:             || (!$this->_config_dir || $this->_config_dir !== $_config_dir)
345:             || (!empty($this->secure_dir) && (!$this->_secure_dir || $this->_secure_dir !== $this->secure_dir))
346:         ) {
347:             $this->_resource_dir = array();
348:             $_template = true;
349:             $_config = true;
350:             $_secure = !empty($this->secure_dir);
351:         }
352: 
353:         // rebuild template dir index
354:         if ($_template) {
355:             $this->_template_dir = $_template_dir;
356:             foreach ($_template_dir as $directory) {
357:                 $directory = realpath($directory);
358:                 $this->_resource_dir[$directory] = true;
359:             }
360:         }
361: 
362:         // rebuild config dir index
363:         if ($_config) {
364:             $this->_config_dir = $_config_dir;
365:             foreach ($_config_dir as $directory) {
366:                 $directory = realpath($directory);
367:                 $this->_resource_dir[$directory] = true;
368:             }
369:         }
370: 
371:         // rebuild secure dir index
372:         if ($_secure) {
373:             $this->_secure_dir = $this->secure_dir;
374:             foreach ((array) $this->secure_dir as $directory) {
375:                 $directory = realpath($directory);
376:                 $this->_resource_dir[$directory] = true;
377:             }
378:         }
379: 
380:         $_filepath = realpath($filepath);
381:         $directory = dirname($_filepath);
382:         $_directory = array();
383:         while (true) {
384:             // remember the directory to add it to _resource_dir in case we're successful
385:             $_directory[$directory] = true;
386:             // test if the directory is trusted
387:             if (isset($this->_resource_dir[$directory])) {
388:                 // merge sub directories of current $directory into _resource_dir to speed up subsequent lookup
389:                 $this->_resource_dir = array_merge($this->_resource_dir, $_directory);
390: 
391:                 return true;
392:             }
393:             // abort if we've reached root
394:             if (($pos = strrpos($directory, DS)) === false || !isset($directory[1])) {
395:                 break;
396:             }
397:             // bubble up one level
398:             $directory = substr($directory, 0, $pos);
399:         }
400: 
401:         // give up
402:         throw new SmartyException("directory '{$_filepath}' not allowed by security setting");
403:     }
404: 
405:     /**
406:      * Check if URI (e.g. {fetch} or {html_image}) is trusted
407:      * To simplify things, isTrustedUri() resolves all input to "{$PROTOCOL}://{$HOSTNAME}".
408:      * So "http://username:password@hello.world.example.org:8080/some-path?some=query-string"
409:      * is reduced to "http://hello.world.example.org" prior to applying the patters from {@link $trusted_uri}.
410:      *
411:      * @param  string $uri
412:      *
413:      * @return boolean         true if URI is trusted
414:      * @throws SmartyException if URI is not trusted
415:      * @uses $trusted_uri for list of patterns to match against $uri
416:      */
417:     public function isTrustedUri($uri)
418:     {
419:         $_uri = parse_url($uri);
420:         if (!empty($_uri['scheme']) && !empty($_uri['host'])) {
421:             $_uri = $_uri['scheme'] . '://' . $_uri['host'];
422:             foreach ($this->trusted_uri as $pattern) {
423:                 if (preg_match($pattern, $_uri)) {
424:                     return true;
425:                 }
426:             }
427:         }
428: 
429:         throw new SmartyException("URI '{$uri}' not allowed by security setting");
430:     }
431: 
432:     /**
433:      * Check if directory of file resource is trusted.
434:      *
435:      * @param  string $filepath
436:      *
437:      * @return boolean         true if directory is trusted
438:      * @throws SmartyException if PHP directory is not trusted
439:      */
440:     public function isTrustedPHPDir($filepath)
441:     {
442:         if (empty($this->trusted_dir)) {
443:             throw new SmartyException("directory '{$filepath}' not allowed by security setting (no trusted_dir specified)");
444:         }
445: 
446:         // check if index is outdated
447:         if (!$this->_trusted_dir || $this->_trusted_dir !== $this->trusted_dir) {
448:             $this->_php_resource_dir = array();
449: 
450:             $this->_trusted_dir = $this->trusted_dir;
451:             foreach ((array) $this->trusted_dir as $directory) {
452:                 $directory = realpath($directory);
453:                 $this->_php_resource_dir[$directory] = true;
454:             }
455:         }
456: 
457:         $_filepath = realpath($filepath);
458:         $directory = dirname($_filepath);
459:         $_directory = array();
460:         while (true) {
461:             // remember the directory to add it to _resource_dir in case we're successful
462:             $_directory[] = $directory;
463:             // test if the directory is trusted
464:             if (isset($this->_php_resource_dir[$directory])) {
465:                 // merge sub directories of current $directory into _resource_dir to speed up subsequent lookup
466:                 $this->_php_resource_dir = array_merge($this->_php_resource_dir, $_directory);
467: 
468:                 return true;
469:             }
470:             // abort if we've reached root
471:             if (($pos = strrpos($directory, DS)) === false || !isset($directory[2])) {
472:                 break;
473:             }
474:             // bubble up one level
475:             $directory = substr($directory, 0, $pos);
476:         }
477: 
478:         throw new SmartyException("directory '{$_filepath}' not allowed by security setting");
479:     }
480: }
481: 
CMS CONTENIDO 4.9.7 API documentation generated by ApiGen