用户输入
“清理您的输入”(或预编码或预转义)您的内容的想法很糟糕。当您真正需要它时,它实际上并不能保护您,并导致各种设计难题。甚至 PHP 也最终放弃了这项技术。
最好通过适当的 API 正确处理数据,这样可以消除风险。例如,使用准备好的语句或带有内容占位符的语句绝对消除了 SQL 注入。这种技术已经存在了很长时间(只要我使用 Java 和 SQL)。
Grails (GORM) 自动处理通过对象保存的任何内容的编码,包括设置单个属性、创建新对象并保存它,或通过 obj.properties = params 或类似的方式设置属性。
只要你使用的是 GORM,就没有 SQL 注入的风险。
内容存储
此外,将已经编码的信息存储在数据库中通常被认为是不正确的,因为该编码仅对给定的显示类型(例如 HTML)是正确的。如果您想使用 JSON 来呈现它,则 HTML 编码不正确。 XML 也略有不同,有时您也可能更喜欢纯文本。
相反,您通常应该将原始(UTF8 或类似)数据存储在数据库中,并在呈现以供显示时将其转换为正确的显示类型。请注意,在渲染时会进行转换——这并不一定意味着每次将其发送给客户端。您可以使用各种缓存技术来确保不会经常发生这种情况——包括new cache plugin added to Grails 2.1。
然而,一种强烈推荐的技术是使用grails.views.default.codec option 将默认视图编解码器设置为 HTML,如下所示:
grails.views.default.codec = 'html'
这只会影响 GSP,并且只会影响使用美元符号语法 (${foo}) 回显的内容。这使您可以灵活地使用标签(推荐的方式)或一次性情况下的 <%= %> 语法覆盖此行为。但是,它应该能够很好地阻止 XSS 攻击。
性能注意事项
最后一点:将内容编码为 HTML 是性能问题的担忧将被视为过早的优化。任何性能瓶颈出现在其他地方的可能性非常很高,而不是在内容的编码中。首先构建您的应用程序(使用良好的设计),然后在您对正在运行的应用程序进行基准测试和分析之后进行优化。