簡體   English   中英

如何使用 C# 驗證字符串不包含 HTML

[英]How to validate that a string doesn't contain HTML using C#

有沒有人有一種簡單有效的方法來檢查字符串是否包含 HTML? 基本上,我想檢查某些字段是否僅包含純文本。 我想尋找 < 字符,但它可以很容易地在純文本中使用。 另一種方法可能是使用以下方法創建一個新的 System.Xml.Linq.XElement:

XElement.Parse("<wrapper>" + MyString + "</wrapper>")

並檢查 XElement 是否不包含子元素,但這對於我需要的東西來說似乎有點重量級。

以下將匹配任何匹配的標簽集。 即<b>這個</b>

Regex tagRegex = new Regex(@"<\s*([^ >]+)[^>]*>.*?<\s*/\s*\1\s*>");

以下將匹配任何單個標簽。 即 <b> (它不必關閉)。

Regex tagRegex = new Regex(@"<[^>]+>");

然后你可以像這樣使用它

bool hasTags = tagRegex.IsMatch(myString);

您可以通過使用HttpUtility.HtmlEncode對輸入進行編碼來確保純文本。

事實上,根據您希望檢查的嚴格程度,您可以使用它來確定字符串是否包含 HTML:

bool containsHTML = (myString != HttpUtility.HtmlEncode(myString));

干得好:

using System.Text.RegularExpressions;
private bool ContainsHTML(string checkString)
{
  return Regex.IsMatch(checkString, "<(.|\n)*?>");
}

這是最簡單的方法,因為括號中的項目不太可能自然發生。

我剛剛嘗試了我的 XElement.Parse 解決方案。 我在字符串類上創建了一個擴展方法,以便我可以輕松地重用代碼:

public static bool ContainsXHTML(this string input)
{
    try
    {
        XElement x = XElement.Parse("<wrapper>" + input + "</wrapper>");
        return !(x.DescendantNodes().Count() == 1 && x.DescendantNodes().First().NodeType == XmlNodeType.Text);
    }
    catch (XmlException ex)
    {
        return true;
    }
}

我發現的一個問題是純文本與符號和小於字符會導致 XmlException 並指示該字段包含 HTML(這是錯誤的)。 為了解決這個問題,傳入的輸入字符串首先需要將&符號和小於字符轉換為它們等效的 XHTML 實體。 我寫了另一個擴展方法來做到這一點:

public static string ConvertXHTMLEntities(this string input)
{
    // Convert all ampersands to the ampersand entity.
    string output = input;
    output = output.Replace("&amp;", "amp_token");
    output = output.Replace("&", "&amp;");
    output = output.Replace("amp_token", "&amp;");

    // Convert less than to the less than entity (without messing up tags).
    output = output.Replace("< ", "&lt; ");
    return output;
}

現在我可以使用用戶提交的字符串並使用以下代碼檢查它是否不包含 HTML:

bool ContainsHTML = UserEnteredString.ConvertXHTMLEntities().ContainsXHTML();

我不確定這是否是防彈的,但我認為這對我的情況來說已經足夠了。

這也會檢查諸如 < br /> 帶有可選空格的自封閉標簽之類的東西。 該列表不包含新的 html5 標簽。

internal static class HtmlExts
{
    public static bool containsHtmlTag(this string text, string tag)
    {
        var pattern = @"<\s*" + tag + @"\s*\/?>";
        return Regex.IsMatch(text, pattern, RegexOptions.IgnoreCase);
    }

    public static bool containsHtmlTags(this string text, string tags)
    {
        var ba = tags.Split('|').Select(x => new {tag = x, hastag = text.containsHtmlTag(x)}).Where(x => x.hastag);

        return ba.Count() > 0;
    }

    public static bool containsHtmlTags(this string text)
    {
        return
            text.containsHtmlTags(
                "a|abbr|acronym|address|area|b|base|bdo|big|blockquote|body|br|button|caption|cite|code|col|colgroup|dd|del|dfn|div|dl|DOCTYPE|dt|em|fieldset|form|h1|h2|h3|h4|h5|h6|head|html|hr|i|img|input|ins|kbd|label|legend|li|link|map|meta|noscript|object|ol|optgroup|option|p|param|pre|q|samp|script|select|small|span|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|title|tr|tt|ul|var");
    }
}

尖括號可能不是您唯一的挑戰。 其他字符也可能是潛在有害的腳本注入。 比如常見的雙連字符“--”,也可以用在SQL注入中。 還有其他人。

在 ASP.Net 頁面上,如果 machine.config、web.config 或頁面指令中的 validateRequest = true,則用戶將收到一個錯誤頁面,指出“從客戶端檢測到潛在危險的 Request.Form 值”(如果 HTML 標記)或檢測到其他各種潛在的腳本注入攻擊。 您可能希望避免這種情況並提供更優雅、更不可怕的 UI 體驗。

您可以使用正則表達式測試開始和結束標記 <>,如果只有其中一個出現,則允許文本。 允許 < 或 >,但不允許 < 后跟一些文本,然后是 >,按此順序。

您可以允許尖括號和 HtmlEncode 文本在數據持久化時保留它們。

使用上面提到的 HttpUtility.HtmlEncode 方法時要小心。 如果您正在檢查一些帶有特殊字符而不是 HTML 的文本,它將錯誤地評估。 也許這就是為什么 J c 使用“...取決於您希望檢查的嚴格程度...”

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM