我对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:我非常关心安全问题!感谢。答案 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('<',name(),'>')" />
<xsl:apply-templates mode="post"/>
<xsl:value-of select="concat('</',name(),'>')" />
</xsl:template>
<xsl:template match="p | br | b | a" mode="post">
<xsl:copy>
<xsl:apply-templates select="@* | node()" mode="post"/>
</xsl:copy>
</xsl:template>
这有点粗糙,但基本上,我们的想法是,任何p
,br
,b
或a
元素都会被最后一个模板选中并复制' as-is',以及*
模板拾取的任何其他内容,而不是使用实际元素,而是输出转义文本。第一个模板就是为了确保其中的任何元素都使用“post”模式进行处理,因此这些模板不会意外地处理其他任何不应该的模板。