注意:我正在使用Zend Framework,但我认为大部分内容都适用于PHP编码.
我正在尝试选择一种编写视图脚本的策略,可能需要借助模板引擎.动机:清晰度和安全性.我对编写.phtml脚本感到不满意.这种语法非常冗长,可以完成最常用的操作 - 输出变量:
escape($this->myVariable); ?>
除了代码冗长之外,恕我直言,模板作者每次他/她想要输出变量时都不应该记住(并且费心)写一个转义调用.忘记呼叫几乎肯定会导致XSS漏洞.
我有两个可能的解决方案来解决这个问题
解决方案1:具有自动转义的模板引擎
我认为至少Smarty可以选择在输出变量时自动转义html实体.有针对Smarty的观点,但可能至少其中一些在即将到来的3.0中得到解决 - 我还没有检查过.
PHPTAL等基于XML的模板引擎默认也会转义任何数据.不过,对于初学者来说,它们看起来可能很奇怪.也许还值得尝试?
解决方案2:转义模型中的数据
当然,另一种选择是逃避模型中已经存在的所需数据(甚至控制器?).模型应该已经知道每个字段的内容类型(主要是纯文本或HTML文本),因此在那里转义数据是合乎逻辑的.该视图可以将所有数据视为安全的HTML.这将允许例如.将字段的数据类型从纯文本更改为HTML而不触及视图脚本 - 只需更改模型即可.
但话说回来,它并不像MVC那样好.此外,这种方法也存在问题:
有时视图只希望打印前n个字符,我们不希望最终截断数据foo & bar
为foo &am
(最早逃脱它为foo & bar
)
也许视图想要在查询字符串中构造一个带有varName = $ varName的URL - 再次,在模型中已经转义的内容会很糟糕.
(这些问题可以通过提供两个版本的数据来解决,或者在模板中进行转换.对我来说似乎不好.)
想法?我错过了什么吗?您认为"最佳实践"是什么?
PS.这篇文章是关于发现了可包含任何用户提供的明文数据的通用解决方案<
或>
或任何其他字符.因此,在将数据保存到数据库之前过滤数据不是解决方案.
更新:
感谢所有评论到目前为止.我做了一些更多的研究,接下来将评估Twig和可能的Open Power Template.两者看起来都很有趣:Twig看起来很简单,但项目很年轻.在XML方面,OPT的语法看起来比PHPTAL好一点.Twig和OPT都有很好的记录.
尽快过滤.您应该确保所有文本输入都是正确的UTF-8,以使您的文本操作功能可以预测.
但是不要试图过滤掉"危险"的角色或碎片!这不起作用.仅修复或拒绝输入上的错误数据.没有什么不正确的<
或'
字符.
逃避尽可能晚.在SQL查询函数中添加SQL转义(或者更好 - 使用预处理语句).HTML模板中的HTML转义.电子邮件生成功能中的Quoted-Printable-escape,运行CLI命令时的shell-escape等.
不要让转义的数据遍布你的应用程序,因为较长的转义的数据的生命,更大的机会,你会与转义数据混合起来或破坏处理过程中逃跑.