好的,所以我一直在 SO 和其他地方阅读有关降价的信息,并且用户输入和数据库之间的步骤通常给出为
- 将 Markdown 转换为 html
- 清理 html(带白名单)
- 插入数据库
但对我来说,执行以下操作更有意义:
- 清理降价(删除所有标签 - 没有例外)
- 转换为 html
- 插入数据库
我错过了什么吗?在我看来,这几乎是防 xss 的
好的,所以我一直在 SO 和其他地方阅读有关降价的信息,并且用户输入和数据库之间的步骤通常给出为
但对我来说,执行以下操作更有意义:
我错过了什么吗?在我看来,这几乎是防 xss 的
请看这个链接:
http://michelf.com/weblog/2010/markdown-and-xss/
> hello <a name="n"
> href="javascript:alert('xss')">*you*</a>
变成
<blockquote>
<p>hello <a name="n"
href="javascript:alert('xss')"><em>you</em></a></p>
</blockquote>
∴您必须在转换为 HTML后进行清理。
你的提议有两个问题:
网上有一些关于输出清理的好资源:
当然,删除/转义所有标签会使标记语言更加安全。然而,Markdown 的全部意义在于它允许用户包含任意 HTML 标记以及它自己的标记 (*) 形式。当您允许 HTML 时,无论如何您都必须清理/白名单输出,因此您最好在降价转换后执行此操作以捕获所有内容。
*:这是一个我完全不同意的设计决定,而且我认为在 SO 中没有被证明是有用的,但这是一个设计决定而不是错误。
顺便说一句,第 3 步应该是“输出到页面”;这通常发生在输出阶段,数据库包含原始提交的文本。
use Text::Markdown ();
use HTML::StripScripts::Parser ();
my $hss = HTML::StripScripts::Parser->new(
{
Context => 'Document',
AllowSrc => 0,
AllowHref => 1,
AllowRelURL => 1,
AllowMailto => 1,
EscapeFiltered => 1,
},
strict_comment => 1,
strict_names => 1,
);
$hss->filter_html(Text::Markdown::markdown(shift))
- 将 Markdown 转换为 html
- 清理 html(带白名单)
- 插入数据库
这里,假设是
- 清理降价(删除所有标签 - 没有例外)
- 转换为 html
- 插入数据库
这里的假设是
markdown sanitizer 不仅要知道危险的 HTML 和危险的 markdown,还要知道 markdown->HTML 转换器是如何工作的。这使得它比上面更简单的 unsafeHTML->safeHTML 函数更复杂,也更容易出错。
作为一个具体的例子,“删除所有标签”假设您可以识别标签,并且不能抵抗 UTF-7 攻击。可能存在其他编码攻击使这种假设没有意义,或者可能存在导致markdown-> HTML程序转换(全角'<',被markdown剥离的奇异空白字符,SCRIPT)的错误一个<script>
标签。
最安全的是:
这样,当您更新您的 HTML sanitizer 时,您将获得针对任何新发现的攻击的保护。这通常效率低下,但您可以通过存储插入了 HTML 的时间戳来获得很好的安全性,这样您就可以知道在有人知道攻击通过您的清理程序的时间段内可能插入了哪些时间戳。