2010-12-16 38 views
12

我可以采用某种配置模板工具包,以便:逃生HTML

[% foo %] 

做什么,你现在需要说:

[% foo | html %] 

就是逃避HTML中foo?和做其他的事情,比如:

[% foo | noHtml %] 

如果我想逃?

回答

3

我想你可以通过扩展Template::Stash来创建自己的存储空间,这样它就可以通过默认的转义变量。

这就是说我认为这不是一个好主意。更好地坚持默认行为,避免自定义修改,因为它们当然令人困惑。

+1

自定义Template :: Stash可能不够好。'[%x%]'和'[%y = x%]'都会调用存储的'get()'方法来查找'x',但只有第一个产生输出,存储可能无法告诉“获取和打印”和“获取”之间的差异,所以你最终会得到很多双/三/ ... HTML编码的东西。可能最好不要打扰。 – 2010-12-17 01:56:49

+0

TT的设计哲学是默认允许跨站点脚本攻击,并且只允许通过大量的牦牛剃须来保证安全。 – geira 2013-10-07 11:18:10

+0

是的,那太适合TT理念了。 – jeje 2014-02-12 15:54:21

1

我最近在这个问题上花了一些时间。这是我的解决方案的大纲。

我创建了一个名为HtmlSafe的新类,它包含可安全写入WWW客户端而没有安全漏洞的字符串。这个想法是,生成HTML标签的函数返回HtmlSafe对象,并且开箱即用的变量不是HtmlSafe。不管产生什么HtmlSafe也为所讨论的字符串的安全性提供保证。使用HTML安全字符串连接非HTML安全字符串会导致非HTML安全字符串通过CGI :: escapeHTML转义,然后使用HTML安全字符串加入。将HtmlSafe的另一个实例连接到HtmlSafe只是在不逃避的情况下加入有问题的字符串。我结束了使用超载,所以我可以重新定义。 HtmlSafe类的运算符。

有了这些东西,我给了一个$模板 - >进程()函数$输出变量,实际上是调用与HtmlSafe的串联,像这样子:

my $output = HtmlSafe->new(""); 
$template->process($vars, sub { $output .= $_[0]; }); 
return $output->unwrap(); # remove HtmlSafe and return underlying string 

我们几乎准备就绪与HtmlSafe TT2。我必须做的最大改变是改变Template :: Directive中的textblock()函数,Template :: Parser使用它来生成任何试图发出的文本块的HtmlSafe实例。这些似乎与解析模板的文本节点对应,所以只是做

package MyDirective; 
use base "Template::Directive"; 
sub textblock { my $self = shift; return "$Template::Directive::OUTPUT HtmlSafe->new(" . $self->text(@_) . ")"; } 

,我给了解析器,像这样:

my $parser = Template::Parser->new({ 
    FACTORY => "MyDirective", 
}); 

除了这个,我定义的“无”过滤器对于定义为HtmlSafe的简单包装的TT2,所以如果必须的话,您可以输出原始HTML。这避免了逃脱的事情。默认的“html”过滤器是无操作的,因为无论如何,连接到HtmlSafe的任何东西都会被转义。