我们的应用程序允许用户从任何来源,并输入其文本复制到一个文本字段。本文的样本可能是这样的(注意没有结束的<
标签):
From Sender
Sent Monday, March 6, 2017 1132 AM
To Receiver <[email protected]
Some email text go go here.....
用户可能还需要插入恶意脚本代码,因为它是一个免费的文本字段,因此文本可能最终会是这样的:
From Sender
Sent Monday, March 6, 2017 1132 AM
To Receiver <[email protected]
Some email text go go here <script>alert("0");</script>.....
我们正在使用微软的AntiXssLibrary V4.3消毒的请求(使用GetSafeHtmlFragment()
),但是,已消毒的输出带出了从第一个未关闭<
,从而使该请求为:
From Sender
Sent Monday, March 6, 2017 1132 AM
To Receiver
我现在试图通过最初的原始请求进行迭代,并移除任何未关闭的标签,留下正确关闭标签由库处理。我遇到的问题是要弄清楚如何移动到下一个未关闭的标签,去除标签的第一指标之后。
下面是我尝试的一个示例:
private string SanitizeInputStream(string inputStream)
{
var firstStartBracketPosition = inputStream.IndexOf("<");
while(firstStartBracketPosition >= 0)
{
var firstEndBracketPosition = inputStream.IndexOf(">");
if (firstEndBracketPosition < 0)
inputStream = inputStream.Remove(firstStartBracketPosition, 1);
firstStartBracketPosition = inputStream.IndexOf("<");
}
return HttpUtility.HtmlDecode(Microsoft.Security.Application.Sanitizer.GetSafeHtmlFragment(inputStream));
}
这样的想法是要遍历传入的请求,找到一个开放标签的第一个索引,以及封闭标签的第一个索引。如果没有发现封闭的标签,在打开的标签第一索引中删除。
这应该做的工作
private string SanitizeInputStream(string inputStream)
{
var firstStartBracketPosition = inputStream.IndexOf("<");
while (firstStartBracketPosition >= 0)
{
var secondOpenBracketPosition = inputStream.IndexOf("<", firstStartBracketPosition + 1);
var firstEndBracketPosition = inputStream.IndexOf(">", firstStartBracketPosition + 1);
if (firstEndBracketPosition < secondOpenBracketPosition)
{
if (firstEndBracketPosition < 0)
inputStream = inputStream.Remove(firstStartBracketPosition, 1);
}
else
{
inputStream = inputStream.Remove(firstStartBracketPosition, 1);
}
if (inputStream.Length < firstEndBracketPosition + 1)
{
firstStartBracketPosition = inputStream.IndexOf("<", firstEndBracketPosition + 1);
}
else
{
firstStartBracketPosition = -1;
}
}
return HttpUtility.HtmlDecode(Microsoft.Security.Application.Sanitizer.GetSafeHtmlFragment(inputStream));
}