OWASP.AntiSamy mXSS when preserving comments
Description
OWASP AntiSamy .NET is a library for performing cleansing of HTML coming from untrusted sources. Prior to version 1.2.0, there is a potential for a mutation cross-site scripting (mXSS) vulnerability in AntiSamy caused by flawed parsing of the HTML being sanitized. To be subject to this vulnerability the preserveComments directive must be enabled in your policy file and also allow for certain tags at the same time. As a result, certain crafty inputs can result in elements in comment tags being interpreted as executable when using AntiSamy's sanitized output. This is patched in OWASP AntiSamy .NET 1.2.0 and later. See important remediation details in the reference given below. As a workaround, manually edit the AntiSamy policy file (e.g., antisamy.xml) by deleting the preserveComments directive or setting its value to false, if present. Also it would be useful to make AntiSamy remove the noscript tag by adding a line described in the GitHub Security Advisory to the tag definitions under the <tagrules> node, or deleting it entirely if present. As the previously mentioned policy settings are preconditions for the mXSS attack to work, changing them as recommended should be sufficient to protect you against this vulnerability when using a vulnerable version of this library. However, the existing bug would still be present in AntiSamy or its parser dependency (HtmlAgilityPack). The safety of this workaround relies on configurations that may change in the future and don't address the root cause of the vulnerability. As such, it is strongly recommended to upgrade to a fixed version of AntiSamy.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
OWASP.AntiSamyNuGet | < 1.2.0 | 1.2.0 |
Affected products
1- Range: < 1.2.0
Patches
28117911933e7Merge pull request #12 from spassarop/develop
42 files changed · +156 −86
.github/workflows/codeql-analysis.yml+6 −11 modified@@ -57,7 +57,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -66,21 +66,16 @@ jobs: # queries: ./path/to/local/query, your-org/your-repo/queries@main # This prevents errors when automatically installing SDK. - # CodeQL does not install .NET 5.0 nor 6.0. - - name: Setup .NET 5.0 SDK+Runtime + # CodeQL does not install .NET 8.0. + - name: Setup .NET 8.0 SDK+Runtime uses: actions/setup-dotnet@v1.7.2 with: - dotnet-version: 5.0.404 - - - name: Setup .NET 6.0 SDK+Runtime - uses: actions/setup-dotnet@v1.7.2 - with: - dotnet-version: 6.0.101 + dotnet-version: 8.0.100 # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v1 + uses: github/codeql-action/autobuild@v2 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -94,4 +89,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2
.github/workflows/netcore_and_netframework.yml+2 −12 modified@@ -40,20 +40,10 @@ jobs: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v2 - - name: Setup .NET Core SDK+Runtime + - name: Setup .NET 8.0 SDK+Runtime uses: actions/setup-dotnet@v1.7.2 with: - dotnet-version: 3.1.x - - - name: Setup .NET 5.0 SDK+Runtime - uses: actions/setup-dotnet@v1.7.2 - with: - dotnet-version: 5.0.404 - - - name: Setup .NET 6.0 SDK+Runtime - uses: actions/setup-dotnet@v1.7.2 - with: - dotnet-version: 6.0.101 + dotnet-version: 8.0.100 - name: Setup MSBuild for .NET Framework uses: microsoft/setup-msbuild@v1
LICENSE+1 −1 modified@@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2022, spassarop +Copyright (c) 2023, spassarop All rights reserved. Redistribution and use in source and binary forms, with or without
OWASP.AntiSamy/AntiSamyPolicyExamples/antisamy-anythinggoes.xml+1 −1 modified@@ -41,7 +41,7 @@ http://www.w3.org/TR/html401/struct/global.html <regexp name="anything" value=".*"/> <regexp name="numberOrPercent" value="(\d)+(%{0,1})"/> - <regexp name="paragraph" value="([\p{L}\p{N},'\.\s\-_\(\)]|&[0-9]{2};)*"/> + <regexp name="paragraph" value="[\p{L}\p{N},'.\s\-_\(\)&;]*"/> <regexp name="htmlId" value="[a-zA-Z0-9\:\-_\.]+"/> <regexp name="htmlTitle" value="[\p{L}\p{N}\s\-_',:\[\]!\./\\\(\)&]*"/> <!-- force non-empty with a '+' at the end instead of '*' --> <regexp name="htmlClass" value="[a-zA-Z0-9\s,\-_]+"/>
OWASP.AntiSamy/AntiSamyPolicyExamples/antisamy-ebay.xml+1 −1 modified@@ -39,7 +39,7 @@ http://www.w3.org/TR/html401/struct/global.html <regexp name="anything" value=".*"/> <regexp name="numberOrPercent" value="(\d)+(%{0,1})"/> - <regexp name="paragraph" value="([\p{L}\p{N},'\.\s\-_\(\)]|&[0-9]{2};)*"/> + <regexp name="paragraph" value="[\p{L}\p{N},'.\s\-_\(\)&;]*"/> <regexp name="htmlId" value="[a-zA-Z0-9\:\-_\.]+"/> <regexp name="htmlTitle" value="[\p{L}\p{N}\s\-_',:\[\]!\./\\\(\)&]*"/> <!-- force non-empty with a '+' at the end instead of '*' --> <regexp name="htmlClass" value="[a-zA-Z0-9\s,\-_]+"/>
OWASP.AntiSamy/AntiSamyPolicyExamples/antisamy-myspace.xml+1 −1 modified@@ -41,7 +41,7 @@ http://www.w3.org/TR/html401/struct/global.html <regexp name="anything" value=".*"/> <regexp name="numberOrPercent" value="(\d)+(%{0,1})"/> - <regexp name="paragraph" value="([\p{L}\p{N},'\.\s\-_\(\)]|&[0-9]{2};)*"/> + <regexp name="paragraph" value="[\p{L}\p{N},'.\s\-_\(\)&;]*"/> <regexp name="htmlId" value="[a-zA-Z0-9\:\-_\.]+"/> <regexp name="htmlTitle" value="[\p{L}\p{N}\s\-_',:\[\]!\./\\\(\)&]*"/> <!-- force non-empty with a '+' at the end instead of '*' --> <regexp name="htmlClass" value="[a-zA-Z0-9\s,\-_]+"/>
OWASP.AntiSamy/AntiSamyPolicyExamples/antisamy.xml+1 −1 modified@@ -44,7 +44,7 @@ http://www.w3.org/TR/html401/struct/global.html <regexp name="anything" value=".*"/> <regexp name="numberOrPercent" value="(\d)+(%{0,1})"/> - <regexp name="paragraph" value="([\p{L}\p{N},'\.\s\-_\(\)]|&[0-9]{2};)*"/> + <regexp name="paragraph" value="[\p{L}\p{N},'.\s\-_\(\)&;]*"/> <regexp name="htmlId" value="[a-zA-Z0-9\:\-_\.]+"/> <regexp name="htmlTitle" value="[\p{L}\p{N}\s\-_',:\[\]!\./\\\(\)&]*"/> <!-- force non-empty with a '+' at the end instead of '*' -->
OWASP.AntiSamy/Css/CssScanner.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Jerry Hoff, Caner Patir, Sebasti�n Passaro + * Copyright (c) 2023, Jerry Hoff, Caner Patir, Sebastián Passaro * * * All rights reserved.
OWASP.AntiSamy/Exceptions/ParseException.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Caner Patir, Sebasti�n Passaro + * Copyright (c) 2023, Caner Patir, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamy/Exceptions/PolicyException.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2022, Jerry Hoff, Sebasti�n Passaro + * Copyright (c) 2008-2023, Jerry Hoff, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamy/Exceptions/ScanException.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2022, Jerry Hoff, Sebasti�n Passaro + * Copyright (c) 2008-2023, Jerry Hoff, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamy/Exceptions/UnknownSelectorException.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2022, Sebastián Passaro + * Copyright (c) 2009-2023, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamy/Html/AntiSamy.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2022, Jerry Hoff, Sebasti�n Passaro + * Copyright (c) 2008-2023, Jerry Hoff, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamy/Html/CleanResults.cs+38 −9 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2022, Jerry Hoff, Sebasti�n Passaro + * Copyright (c) 2008-2023, Jerry Hoff, Sebastián Passaro * * All rights reserved. * @@ -29,11 +29,31 @@ namespace OWASP.AntiSamy.Html { /// <summary> - /// This class contains the results of a scan. - /// - /// The list of error messages (<see cref="GetErrorMessages"/>) will let the user know - /// what, if any HTML errors existed, and what, if any, security or - /// validation-related errors existed, and what was done about them. + /// This class contains the results of a scan. It primarily provides access to the clean sanitized + /// HTML, per the AntiSamy sanitization policy applied. It also provides access to some utility + /// information, like possible error messages and error message counts. + /// + /// <para>WARNING: The ONLY output from the class you can completely rely on is the CleanResults output. + /// As stated in the documentation, neither the <see cref="GetErrorMessages"/> nor the <see cref="GetNumberOfErrors"/> methods + /// subtly answer the question "is this safe input?" in the affirmative if it returns an empty list. + /// You must always use the sanitized 'Clean' input and there is no way to be sure the input passed in had no attacks. + /// </para> + /// + /// <para>The serialization and deserialization process that is critical to the effectiveness of the + /// sanitizer is purposefully lossy and will filter out attacks via a number of attack vectors. + /// Unfortunately, one of the tradeoffs of this strategy is that AntiSamy doesn't always know in + /// retrospect that an attack was seen. Thus, the <see cref="GetErrorMessages"/> API is there to help users + /// understand whether their well-intentioned input meets the requirements of the system, not help a + /// developer detect if an attack was present. + /// </para> + /// + /// <para>The list of error messages (<see cref="errorMessages"/>) will let the user know what, if any + /// HTML errors existed, and what, if any, security or validation-related errors were detected, and + /// what was done about them. NOTE: As just stated, the absence of error messages does NOT mean there + /// were no attacks in the input that was sanitized out. You CANNOT rely on the <see cref="errorMessages"/> to tell + /// you if the input was dangerous. You MUST use the output of <see cref="GetCleanHtml"/> to ensure your output + /// is safe. + /// </para> /// </summary> public class CleanResults { @@ -74,11 +94,17 @@ public CleanResults(DateTime startOfScan, DateTime endOfScan, string cleanHTML, /// <param name="cleanHtml"></param> public void SetCleanHtml(string cleanHtml) => this.cleanHtml = cleanHtml; - /// <summary> Return the filtered HTML as a string.</summary> + /// <summary> + /// Return the filtered HTML as a string. This output is the ONLY output you can trust to be safe. + /// The absence of error messages does NOT indicate the input was safe. + /// </summary> /// <returns> A string object which contains the serialized, safe HTML.</returns> public string GetCleanHtml() => cleanHtml; - /// <summary> Return a list of error messages.</summary> + /// <summary> + /// Return a list of error messages -- but an empty list returned does not mean there was no attack + /// present, due to the serialization and deserialization process automatically cleaning up some attacks. + /// </summary> /// <returns> A <see cref="List{String}"/> object which contains the error messages after a scan.</returns> public List<string> GetErrorMessages() => errorMessages; @@ -98,7 +124,10 @@ public CleanResults(DateTime startOfScan, DateTime endOfScan, string cleanHTML, /// <param name="msg">An error message to append to the list of aggregate error messages during filtering.</param> public void AddErrorMessage(string msg) => errorMessages.Add(msg); - /// <summary> Return the number of errors encountered during filtering.</summary> + /// <summary> + /// Return the number of errors encountered during filtering. Note that 0 errors does NOT + /// mean the input was safe. Only the output of <see cref="GetCleanHtml"/> can be considered safe. + /// </summary> public int GetNumberOfErrors() => errorMessages.Count; } }
OWASP.AntiSamy/Html/InternalPolicy.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2022, Kristian Rosenvold, Sebasti�n Passaro + * Copyright (c) 2008-2023, Kristian Rosenvold, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamy/Html/Model/AntiSamyPattern.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2022, Jerry Hoff, Sebasti�n Passaro + * Copyright (c) 2008-2023, Jerry Hoff, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamy/Html/Model/Attribute.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2022, Jerry Hoff, Sebasti�n Passaro + * Copyright (c) 2008-2023, Jerry Hoff, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamy/Html/Model/Property.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2022, Jerry Hoff, Sebasti�n Passaro + * Copyright (c) 2008-2023, Jerry Hoff, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamy/Html/Model/Tag.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2022, Jerry Hoff, Sebasti�n Passaro + * Copyright (c) 2008-2023, Jerry Hoff, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamy/Html/ParseContext.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2022, Arshan Dabirsiaghi, Jason Li, Kristian Rosenvold, Sebasti�n Passaro + * Copyright (c) 2007-2023, Arshan Dabirsiaghi, Jason Li, Kristian Rosenvold, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamy/Html/Policy.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2022, Jerry Hoff, Sebastián Passaro + * Copyright (c) 2008-2023, Jerry Hoff, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamy/Html/Scan/AntiSamyDomScanner.cs+11 −2 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2022, Jerry Hoff, Sebasti�n Passaro + * Copyright (c) 2009-2023, Jerry Hoff, Sebastián Passaro * * All rights reserved. * @@ -136,7 +136,7 @@ public CleanResults Scan(string html) // All the cleaned HTML string finalCleanHTML = Policy.PreservesSpace ? htmlDocument.DocumentNode.InnerHtml : htmlDocument.DocumentNode.InnerHtml.Trim(); - + // Encode special/international characters if stated by policy if (Policy.EntityEncodesInternationalCharacters) { @@ -371,6 +371,15 @@ private void ValidateTag(HtmlNode node, HtmlNode parentNode, string tagName, Tag return; } + /* + * Parse every <noscript> node content as plain text by replacing its content with its transformation. + * Covers a case when preserving comments and how the underlying parser works, where a bug arises. + */ + if (tagName.ToLowerInvariant() == "noscript" && Policy.PreservesComments) + { + node.ParentNode.ReplaceChild(parentNode.OwnerDocument.CreateTextNode(node.InnerText), node); + } + /* * Go through the attributes in the tainted tag and validate them against the values we have for them. * If we don't have a rule for the attribute we remove the attribute.
OWASP.AntiSamy/Html/Scan/Constants.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2022, Jerry Hoff, Sebastián Passaro + * Copyright (c) 2008-2023, Jerry Hoff, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamy/Html/TagMatcher.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2022, Kristian Rosenvold, Sebasti�n Passaro + * Copyright (c) 2013-2023, Kristian Rosenvold, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamy/Html/Util/DictionaryExtensions.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Sebasti�n Passaro + * Copyright (c) 2023, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamy/Html/Util/ErrorMessageUtil.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Sebasti�n Passaro + * Copyright (c) 2023, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamy/Html/Util/HtmlEntityEncoder.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2022, Jerry Hoff, Sebasti�n Passaro + * Copyright (c) 2008-2023, Jerry Hoff, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamy/Html/Util/PolicyParserUtil.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2022, Arshan Dabirsiaghi, Jason Li, Kristian Rosenvold, Sebasti�n Passaro + * Copyright (c) 2008-2023, Arshan Dabirsiaghi, Jason Li, Kristian Rosenvold, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamy/Html/Util/SpecialCharactersEncoder.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Sebasti�n Passaro + * Copyright (c) 2023, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamy/Html/Util/XmlUtil.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2022, Jerry Hoff, Sebasti�n Passaro + * Copyright (c) 2008-2023, Jerry Hoff, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamy/OWASP.AntiSamy.csproj+7 −14 modified@@ -1,6 +1,6 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFrameworks>net6.0;net5.0;netstandard2.0;netcoreapp3.1;net46</TargetFrameworks> + <TargetFrameworks>netstandard2.0;net8.0;net48</TargetFrameworks> <StartupObject></StartupObject> <OldToolsVersion>3.5</OldToolsVersion> <GenerateAssemblyInfo>false</GenerateAssemblyInfo> @@ -11,26 +11,18 @@ <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> <Authors>spassaro</Authors> <PackageLicenseExpression>BSD-3-Clause</PackageLicenseExpression> - <Copyright>Copyright © 2022 - Arshan Dabirsiaghi, Sebastián Passaro</Copyright> + <Copyright>Copyright © 2023 - Arshan Dabirsiaghi, Sebastián Passaro</Copyright> <Description>A library for performing fast, configurable cleansing of HTML coming from untrusted sources. Another way of saying that could be: It's an API that helps you make sure that clients don't supply malicious cargo code in the HTML they supply for their profile, comments, etc., that get persisted on the server. The term "malicious code" in regard to web applications usually mean "JavaScript." Mostly, Cascading Stylesheets are only considered malicious when they invoke JavaScript. However, there are many situations where "normal" HTML and CSS can be used in a malicious manner.</Description> <Title>OWASP.AntiSamy</Title> <GenerateDocumentationFile>true</GenerateDocumentationFile> + <PackageReadmeFile>README.md</PackageReadmeFile> </PropertyGroup> - <PropertyGroup Condition=" '$(TargetFramework)' == 'net5.0'"> - <DefineConstants>NET5_0</DefineConstants> - </PropertyGroup> - <ItemGroup> - <PackageReference Include="AngleSharp" Version="0.16.1" /> - <PackageReference Include="AngleSharp.Css" Version="0.16.4" /> - <PackageReference Include="HtmlAgilityPack" Version="1.11.42" /> - </ItemGroup> <ItemGroup> - <!-- Added so NuGet copies this folder to the output package --> - <Content Include="AntiSamyPolicyExamples\**\*"> - <CopyToPublishDirectory>true</CopyToPublishDirectory> - </Content> + <PackageReference Include="AngleSharp" Version="0.17.1" /> + <PackageReference Include="AngleSharp.Css" Version="0.17.0" /> + <PackageReference Include="HtmlAgilityPack" Version="1.11.55" /> </ItemGroup> <ItemGroup> <None Update="AntiSamyPolicyExamples\antisamy-anythinggoes.xml"> @@ -57,6 +49,7 @@ Another way of saying that could be: It's an API that helps you make sure that c <None Update="AntiSamyPolicyExamples\antisamy.xsd"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> + <None Include="..\README.md" Pack="true" PackagePath="\"/> </ItemGroup> <ItemGroup> <Compile Update="Properties\Resources.Designer.cs">
OWASP.AntiSamy/Properties/AssemblyInfo.cs+1 −1 modified@@ -11,7 +11,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("spassaro")] [assembly: AssemblyProduct("AntiSamy")] -[assembly: AssemblyCopyright("Copyright © 2022 - Arshan Dabirsiaghi, Sebastián Passaro")] +[assembly: AssemblyCopyright("Copyright © 2023 - Arshan Dabirsiaghi, Sebastián Passaro")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")]
OWASP.AntiSamyTests/Html/AntiSamyTest.cs+53 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2022, Arshan Dabirsiaghi, Sebastián Passaro + * Copyright (c) 2009-2023, Arshan Dabirsiaghi, Sebastián Passaro * * All rights reserved. * @@ -903,6 +903,10 @@ public void TestSmuggledTagsInStyleContent() .Should().NotContain("script"); antisamy.Scan("<select<style/>k<input<</>input/onfocus=alert(1)>", policy).GetCleanHtml() .Should().NotContain("input"); + antisamy.Scan("<style/><listing/>]]><noembed></style><img src=x onerror=mxss(1)></noembed>", policy).GetCleanHtml() + .Should().NotContain("mxss"); + antisamy.Scan("<style/><math>'<noframes ></style><img src=x onerror=mxss(1)></noframes>'", policy).GetCleanHtml() + .Should().NotContain("mxss"); } [Test] @@ -930,5 +934,53 @@ public void TestMalformedPIScan() } result.Should().NotBeNull(); } + + [Test] + [Ignore("Not passing. To correct in the future if there is a complain or easy fix.")] + public void TestQuotesInsideStyles() + { + string input = "<span style=\"font-family: 'comic sans ms', sans-serif; color: #ba372a;\">Text</span>"; + antisamy.Scan(input, policy).GetCleanHtml().Should().ContainAll("'comic sans ms'", "\"font-family"); + + input = "<span style='font-family: \"comic sans ms\", sans-serif; color: #ba372a;'>Text</span>"; + antisamy.Scan(input, policy).GetCleanHtml().Should().ContainAll("'comic sans ms'", "\"font-family"); + } + + [Test] + public void TestRawTextProcessingWhenPreservingComments() + { + var tag = new Tag("xmp", Constants.ACTION_VALIDATE, new Dictionary<string, Attribute>()); + Policy revised = policy.MutateTag(tag).CloneWithDirective(Constants.PRESERVE_COMMENTS, "true"); + + antisamy.Scan("<noscript><!--</noscript><img src=x onerror=mxss(1)>-->", revised) + .GetCleanHtml().Should().NotContain("mxss"); + antisamy.Scan("<textarea/><!--</textarea><img src=x onerror=mxss(1)>-->", revised) + .GetCleanHtml().Should().NotContain("mxss"); + antisamy.Scan("<xmp/><!--</xmp><img src=x onerror=mxss(1)>-->", revised) + .GetCleanHtml().Should().Be("<!--</xmp><img src=x onerror=mxss(1)>-->"); + antisamy.Scan("<!--<div/>--><img src=x onerror=mxss(1)> <li>--></p><input/>", revised) + .GetCleanHtml().Should().NotContain("mxss"); + } + + [Test] + public void TestRegexStackOverflow() + { + string result = null; + try + { + string input = "<img border=\"0\" width=\"320\" height=\"200\" style=\"width:3.368in;height:2.0486in\" id=\"id_123\" src=\"/url/uri\" alt=\""; + for (int i = 0; i < 2500; i++) + { + input += "SampleText "; + } + input += "!\\\">"; + result = antisamy.Scan(input, policy).GetCleanHtml(); + } + catch + { + // To comply with try/catch + } + result.Should().NotBeNull(); + } } }
OWASP.AntiSamyTests/Html/LiteralTest.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2022, Arshan Dabirsiaghi, Sebastián Passaro + * Copyright (c) 2009-2023, Arshan Dabirsiaghi, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamyTests/Html/LocalizationTest.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Sebastián Passaro + * Copyright (c) 2023, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamyTests/Html/Model/TagTest.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2022, Kristian Rosenvold, Sebastián Passaro + * Copyright (c) 2013-2023, Kristian Rosenvold, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamyTests/Html/PolicyTest.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2022, Arshan Dabirsiaghi, Sebastián Passaro + * Copyright (c) 2009-2023, Arshan Dabirsiaghi, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamyTests/Html/TagMatcherTest.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2022, Kristian Rosenvold, Sebastián Passaro + * Copyright (c) 2013-2023, Kristian Rosenvold, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamyTests/OWASP.AntiSamyTests.csproj+3 −3 modified@@ -1,9 +1,9 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFrameworks>net6.0;net5.0;netcoreapp3.1;net46</TargetFrameworks> + <TargetFrameworks>net8.0;net48</TargetFrameworks> <IsPackable>false</IsPackable> - <Copyright>Copyright © 2022 - Arshan Dabirsiaghi, Sebastián Passaro</Copyright> + <Copyright>Copyright © 2023 - Arshan Dabirsiaghi, Sebastián Passaro</Copyright> <PackageLicenseExpression>BSD-3-Clause</PackageLicenseExpression> <Description>Tests project for OWASP AntiSamy .NET.</Description> </PropertyGroup> @@ -34,7 +34,7 @@ <ItemGroup> <PackageReference Include="FluentAssertions" Version="5.10.3" /> <PackageReference Include="nunit" Version="3.13.2" /> - <PackageReference Include="NUnit3TestAdapter" Version="4.2.1" /> + <PackageReference Include="NUnit3TestAdapter" Version="4.3.2" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" /> </ItemGroup>
OWASP.AntiSamyTests/TestConstants.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Sebastián Passaro + * Copyright (c) 2023, Sebastián Passaro * * All rights reserved. *
OWASP.AntiSamyTests/TestPolicy.cs+1 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Sebastián Passaro + * Copyright (c) 2023, Sebastián Passaro * * All rights reserved. *
README.md+2 −0 modified@@ -12,6 +12,8 @@ This project will be trying to be in sync with the original Java version, its re Check the [wiki](https://github.com/spassarop/antisamy-dotnet/wiki) for information on how to use, build, test and more. +**Important note**: Since 1.2.0 the example policy files that were previously included in the NuGet package are removed. Each developer/deployer must manually place a policy in a location of their choice. For mor information about policies, refer to the wiki mentioned above. + ## Contributing to OWASP AntiSamy .NET ### Found an issue?
7e500daef6adAdd more tests for mXSS
1 file changed · +4 −0
OWASP.AntiSamyTests/Html/AntiSamyTest.cs+4 −0 modified@@ -903,6 +903,10 @@ public void TestSmuggledTagsInStyleContent() .Should().NotContain("script"); antisamy.Scan("<select<style/>k<input<</>input/onfocus=alert(1)>", policy).GetCleanHtml() .Should().NotContain("input"); + antisamy.Scan("<style/><listing/>]]><noembed></style><img src=x onerror=mxss(1)></noembed>", policy).GetCleanHtml() + .Should().NotContain("mxss"); + antisamy.Scan("<style/><math>'<noframes ></style><img src=x onerror=mxss(1)></noframes>'", policy).GetCleanHtml() + .Should().NotContain("mxss"); } [Test]
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-8x6f-956f-q43wghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-51652ghsaADVISORY
- github.com/spassarop/antisamy-dotnet/commit/7e500daef6ad9c10e97c68feab78f4cb6e3083c6ghsax_refsource_MISCWEB
- github.com/spassarop/antisamy-dotnet/commit/8117911933e75a25cd0054ef017577486338444aghsax_refsource_MISCWEB
- github.com/spassarop/antisamy-dotnet/security/advisories/GHSA-8x6f-956f-q43wghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.