我们使用jspx作为模板引擎。我们有数十个屏幕,其中包含数百个el表达式,例如$ {user.firstName}或“ $ {mail.subject}”
并且所有这些HTML代码默认情况下都不会转义。如果在字段中带有
1)
默认情况下,有没有一种方法可以逃脱?
我知道的唯一方法是破解JSP编译器(例如Tomcat的jasper)。但这不是走的路。
2)
为什么有人可能需要el中未转义的HTML?将HTML存储在模板之外(例如在数据库中)不是一个好习惯。
3)我确信模板引擎应该自动处理它(就像在XSLT中所做的那样),用户为什么要关心它?
手动转义(fn:escapeXml)的气味类似于SQL手动转义(用于代替JDBC setParam):样板代码和sql注入的好地方(本例中为跨站点脚本)。
最佳答案
1)默认情况下有办法逃脱吗?
不在老式的JSP中。但是,其后继Facelets默认情况下会对其进行转义。禁用转义的唯一方法是使用<h:outputText value="#{bean.foo}" escape="false" />
而不是#{bean.foo}
。
2)为什么有人可能需要在el中使用未转义的HTML?将HTML存储在模板之外(例如在数据库中)不是一个好习惯。
但是,存储sanitized HTML的工作比通常要多。例如。允许一小部分无害的HTML标记(例如<p>
,<b>
,<i>
),并且已经从中删除了on*
属性。
3)我确信模板引擎应该自动处理它(就像在XSLT中所做的那样),用户为什么要关心它?手动转义(fn:escapeXml)的气味类似于SQL手动转义(用于代替JDBC setParam):样板代码和sql注入的好地方(本例中为跨站点脚本)。
JSP是一种古老的视图技术。它并不是真正的灵活模板引擎。
通常可以通过仅使用PreparedStatement
而不是Statement
来防止SQL注入(或者通过使用ORM框架而不是“原始JDBC”来阻止SQL注入,就像可以通过仅使用MVC框架而不是“原始”来防止XSS问题一样JSP”)。
对于您的具体问题,基本上可以通过以下四种方法解决:
咬紧牙关,用fn:escapeXml()
或<c:out>
替换所有EL-in-template-text,以重新显示用户控制的输入,并教会自己和您的团队将来注意这一点。提示,像Eclipse一样不错的IDE具有基于正则表达式的“查找并替换所有文件”。
具有某种DB拦截器,可在插入DB之前剥离恶意HTML。如有必要,运行数据库脚本来清理现有数据。但是,这比真正的解决方案更是一种解决方法。
用一个自定义的JSP EL解析器替换该自定义解析器,该自定义编码器转义所有HTML。但是,这样做的缺点是,您永远无法在真正需要时通过EL显示纯HTML。
使用具有内置HTML转义的不错的MVC框架。但是,这不仅仅是固定单个EL表达式,还需要更多工作。