public void RemoveEmptyCascadedTest() { string input, result, expected; var sanitizer = new HtmlSanitizer(); sanitizer.WhiteListMode = true; sanitizer.Tag("span").RemoveEmpty(); sanitizer.Tag("font").RemoveEmpty().AllowAttributes("id"); // The font tag is empty and will be removed. This results in the span tag also being empty, which would // lead one to expect the span tag to be removed completely. input = @"<span><font></font></span>"; expected = @""; result = sanitizer.Sanitize(input); Assert.Equal(expected, result); }
public void TagRenameTest() { var input = "<b>before</b> <strong>content</strong> after<b></b>"; var expected = "<strong>before</strong> <strong>content</strong> after"; string result; var sanitizer = new HtmlSanitizer(); sanitizer.Tag("strong").RemoveEmpty(); sanitizer.Tag("b").Rename("strong").RemoveEmpty(); sanitizer.Tag("i").RemoveEmpty(); sanitizer.Tag("a").SetAttribute("target", "_blank") .SetAttribute("rel", "nofollow") .CheckAttributeUrl("href") .RemoveEmpty(); result = sanitizer.Sanitize(input); Assert.Equal(expected, result); }
public void RemoveEmptyTest() { string input, result, expected; var sanitizer = new HtmlSanitizer(); sanitizer.WhiteListMode = true; sanitizer.Tag("span").RemoveEmpty(); sanitizer.Tag("font").RemoveEmpty().AllowAttributes("id"); // Simply empty tags must be removed if instructed to do so. input = @"<span>Test test<font></font></span>"; expected = @"<span>Test test</span>"; result = sanitizer.Sanitize(input); Assert.Equal(expected, result); // While empty content wise, it does have attributes. It should not simply be removed. input = @"<span>Test test<font id=""test-id""></font></span>"; expected = @"<span>Test test<font id=""test-id""></font></span>"; result = sanitizer.Sanitize(input); Assert.Equal(expected, result); // The font tag is not really empty as it contains a space. input = @"<span>Test test<font> </font></span>"; expected = @"<span>Test test<font> </font></span>"; result = sanitizer.Sanitize(input); Assert.Equal(expected, result); // The font tag is not really empty as it contains a linebreak. input = @"<span>Test test<font> </font></span>"; expected = @"<span>Test test<font> </font></span>"; result = sanitizer.Sanitize(input); Assert.Equal(expected, result); // The unclosed font tag should not show up at all, and at least be removed because it is empty. input = @"<span>Test test<font></span>"; expected = @"<span>Test test</span>"; result = sanitizer.Sanitize(input); Assert.Equal(expected, result); }
public void TagFlattenTests() { var input = @"<p>Some prepended content</p> <p>before <span><b>Preserve before</b> content <i>Preserve</i></span> after</p> <p>Some trailing content</p>"; var expected = @"<p>Some prepended content</p> <p>before <b>Preserve before</b> content <i>Preserve</i> after</p> <p>Some trailing content</p>"; string result; var sanitizer = new HtmlSanitizer(); sanitizer.Tag("span").Operation(SanitizerOperation.FlattenTag); sanitizer.Tag("i"); sanitizer.Tag("b"); sanitizer.Tag("p"); // Test flatten result = sanitizer.Sanitize(input); Assert.Equal(expected, result); }
public void UnescapedAttributeTest() { string result; var sanitizer = new HtmlSanitizer(); sanitizer.Tag("span").AllowAttributes("style"); var input = @"<span style=""<strong>Whats this?</strong>"">Text</span>"; result = sanitizer.Sanitize(input); Assert.Equal(input, result); }
public void DivStackOverflowAttempt() { string result; var sanitizer = new HtmlSanitizer(); sanitizer.Tag("div"); sanitizer.MaxRecursionDepth = 10; // Test some illegal href var input = @"<meta http-equiv=""Content-Type"" content=""text/html; charset=utf-8""><div class=""reply-body""> <div> <span style=""font-family: arial, helvetica, sans-serif;""><span style=""font-size: 14px;""><span style=""color: #000000;"">Hi friend,</span></span> </span> </div> </div> <div> <div class=""reply-body""> </div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> "; Assert.Throws <InvalidOperationException>(() => { result = sanitizer.Sanitize(input); }); }
public void AttributeWhiteListing() { string result; var sanitizer = new HtmlSanitizer(); sanitizer.Tag("input").AllowAttributes("whitelisted"); var input = @"<input nonwhitelisted="""" whitelisted="""">"; var expected = @"<input whitelisted="""">"; result = sanitizer.Sanitize(input); Assert.Equal(expected, result); }
public void EmptyAttributeTest() { string result; var sanitizer = new HtmlSanitizer(); sanitizer.Tag("input").AllowAttributes("disabled value"); var input = @"<input disabled value=""test"">"; var expected = @"<input disabled="""" value=""test"">"; result = sanitizer.Sanitize(input); Assert.Equal(expected, result); }
public void ImgSrcUrlCheckRelativeTest() { string result; var sanitizer = new HtmlSanitizer(); sanitizer.Tag("img").CheckAttributeUrl("src"); // Test a relative url, which should pass. var input = @"<img src=""../relative.png"">"; var expected = @"<img src=""../relative.png"">"; result = sanitizer.Sanitize(input); Assert.Equal(expected, result); }
public void InvalidUrlEncodingTest() { string result; var sanitizer = new HtmlSanitizer(); sanitizer.Tag("a").CheckAttributeUrl("href"); // Test a relative url, which should pass. var input = @"<a href=""mailto:[email protected]?subject=test this"">MailTo</a>"; var expected = @"<a href=""mailto:[email protected]?subject=test this"">MailTo</a>"; result = sanitizer.Sanitize(input); Assert.NotEqual(expected, result); }
public void AHrefUrlCheckRelativeTest() { string result; var sanitizer = new HtmlSanitizer(); sanitizer.Tag("a").CheckAttributeUrl("href"); // Test a relative url, which should pass. var input = @"<a href=""../relative.htm"">Relative link</a>"; var expected = @"<a href=""../relative.htm"">Relative link</a>"; result = sanitizer.Sanitize(input); Assert.Equal(expected, result); }
public void CustomAttributeSanitization() { string result; var sanitizer = new HtmlSanitizer(); var attributeSanitizer = new CustomSanitizer(); sanitizer.Tag("span").SanitizeAttributes("style", attributeSanitizer); var input = @"<span style=""heading"">Text</span>"; var expected = @"<span style=""123"">Text</span>"; result = sanitizer.Sanitize(input); Assert.Equal(expected, result); }
public void DivRecursionAttempt() { string result; var sanitizer = new HtmlSanitizer(); sanitizer.Tag("div"); sanitizer.MaxRecursionDepth = 10; // Test 11 nested div elements var input = @" <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> <div> </div></div></div></div></div></div></div></div></div></div></div>"; Assert.Throws <InvalidOperationException>(() => { result = sanitizer.Sanitize(input); }); }
public void RuleOperationTests() { var input = "before <span>content</span> after"; var remove = "before after"; var flatten = "before content after"; string result; var sanitizer = new HtmlSanitizer(); // Test do nothing sanitizer.Tag("span").Operation(SanitizerOperation.DoNothing); result = sanitizer.Sanitize(input); Assert.Equal(input, result); // Test flatten sanitizer.Tag("span").Operation(SanitizerOperation.FlattenTag); result = sanitizer.Sanitize(input); Assert.Equal(flatten, result); // Test remove sanitizer.Tag("span").Operation(SanitizerOperation.RemoveTag); result = sanitizer.Sanitize(input); Assert.Equal(remove, result); }
public void AHrefUrlDataUriCheckTest() { string result; var sanitizer = new HtmlSanitizer(); sanitizer.Tag("a").CheckAttribute("href", HtmlSanitizerCheckType.Url); // Test some well formed href var inputLegal = @"<a href=""data:image/svg+xml;base64,UEsDBBQAAAAI"">That XSS trick</a>"; result = sanitizer.Sanitize(inputLegal); Assert.Equal(inputLegal, result); // Test a illegal var inputIllegal = @"<a href=""data:html/text;base64,UEsDBBQAAAAI"">That XSS trick</a>"; result = sanitizer.Sanitize(inputIllegal); Assert.Equal("That XSS trick", result); }
public void ImgSrcUrlCheckTest() { string result; var sanitizer = new HtmlSanitizer(); sanitizer.Tag("img").CheckAttributeUrl("src"); // Test some illegal href var inputIllegal = @"<img src=""javascript:alert('test')"">"; var expectedIllegal = @""; result = sanitizer.Sanitize(inputIllegal); Assert.Equal(expectedIllegal, result); // Test a legal well formed url var inputLegal = @"<img src=""http://www.google.com/a.png"">"; result = sanitizer.Sanitize(inputLegal); Assert.Equal(inputLegal, result); }
public void AHrefUrlCheckTestLegacy() { string result; var sanitizer = new HtmlSanitizer(); sanitizer.Tag("a").CheckAttributeUrl("href"); // Test some illegal href var inputIllegal = @"<a href=""javascript:alert('test')"">That XSS trick</a>"; var expectedIllegal = @"That XSS trick"; result = sanitizer.Sanitize(inputIllegal); Assert.Equal(expectedIllegal, result); // Test a legal well formed url var inputLegal = @"<a href=""http://www.google.com/"">Legal link</a>"; result = sanitizer.Sanitize(inputLegal); Assert.Equal(inputLegal, result); }
/// <summary> /// Returns an instance of the HtmlSanitizer with a HTML5 compliant rule set for documents with simple markup. /// </summary> /// <remarks>Strips all CSS and only allows simple links. Enfores nofollow.</remarks> /// <returns></returns> public static HtmlSanitizer SimpleHtml5Sanitizer() { var sanitizer = new HtmlSanitizer(); sanitizer.WhiteListMode = true; sanitizer.Tag("h1").RemoveEmpty(); sanitizer.Tag("h2").RemoveEmpty(); sanitizer.Tag("h3").RemoveEmpty(); sanitizer.Tag("h4").RemoveEmpty(); sanitizer.Tag("h5").RemoveEmpty(); sanitizer.Tag("strong").RemoveEmpty(); sanitizer.Tag("b").Rename("strong").RemoveEmpty(); sanitizer.Tag("i").RemoveEmpty(); sanitizer.Tag("em"); sanitizer.Tag("br"); sanitizer.Tag("p"); sanitizer.Tag("div").NoAttributes(SanitizerOperation.FlattenTag); sanitizer.Tag("span").RemoveEmpty(); sanitizer.Tag("ul"); sanitizer.Tag("ol"); sanitizer.Tag("li"); sanitizer.Tag("a").SetAttribute("target", "_blank") .SetAttribute("rel", "nofollow") .CheckAttribute("href", HtmlSanitizerCheckType.Url) .RemoveEmpty() .NoAttributes(SanitizerOperation.FlattenTag); return(sanitizer); }
/// <summary> /// White lists the specified HTML tag, creating a rule for it which allows further specification of what is to be done /// with the tag. /// </summary> /// <param name="sanitizer"></param> /// <param name="tagName"></param> /// <returns></returns> public static HtmlSanitizerTagRule Tag(this HtmlSanitizer sanitizer, string tagName) { return(sanitizer.Tag(tagName, true)); }
/// <summary> /// Returns an instance of the HtmlSanitizer with a HTML5 compliant rule set for documents with simple markup. /// </summary> /// <remarks>Strips all CSS and only allows simple links. Enfores nofollow.</remarks> /// <returns></returns> public static HtmlSanitizer SimpleHtml5Sanitizer() { var sanitizer = new HtmlSanitizer(); sanitizer.WhiteListMode = true; sanitizer.AllowCssClassAttribute = true; sanitizer.Tag("script").Remove(); sanitizer.Tag("header").RemoveEmpty(); sanitizer.Tag("h1").RemoveEmpty(); sanitizer.Tag("h2").RemoveEmpty(); sanitizer.Tag("h3").RemoveEmpty(); sanitizer.Tag("h4").RemoveEmpty(); sanitizer.Tag("h5").RemoveEmpty(); sanitizer.Tag("strong").RemoveEmpty(); sanitizer.Tag("b").Rename("strong").RemoveEmpty(); sanitizer.Tag("i").RemoveEmpty(); sanitizer.Tag("em"); sanitizer.Tag("code"); sanitizer.Tag("br"); sanitizer.Tag("hr"); sanitizer.Tag("p"); sanitizer.Tag("pre"); sanitizer.Tag("div").NoAttributes(SanitizerOperation.FlattenTag); sanitizer.Tag("span").RemoveEmpty(); sanitizer.Tag("ul"); sanitizer.Tag("ol"); sanitizer.Tag("dl"); sanitizer.Tag("dt"); sanitizer.Tag("li"); sanitizer.Tag("a").SetAttribute("target", "_blank") .SetAttribute("rel", "nofollow") .CheckAttribute("href", HtmlSanitizerCheckType.Url) .RemoveEmpty() .NoAttributes(SanitizerOperation.FlattenTag); sanitizer.Tag("img") .CheckAttribute("src", HtmlSanitizerCheckType.UrlOrBase64Data) .AllowAttributes("alt height width rel") .NoAttributes(SanitizerOperation.RemoveTag); return(sanitizer); }