Restrictive ("Secure") Compiler for Savant
This page is to track issues related to the new "secure" compiler for Savant. A number of people (notably and most recently RevJim) have opined that Savant needs a decent secure compiler so that untrusted users can be allowed to edit templates. I agree.
Note: The compiler is not a required element. The normal use of Savant remains; that is, PHP itself is the template markup. The only time you really need to compile a template is when you have anonymous or otherwise possibly mailicious users, and this compiler exists to support that relatively rare case.
So the idea now is to replace the existing "basic" compiler with a more-secure version; you can view the source code here. Note that it depends on Josh Eichorn's excellent PHPCodeAnalyzer script, which itself depends on the tokenizer function in PHP 4.3.0 and later.
I don't know if I like calling the new compiler "secure" or not, but it sure is restrictive. Here are the built-in restrictions and features:
- The markup language is PHP in most cases, just surrounded in non-PHP tags
- Prefix and suffix tags default to "{" and "}", but are user-definable.
- No <?php ... ?> or <? ... ?> tags allowed
- Simple variable echoing via {$var}
- Comments via {* ... *}
- Control structures are regular PHP ( {if (...):}, {else}, {foreach (...):}, etc)
- No support for switch/case, but break and continue are allowed
- Plugins supported via {['pluginName', 'arg1', $arg2, ... ]}
- Certain language constructs are disallowed: eval, global, include[_once], require[_once], parent, self
- The only way to include other templates is via the {tpl} tag
- If the Savant $_restrict flag is on, template requests are restricted to specific allowed paths
- Access to superglobals ($GLOBALS, $_GET, etc) is disallowed
- Access to private $this properties is disallowed
- Variable-variables and variable-functions are disallowed
- Only whitelisted functions are allowed (the whitelist is user-definable)
- Only whitelisted static method calls are allowed (the whitelist is user-definable)
- Use of $this by itself is disallowed; it must be followed by -> (e.g., "$this" generates an error, but "$this_thing" and "$this->property" are allowed)
I think that's it. If the compile generates errors, the compiled script is not saved and the compiler returns a list of restriction violations with line numbers (the number correspond to both the source template and the compiled template becuase the markup language is very close to native PHP).
Comments? Questions? Have I forgotten to take something into account? It's only been a week, so I am sure to have missed some form of sneakiness.