文字列にHTMLが含まれていないことを確認する簡単で効率的な方法はありますか?基本的に、特定のフィールドにプレーンテキストのみが含まれていることを確認したいと思います。 <文字を探すことを考えましたが、プレーンテキストで簡単に使用できます。別の方法は、以下を使用して新しいSystem.Xml.Linq.XElementを作成することです。
XElement.Parse("<wrapper>" + MyString + "</wrapper>")
xElementに子要素が含まれていないことを確認しますが、これは私が必要としているものに対して少し重いようです。
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;
}
}
私が見つけた問題の1つは、プレーンテキストのアンパサンドと小なり文字がXmlExceptionを引き起こし、フィールドにHTMLが含まれていることを示していることでした(これは間違っています)。これを修正するには、最初に渡される入力文字列に、アンパサンドと文字未満を同等のXHTMLエンティティに変換する必要があります。私はそれを行うために別の拡張メソッドを書きました:
public static string ConvertXHTMLEntities(this string input)
{
// Convert all ampersands to the ampersand entity.
string output = input;
output = output.Replace("&", "amp_token");
output = output.Replace("&", "&");
output = output.Replace("amp_token", "&");
// Convert less than to the less than entity (without messing up tags).
output = output.Replace("< ", "< ");
return output;
}
これで、ユーザーが送信した文字列を取得し、次のコードを使用してHTMLが含まれていないことを確認できます。
bool ContainsHTML = UserEnteredString.ConvertXHTMLEntities().ContainsXHTML();
これが防弾かどうかはわかりませんが、私の状況には十分だと思います。
以下は、一致するタグのセットと一致します。つまり、<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)*?>");
}
括弧内の項目は自然に発生する可能性が低いため、これが最も簡単な方法です。
これは、オプションの空白を含む<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、またはpageディレクティブでvalidateRequest = trueの場合、HTMLタグの場合、「潜在的に危険なRequest.Form値がクライアントから検出されました」というエラーページが表示されます。または、その他のさまざまな潜在的なスクリプトインジェクション攻撃が検出されます。おそらくこれを避けて、よりエレガントで怖くないUIエクスペリエンスを提供したいと思うでしょう。
正規表現を使用して開始タグと終了タグの両方をテストし、どちらか一方のみが発生する場合はテキストを許可することができます。 <または>を許可しますが、<、テキスト、>の順に許可します。
山かっことHtmlEncodeを許可して、データが永続化されるときにそれらを保持することができます。
上記のHttpUtility.HtmlEncodeメソッドを使用する場合は注意してください。 HTMLではなく特殊文字を含むテキストをチェックしている場合、正しく評価されません。たぶんそれがJcが「...チェックをどれだけ厳しくしたいかに応じて...」を使用した理由です。