【问题标题】:XSLT escape all entities except <p> <br> <b> <a>XSLT 转义除 <p> <br> <b> <a> 之外的所有实体
【发布时间】:2012-06-25 11:29:54
【问题描述】:

我有一个关于 xslt 的小问题

我有这段文字

newline<br /> <br /> newline<br /> <br /> <br /> newline<br /> <br /> <br /> newline<br /> <br /> <b>asdasdasd</b><br /> <br /> <script>alert(0)</script>

我想转义除&lt;p&gt; &lt;br&gt; &lt;b&gt; &lt;a&gt; 之外的所有实体,因此当我使用时

<xsl:value-of select="page/@post_content" disable-output-escaping="yes"/>

能够加粗文本,插入链接......等等,但是&lt;script&gt;标签被转义但不被strip_tags剥离......但是当我让disable-output-escaping="yes"收到一条消息时,所以有XSS这里的漏洞...

我的php代码是

$hrefs->item(0)->setAttribute("post_content",nl2br($PostContent));

那我该怎么做呢?

PS:我非常关心安全!谢谢。

【问题讨论】:

  • 你为什么不把你想要的没有输出的元素转义?如果您担心安全性,您可以采用白名单方法。而且您不应该只禁用所有子元素的输出转义,这显然是错误的。
  • 我真的不知道该怎么做,我相信这是一个简单的问题,但我没有找到答案,你的想法是,让 PHP 来做这个或 XSLT?
  • 那么你是否一直在应用禁用输出转义?
  • IIRC 你应该可以在 select 属性中告诉哪些标签不应该被转义,可能使用 xpath 联合(| 运算符)。好的,我看到这是一个属性。您还需要将属性值视为 XML。您可能应该将 XML 也添加到您的问题和一些代码中,以便更清楚您在做什么。
  • 没有简单的解决方案吗?因为这是一个简单的问题,只是输出一些东西..

标签: php xml xslt xslt-1.0


【解决方案1】:

XSLT 并不是真正为此而设计的,虽然您可以使用 XSLT 2.0 使用 Regular Expression 来完成它,但这不是您正在使用的 XSLT 版本,并且 PHP 目前默认不使用 XSLT 2。你最好用你的后端编程语言(比如 PHP)来做。

我知道你说你不想使用strip_tags 有什么理由吗?它确实允许您指定可以保留的标签。

【讨论】:

  • XSLT 2.0 =/= XSLT 1.0(默认情况下在 PHP 中只有 XSLT 1.0)。
  • 我知道,但是 strip_tags 做了什么,它实际上使 成为 alert(0)
  • 啊,所以您希望 html 标签只是转义而不是剥离。给我几分钟
【解决方案2】:

如果您将 post_content 放入属性值中,您将很难使用 XSLT 执行此操作,因为该属性将包含一个大长字符串。如果用户输入了无效的 HTML 会发生什么?

如果您将 xml 直接放入名为“post_content”的元素中,则可以使用这些模板:

<xsl:template match="post_content">
  <xsl:apply-templates mode="post" />
</xsl:template>

<xsl:template match="*" mode="post">
  <xsl:value-of select="concat('&lt;',name(),'&gt;')" />
  <xsl:apply-templates mode="post"/>
  <xsl:value-of select="concat('&lt;/',name(),'&gt;')" />
</xsl:template>

<xsl:template match="p | br | b | a" mode="post">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()" mode="post"/>
    </xsl:copy>
</xsl:template>

这有点粗略,但基本上,这个想法是任何pbrba 元素都被最后一个模板拾取并“按原样”复制,以及其他任何内容由* 模板提取,而不是使用实际元素,而是输出转义文本。第一个模板只是为了确保其中的任何元素都使用“发布”模式进行处理,因此这些模板不会意外处理它们不应该处理的任何其他内容。

【讨论】:

  • 我已经用 PHP 做到了这一点,比如 $PostContent = htmlentities($PostContent); $PostContent = nl2br($PostContent); $hrefs->item(0)->setAttribute("post_content",$PostContent);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 2015-11-24
相关资源
最近更新 更多