如果 JSON 字符串未关闭 html 标签,如何使用 AntiXss

How to use AntiXss if the JSON string has unclosed html tags

我们的应用程序允许用户从任何来源复制文本并将其输入到文本字段中。此文本的示例可能如下所示(注意未闭合的 < 标记):

From Sender 
Sent Monday, March 6, 2017 1132 AM
To Receiver <receiver@domain.co.za

Some email text go go here.....

用户可能还想插入恶意脚本标签,因为它是一个自由文本字段,所以文本可能会这样结束:

From Sender 
Sent Monday, March 6, 2017 1132 AM
To Receiver <receiver@domain.co.za

Some email text go go here <script>alert("0");</script>.....

我们正在使用 Microsoft 的 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));
    }