You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XSLT禁用输出转义时如何仅放行指定HTML标签防范XSS漏洞

XSLT评论输出防XSS白名单配置方案

问题说明

当前使用如下XSLT代码输出评论内容时,全局开启disable-output-escaping="yes"会直接原样输出所有HTML/脚本内容,存在XSS跨站脚本安全漏洞:

<xsl:value-of disable-output-escaping="yes" select="//datafor:field[datafor:name='comments']/datafor:value" />

需要实现白名单过滤机制,仅放行指定标签和属性,在保留内容渲染格式的同时规避安全风险,待放行范围如下:

  • 无属性允许标签:b、strong、i、ul、ol、li、br
  • 带属性允许标签:p(仅允许style属性)、div(仅允许class属性)

实现方案

核心原则:彻底移除全局disable-output-escaping="yes"配置,改用XSLT模板递归遍历评论内容的所有节点,基于白名单规则逐节点校验输出,非白名单内容自动转义或过滤。

完整实现代码

<!-- 1. 替换原有value-of输出逻辑,调用清洗模板处理评论节点 -->
<xsl:apply-templates select="//datafor:field[datafor:name='comments']/datafor:value/node()" mode="comment-sanitize" />

<!-- 2. 基础身份模板:默认复制所有校验通过的节点 -->
<xsl:template mode="comment-sanitize" match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()" mode="comment-sanitize" />
  </xsl:copy>
</xsl:template>

<!-- 3. 匹配无属性白名单标签 + p标签(放行style属性) -->
<xsl:template mode="comment-sanitize" match="b|strong|i|ul|ol|li|br|p">
  <xsl:element name="{local-name()}">
    <xsl:if test="local-name() = 'p'">
      <!-- 仅复制p标签的style属性,其余属性自动忽略 -->
      <xsl:copy-of select="@style" />
    </xsl:if>
    <xsl:apply-templates select="node()" mode="comment-sanitize" />
  </xsl:element>
</xsl:template>

<!-- 4. 匹配div标签,仅放行class属性 -->
<xsl:template mode="comment-sanitize" match="div">
  <xsl:element name="div">
    <xsl:copy-of select="@class" />
    <xsl:apply-templates select="node()" mode="comment-sanitize" />
  </xsl:element>
</xsl:template>

<!-- 5. 非白名单标签:剔除标签本身,仅输出内部纯文本,特殊字符自动转义 -->
<xsl:template mode="comment-sanitize" match="*[not(local-name() = ('b','strong','i','ul','ol','li','br','p','div'))]">
  <xsl:apply-templates select="node()" mode="comment-sanitize" />
</xsl:template>

<!-- 6. 非白名单属性:直接拦截不输出 -->
<xsl:template mode="comment-sanitize" match="@*[not(
  (local-name() = 'style' and parent::p)
  or (local-name() = 'class' and parent::div)
)]" />

注意事项

  • 如果评论字段存储的是转义后的HTML字符串(节点内容为&lt;b&gt;测试&lt;/b&gt;这类未解析的文本),XSLT 1.0需要借助对应处理器的节点集扩展函数(如MSXML的msxml:node-set、libxslt的exslt:node-set)将字符串解析为节点集后再套用上述模板;XSLT 2.0及以上版本可直接使用parse-xml-fragment()函数解析后处理。
  • 建议对放行的style属性值增加二次校验,拦截javascript:、expression()等危险脚本片段,避免属性值注入风险。
  • 所有输出的非白名单内容会被XSLT默认转义为实体字符,从根源上阻断XSS注入路径。

内容的提问来源于stack exchange,提问作者adam78

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 22:36:22