html 带有占位符的消息属性中的标记 - 潜在的 XSS

html markup in messages properties with placeholders - XSS potential

给定消息属性文件中的消息:

message = Change relation <strong>{0}</strong> -> <strong>{1}</strong> to <strong>{2}</strong> -> <strong>{3}</strong>?

如果任何占位符的内容是受用户影响的字符串,我需要 html 转义消息以防止潜在的 XSS(我通过使用 c:out我的 JSP 模板中的标签,我想我也可以使用 spring:message 标签的 htmlEscape 属性,但我认为没有区别。

然而,这样做会破坏消息中的标记,<strong> 等,从而导致输出:

Change relation <strong>Peter</strong> -> <strong>Car</strong> to <strong>Carl</strong> -> <strong>Bus</strong>?

我已经阅读了这里的帖子 on Whosebug 但它没有解决 XSS。

我正在考虑这些选项:

1) 只需用单引号替换消息属性文件中的所有 <strong> 标记。那么就没有问题 html 转义整个消息,缺点是消息的特定部分的突出显示较少。

2) 将消息拆分为允许在 (JSP) 模板中进行单独标记的部分。感觉只是为了正确标记需要做很多工作。

我是不是漏掉了什么?哪个更好,或者还有其他选择吗?

编辑: 没有 html- 转义消息就像我希望的那样:

改变关系 Peter -> CarCarl -> 公交车?

因此 html 文件中的 messages.properties 标记在模板中显示时正在呈现。

转义时,消息如上,显示 <strong> 标签而不是渲染它们。

假设您将获得以下输出:

Change relation &lt;strong&gt;Peter&lt;/strong&gt; -&gt; &lt;strong&gt;Car&lt;/strong&gt; to &lt;strong&gt;Carl&lt;/strong&gt; -&gt; &lt;strong&gt;Bus&lt;/strong&gt;

看起来您正在转义整个 HTML 字符串,而不仅仅是需要转义的部分。

您应该单独转义每个 {#} 值,然后将其放入 HTML。您需要转义的一般值为:<>'"&,但要使用反 xss 库和模板系统如果可以的话。

一旦你逃脱了所有潜在危险的部分,你就可以使用类似 <c:out value="${msg}" escapeXml="false"/> 的东西。这不是 language/framework 我知道的,但你需要一些方法来输出实际的 HTML 与转义版本。只要您正确地避开不受信任的部分,无论您喜欢哪种方式都应该没问题。