From 146d5e4f606f5f591726698e6f45d136a428d529 Mon Sep 17 00:00:00 2001 From: Michael Ganss Date: Fri, 28 Feb 2020 16:50:59 +0100 Subject: [PATCH] Fix #206 --- src/HtmlSanitizer/HtmlSanitizer.cs | 23 ++++++++++++----------- src/HtmlSanitizer/IHtmlSanitizer.cs | 6 +++--- test/HtmlSanitizer.Tests/Tests.cs | 20 ++++---------------- 3 files changed, 19 insertions(+), 30 deletions(-) diff --git a/src/HtmlSanitizer/HtmlSanitizer.cs b/src/HtmlSanitizer/HtmlSanitizer.cs index 94e3670..862cddc 100644 --- a/src/HtmlSanitizer/HtmlSanitizer.cs +++ b/src/HtmlSanitizer/HtmlSanitizer.cs @@ -58,9 +58,8 @@ namespace Ganss.XSS /// The allowed HTML attributes such as "href" and "alt". When null, uses /// The HTML attributes that can contain a URI such as "href". When null, uses /// The allowed CSS properties such as "font" and "margin". When null, uses - /// CSS class names which are allowed in the value of a class attribute. When null, any class names are allowed. public HtmlSanitizer(IEnumerable allowedTags = null, IEnumerable allowedSchemes = null, - IEnumerable allowedAttributes = null, IEnumerable uriAttributes = null, IEnumerable allowedCssProperties = null, IEnumerable allowedCssClasses = null) + IEnumerable allowedAttributes = null, IEnumerable uriAttributes = null, IEnumerable allowedCssProperties = null) { AllowedTags = new HashSet(allowedTags ?? DefaultAllowedTags, StringComparer.OrdinalIgnoreCase); AllowedSchemes = new HashSet(allowedSchemes ?? DefaultAllowedSchemes, StringComparer.OrdinalIgnoreCase); @@ -68,7 +67,7 @@ namespace Ganss.XSS UriAttributes = new HashSet(uriAttributes ?? DefaultUriAttributes, StringComparer.OrdinalIgnoreCase); AllowedCssProperties = new HashSet(allowedCssProperties ?? DefaultAllowedCssProperties, StringComparer.OrdinalIgnoreCase); AllowedAtRules = new HashSet(DefaultAllowedAtRules); - AllowedCssClasses = allowedCssClasses != null ? new HashSet(allowedCssClasses) : null; + AllowedClasses = new HashSet(DefaultAllowedClasses, StringComparer.OrdinalIgnoreCase); } /// @@ -393,12 +392,17 @@ namespace Ganss.XSS } /// - /// Gets or sets the allowed CSS classes. + /// The default allowed CSS classes. + /// + public static ISet DefaultAllowedClasses { get; } = new HashSet(StringComparer.OrdinalIgnoreCase); + + /// + /// Gets or sets the allowed CSS classes. If the set is empty, all classes will be allowed. /// /// - /// The allowed CSS classes. + /// The allowed CSS classes. An empty set means all classes are allowed. /// - public ISet AllowedCssClasses { get; private set; } + public ISet AllowedClasses { get; private set; } /// /// Occurs after sanitizing the document and post processing nodes. @@ -675,9 +679,6 @@ namespace Ganss.XSS var oldStyleEmpty = string.IsNullOrEmpty(tag.GetAttribute("style")); SanitizeStyle(tag, baseUrl); - var checkClasses = AllowedCssClasses != null; - var allowedTags = AllowedCssClasses?.ToArray() ?? Array.Empty(); - // sanitize the value of the attributes foreach (var attribute in tag.Attributes.ToList()) { @@ -689,9 +690,9 @@ namespace Ganss.XSS } else { - if (checkClasses && attribute.Name == "class") + if (AllowedClasses.Any() && attribute.Name == "class") { - var removedClasses = tag.ClassList.Except(allowedTags).ToArray(); + var removedClasses = tag.ClassList.Except(AllowedClasses).ToArray(); foreach (var removedClass in removedClasses) RemoveCssClass(tag, removedClass, RemoveReason.NotAllowedCssClass); diff --git a/src/HtmlSanitizer/IHtmlSanitizer.cs b/src/HtmlSanitizer/IHtmlSanitizer.cs index 4586318..9d0c8f1 100644 --- a/src/HtmlSanitizer/IHtmlSanitizer.cs +++ b/src/HtmlSanitizer/IHtmlSanitizer.cs @@ -91,12 +91,12 @@ namespace Ganss.XSS Regex DisallowCssPropertyValue { get; set; } /// - /// Gets or sets the allowed CSS classes. + /// Gets or sets the allowed CSS classes. If the set is empty, all classes will be allowed. /// /// - /// The allowed CSS classes. + /// The allowed CSS classes. An empty set means all classes are allowed. /// - ISet AllowedCssClasses { get; } + ISet AllowedClasses { get; } /// /// Occurs after sanitizing the document and post processing nodes. diff --git a/test/HtmlSanitizer.Tests/Tests.cs b/test/HtmlSanitizer.Tests/Tests.cs index 2fd731a..b7dbaa9 100644 --- a/test/HtmlSanitizer.Tests/Tests.cs +++ b/test/HtmlSanitizer.Tests/Tests.cs @@ -2548,7 +2548,7 @@ rl(javascript:alert(""foo""))'>"; RemoveReason? reason = null; string removedClass = null; - var s = new HtmlSanitizer(allowedAttributes: new[] { "class" }, allowedCssClasses: new[] { "good" }); + var s = new HtmlSanitizer(allowedAttributes: new[] { "class" }) { AllowedClasses = { "good" } }; s.RemovingCssClass += (sender, args) => { reason = args.Reason; @@ -2567,7 +2567,7 @@ rl(javascript:alert(""foo""))'>"; RemoveReason? reason = null; string attributeName = null; - var s = new HtmlSanitizer(allowedAttributes: new[] { "class" }, allowedCssClasses: new[] { "other" }); + var s = new HtmlSanitizer(allowedAttributes: new[] { "class" }) { AllowedClasses = { "other" } }; s.RemovingAttribute += (sender, args) => { attributeName = args.Attribute.Name; @@ -2942,7 +2942,7 @@ zqy1QY1kkPOuMvKWvvmFIwClI2393jVVcp91eda4+J+fIYDbfJa7RY5YcNrZhTuV//9k=""> [Fact] public void AllowClassesTest() { - var sanitizer = new HtmlSanitizer(allowedAttributes: new[] { "class" }, allowedCssClasses: new[] { "good" }); + var sanitizer = new HtmlSanitizer(allowedAttributes: new[] { "class" }) { AllowedClasses = { "good" } }; var html = @"
Test
"; var actual = sanitizer.Sanitize(html); @@ -2969,22 +2969,10 @@ zqy1QY1kkPOuMvKWvvmFIwClI2393jVVcp91eda4+J+fIYDbfJa7RY5YcNrZhTuV//9k=""> Assert.Equal(@"
Test
", actual); } - [Fact] - public void RemoveClassAttributeIfNoAllowedClassesTest() - { - // Empty array for allowed classes = no classes allowed - var sanitizer = new HtmlSanitizer(allowedAttributes: new[] { "class" }, allowedCssClasses: Array.Empty()); - - var html = @"
Test
"; - var actual = sanitizer.Sanitize(html); - - Assert.Equal(@"
Test
", actual); - } - [Fact] public void RemoveClassAttributeIfEmptyTest() { - var sanitizer = new HtmlSanitizer(allowedAttributes: new[] { "class" }, allowedCssClasses: new[] { "other" }); + var sanitizer = new HtmlSanitizer(allowedAttributes: new[] { "class" }) { AllowedClasses = { "other" } }; var html = @"
Test
"; var actual = sanitizer.Sanitize(html);