1)有没有办法默认逃跑?
不在老式 JSP 中。然而,它的继任者 Facelets 在默认情况下会避开它们。禁用转义的唯一方法是使用<h:outputText value="#{bean.foo}" escape="false" />
而不是#{bean.foo}
.
2) 为什么有人可能需要在 el 中未转义的 HTML?将 HTML 存储在模板之外(例如在数据库中)不是一个好习惯。
然而,存储净化的 HTML 并不常见。例如,允许一小部分无辜的 HTML 标记,如、<p>
和,其中属性已经被剥离。<b>
<i>
on*
3) 我确信模板引擎应该自动处理它(就像在 XSLT 中所做的那样),用户为什么要关心它?手动转义 (fn:escapeXml) 闻起来像 SQL 手动转义(用于代替 JDBC setParam):样板代码和 sql 注入的好地方(在我们的例子中是跨站点脚本)。
JSP是一种古老的视图技术。它不是一个真正灵活的模板引擎。
SQL 注入通常可以通过使用PreparedStatement
而不是Statement
(或使用 ORM 框架而不是“原始 JDBC”来防止,就像您的 XSS 问题可以通过使用 MVC 框架而不是“原始 JSP”来防止)。
至于您的具体问题,您可以通过以下四种方式解决:
咬紧牙关,替换所有重新显示用户控制输入的 EL-in-template-text,fn:escapeXml()
并<c:out>
教您自己和您的团队在未来注意这一点。提示,像 Eclipse 这样有点体面的 IDE 有一个基于正则表达式的 find-and-replace-in-all-files。
有一种 DB 拦截器,可以在插入 DB 之前去除恶意 HTML。如有必要,运行数据库脚本来清理现有数据。然而,这更像是一种解决方法,而不是真正的解决方案。
将 JSP EL 解析器替换为转义所有 HTML 的自定义解析器。然而,这有一个缺点,即您永远无法在真正需要时通过 EL 显示纯 HTML。
使用具有内置 HTML 转义功能的体面的 MVC 框架。然而,这不仅仅是修复单个 EL 表达式的工作。