除了<p> <br/> <b> <a></a> </b> </p>之外,XSLT将转义所有实体

时间:2012-06-23 09:47:57

标签: php xml xslt xslt-1.0

我对xslt

有一个小问题

我有这个文字

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

我想要转义除<p> <br> <b> <a>之外的所有实体,因此当我使用

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

能够加粗文字,插入链接等等,但<script>标记要转义,但不会使用strip_tags剥离...但是当我让disable-output-escaping="yes"我收到消息时,所以这里有XSS漏洞...

我的PHP代码是

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

那我怎么能这样做呢?

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

2 个答案:

答案 0 :(得分:0)

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

我意识到你说你不想使用strip_tags有什么理由吗?它允许您指定您能够保留的标签。

答案 1 :(得分:0)

如果将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元素都会被最后一个模板选中并复制' as-is',以及*模板拾取的任何其他内容,而不是使用实际元素,而是输出转义文本。第一个模板就是为了确保其中的任何元素都使用“post”模式进行处理,因此这些模板不会意外地处理其他任何不应该的模板。