ASP.net разбор HTML, чтобы сделать его безопасным.Это нормально? - PullRequest
0 голосов
/ 03 апреля 2012

Я уверен, что об этом спрашивали несколько раз, но у меня проблемы с поиском чего-то, что соответствует тому, что я хочу.Я хочу иметь возможность безопасно отображать html на своей веб-странице, но разрешать только ссылки,
и

теги

Я пришел к следующему, но хочу убедиться, что я ничего не испортилили, если есть лучший способ, пожалуйста, дайте мне знать.

Код:

    private string RemoveEvilTags(string value)
    {
        string[] allowed = { "<br/>", "<p>", "</p>", "</a>", "<a href" };
        string anchorPattern = @"<a[\s]+[^>]*?href[\s]?=[\s\""\']+(?<href>.*?)[\""\']+.*?>(?<fileName>[^<]+|.*?‌​)?<\/a>";            
        string safeText = value;

        System.Text.RegularExpressions.MatchCollection matches = Regex.Matches(value, anchorPattern, RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Compiled);
        if (matches.Count > 0)
        {
            foreach (Match m in matches)
            {
                string url = m.Groups["href"].Value;
                string linkText = m.Groups["fileName"].Value;                    

                Uri testUri = null;
                if (Uri.TryCreate(url, UriKind.Absolute, out testUri) && testUri.AbsoluteUri.StartsWith("http"))
                {
                    safeText = safeText.Replace(m.Groups[0].Value, string.Format("<a href=\"{0}\" >{1}</a>", testUri.AbsoluteUri, linkText));
                }
                else
                {
                    safeText = safeText.Replace(m.Groups[0].Value, linkText);
                }
            }
        }

        //Remove everything.
        safeText = System.Text.RegularExpressions.Regex.Replace(safeText, @"<[a-zA-Z\/][^>]*>", m => m != null && allowed.Contains(m.Value) || m.Value.StartsWith("<a href") ? m.Value : String.Empty);

        //Now add them back in.
        return safeText;
    }

Тесты:

    [Test]
    public void EvilTagTest()
    {
        var safeText = RemoveEvilTags("this is a test <p>ok</p>");
        Assert.AreEqual("this is a test <p>ok</p>", safeText);

        safeText = RemoveEvilTags("this is a test <script>ok</script>");
        Assert.AreEqual("this is a test ok", safeText);

        safeText = RemoveEvilTags("this is a test <script><script>ok</script></script>");
        Assert.AreEqual("this is a test ok", safeText);

        //Check relitive link
        safeText = RemoveEvilTags("this is a test <a href=\"bob\" >click here</a>");
        Assert.AreEqual("this is a test click here", safeText);

        //Check full link
        safeText = RemoveEvilTags("this is a test <a href=\"http://test.com/\" >click here</a>");
        Assert.AreEqual("this is a test <a href=\"http://test.com/\" >click here</a>", safeText);

        //Check full link
        safeText = RemoveEvilTags("this is a test <a href=\"https://test.com/\" >click here</a>");
        Assert.AreEqual("this is a test <a href=\"https://test.com/\" >click here</a>", safeText);

        //javascript link
        safeText = RemoveEvilTags("this is a test <a href=\"javascript:evil()\" >click here</a>");
        Assert.AreEqual("this is a test click here", safeText);

        safeText = RemoveEvilTags("this is a test <a href=\"https://test.com/\" ><script>evil();</script>click here</a>");
        Assert.AreEqual("this is a test <a href=\"https://test.com/\" >click here</a>", safeText);
    }

Все тесты пройдены, но что я пропустил?

Спасибо.

Ответы [ 2 ]

2 голосов
/ 03 апреля 2012

Для лучшей практики не следует создавать свою собственную библиотеку для «RemoveEvilTags».Существует множество методов, которые злоумышленники могут использовать для атаки XSS.ASP.NET уже предоставляет библиотеку Anti XSS:

http://msdn.microsoft.com/en-us/library/aa973813.aspx

Поскольку вы используете ASP.NET, у Plural Sight есть хорошее видео на XSS.Более сфокусирован на MVC, однако он все еще действует в этом контексте.

http://www.pluralsight -training.net / microsoft / Players / PSODPlayer? Author = scott-allen & name = mvc3-building-security & mode = live & clip= 0 и, конечно = aspdotnet-mvc3-интро

0 голосов
/ 03 апреля 2012

Вместо написания такого кода, я бы посоветовал вам использовать html-парсер, такой как Html Agility Pack .

Ваш код для разбора кода может столкнуться с множеством необработанных угловых случаев - надеюсь, парсер справится с большинством из этих случаев. После анализа вы можете отклонить неверный ввод или разрешить только допустимые теги (в соответствии с вашими потребностями).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...