|
Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon. |
|
View previous topic :: View next topic |
Author |
Message |
mohrt Administrator
Joined: 16 Apr 2003 Posts: 7368 Location: Lincoln Nebraska, USA
|
Posted: Wed Mar 02, 2011 5:19 pm Post subject: Auto-HTML-escaping variables and templates |
|
|
NOTE: Smarty 3.1 now has an automated html-escape mode. http://www.smarty.net/docs/en/variable.escape.html.tpl
It is easy to selectively HTML-escape template variables with the {$foo|escape} modifier. However, sometimes it is advantageous to have everything assigned to Smarty automatically HTML-escaped to reduce the risks of XSS (cross-site scripting) vulnerabilities.
Smarty currently does not do this out of the box, nor does it offer a flag to enable this, but it is quite trivial to implement with a variable filter. Here is how it is done:
First, somewhere in your code make a function to do the escapement:
Code: | function escFilter($content,$smarty) {
return htmlspecialchars($content,ENT_QUOTES,UTF-8);
} |
Now register the variable filter with Smarty:
Code: | $smarty->registerFilter('variable','escFilter'); |
Now any variable assigned to Smarty will be HTML escaped:
PHP:
Code: | $smarty->assign('foo','This is <some> content'); |
Template:
Output:
Code: | This is <some> content |
You can also selectively "unescape" variables by skipping the filter:
Template:
Code: | {$foo} {* this gets filtered *}
{$foo nofilter} {* this does not *} |
Output:
Code: | This is <some> content
This is <some> content |
To go one step further, lets say you would like to mark blocks of template content that also get HTML-escaped. You can do this with a block plugin:
First make a PHP function for the plugin:
Code: | function escPlugin($params,$content,$smarty,&$repeat) {
return htmlspecialchars($content,ENT_QUOTES,UTF-8);
} |
Now register the block plugin with Smarty:
Code: | $smarty->registerPlugin('block','escape','escPlugin'); |
And now you can use this in your templates:
Code: | {escape}
This is some text I want <> escaped.
{/escape}
This not <> escaped. |
Output:
Code: | This is some text I want <> escaped.
This not <> escaped. |
Be warned, block plugins act on the output of template variables inside the block. Therefore, variables inside the block are also escaped. If you have the escape filter on a variable and put it inside the escape block, it will get double escaped!
Template:
Code: | {$foo} {* escaped by filter *}
{escape}
This is <some> text to escape.
{$foo} {* double-escaped! *}
{$foo nofilter} {* still escaped by the block *}
{/escape} |
If you want *everything* escaped on the page you could implement an output filter in the same manner as above. This would probably not be a common case as most pages contain some legitimate HTML. So, I'll leave that as an exercise to the reader
And that should do it!
Last edited by mohrt on Thu Dec 01, 2011 5:51 pm; edited 1 time in total |
|
Back to top |
|
thelem Smarty n00b
Joined: 10 Apr 2011 Posts: 1
|
Posted: Sun Apr 10, 2011 10:27 am Post subject: |
|
|
Isn't this basically the same as PHP's Magic Quotes feature, which was generally agreed to be a bad idea and subsequently removed?
http://php.net/manual/en/security.magicquotes.php
Having said that, this does seem to be implemented at the correct layer which magic quotes wasn't (it applied the same escaping algorithm whether you were using the data in SQL, HTML or whatever) and having to explictly mark certain variables as allowing HTML (using nofilter) does seem a safer default. |
|
Back to top |
|
mohrt Administrator
Joined: 16 Apr 2003 Posts: 7368 Location: Lincoln Nebraska, USA
|
Posted: Sun Apr 10, 2011 3:06 pm Post subject: |
|
|
thelem wrote: | Isn't this basically the same as PHP's Magic Quotes feature, which was generally agreed to be a bad idea and subsequently removed?
http://php.net/manual/en/security.magicquotes.php
Having said that, this does seem to be implemented at the correct layer which magic quotes wasn't (it applied the same escaping algorithm whether you were using the data in SQL, HTML or whatever) and having to explictly mark certain variables as allowing HTML (using nofilter) does seem a safer default. |
Yes applying an escapement filter on the template layer is the correct implementation for its purpose. This isn't exactly like magic quotes either, it doesn't try to SQL escape. |
|
Back to top |
|
rodneyrehm Administrator
Joined: 30 Mar 2007 Posts: 674 Location: Germany, border to Switzerland
|
Posted: Sun Apr 10, 2011 3:30 pm Post subject: Re: Auto-HTML-escaping variables and templates |
|
|
mohrt wrote: | [...] Be warned, block plugins act on the output of template variables inside the block. Therefore, variables inside the block are also escaped. If you have the escape filter on a variable and put it inside the escape block, it will get double escaped! |
As of PHP 5.2.3 htmlspecialchars() features the $double_encode argument. If set to true, entities are not escaped again. Smarty (as of 3.1) already has an internal function to deal with a fallback for PHP < 5.2.3. This allows for
Code: | require_once SMARTY_DIR . 'plugins/shared.escape_special_chars.php';
$smarty->registerFilter('variable','smarty_function_escape_special_chars'); | and Code: | function escPlugin($params,$content,$smarty,&$repeat) {
return smarty_function_escape_special_chars($content);
}
$smarty->registerPlugin('block','escape','escPlugin'); |
|
|
Back to top |
|
Adi21 Smarty n00b
Joined: 15 Sep 2011 Posts: 1
|
Posted: Thu Sep 15, 2011 4:40 am Post subject: |
|
|
Autoescape is a very cool option. I would like to see it turned on by default, or at the very least let it be an (optional) argument to the constructor of the Dwoo main class, so I don't have to use a couple of lines of boiler plate code, each time a new Dwoo instance is created.
Escaping html-characters is something a lot of developers don't get right. In most cases, the strings you insert into a template, should be escaped. So I think it's a very sane choice the Django folks made, by making autoescape default and I think you would do well by following the same standard for Dwoo. Otherwise a very nice template engine.
-----------------------------------------
tools parts & accessories |
|
Back to top |
|
rodneyrehm Administrator
Joined: 30 Mar 2007 Posts: 674 Location: Germany, border to Switzerland
|
Posted: Thu Sep 15, 2011 7:01 am Post subject: |
|
|
Adi21 wrote: | Autoescape is a very cool option. I would like to see it turned on by default, or at the very least let it be an (optional) argument to the constructor of the Dwoo main class, so I don't have to use a couple of lines of boiler plate code, each time a new Dwoo instance is created. |
You know that this is the Smarty forum, not Dwoo, right?
Smarty 3.1 also sports a new flag $escape_html, which would run all your output through htmlspecialchars(). _________________ Twitter |
|
Back to top |
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|
|