Я уверен, что об этом спрашивали несколько раз, но у меня проблемы с поиском чего-то, что соответствует тому, что я хочу.Я хочу иметь возможность безопасно отображать 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);
}
Все тесты пройдены, но что я пропустил?
Спасибо.