mganss / HtmlSanitizer

Cleans HTML to avoid XSS attacks
MIT License
1.51k stars 198 forks source link

AngleSharp dependency issue in .NET Framework (IIS-hosted WCF service) #544

Closed qwerty-debug closed 1 month ago

qwerty-debug commented 2 months ago

I installed HtmlSaniziter 8.0.865 (+ dependencies) from NuGet. Running my project locally in debug mode works fine, but when publishing to a server I run into the following issue:

System.TypeInitializationException: The type initializer for 'Ganss.Xss.HtmlSanitizer' threw an exception. ---> System.IO.FileLoadException: Could not load file or assembly 'AngleSharp, Version=0.17.0.0, Culture=neutral, PublicKeyToken=e83494dcdc6d31ea' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) at Ganss.Xss.HtmlSanitizer..cctor() --- End of inner exception stack trace ---

note:

After some experimenting I found a workaround: if I download HtmlSanitizer 8.0.865, AngleSharp 0.17.1 and AngleSharp.Css 0.17.0 from GitHub and then build from source everything works.

mganss commented 2 months ago

Have you checked for https://github.com/mganss/HtmlSanitizer/issues/528#issuecomment-1939621500?

qwerty-debug commented 2 months ago

Yes. As mentioned above I tried your suggestion from https://github.com/mganss/HtmlSanitizer/issues/528 , but it didn't work.

mganss commented 2 months ago

I meant the binding redirect fix that worked for @Chmielinski.

qwerty-debug commented 2 months ago

Not sure I follow...

@Chmielinski mentions the issue being caused by an out-of-date binding redirect for AngleSharp. I assume he simply removed the binding redirect and cleared his build folders to fix the issue.

My project does not have any binding redirect, and until last week I had no dependency on HtmlSanitizer, AngleSharp or AngleSharp.Css.

mganss commented 2 months ago

Perhaps you can try Fuslogvw to debug the issue.

qwerty-debug commented 2 months ago

AngleSharp, Version=0.17.0.0, Culture=neutral, PublicKeyToken=e83494dcdc6d31ea.HTM.txt AngleSharp, Version=0.17.1.0, Culture=neutral, PublicKeyToken=e83494dcdc6d31ea.HTM.txt

Looks like the root issue is in (the .NET framework build of) AngleSharp.CSS.

mganss commented 1 month ago

I think you'll need a binding redirect. AngleSharp.Css 0.17.0 references AngleSharp 0.17.0 while the latest HtmlSanitizer references AngleSharp 0.17.1. In .NET Framework 4.5.1 and later binding redirects should be created automatically.

See https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/redirect-assembly-versions and https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/how-to-enable-and-disable-automatic-binding-redirection#enable-automatic-binding-redirects-in-web-apps

When you create a net48 desktop application, the following gets automatically added to the App.config when adding the HtmlSanitizer NuGet package:

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="AngleSharp" publicKeyToken="e83494dcdc6d31ea" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-0.17.1.0" newVersion="0.17.1.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>
qwerty-debug commented 1 month ago

Looks like App.config of the WCF service project does indeed have an (automatically added) binding redirect for AngleSharp, but the Web.config of the website hosting the WCF service does not.

Copying over the binding redirect from App.config to Web.config solves the issue.

Thanks for your time.

tibx commented 1 month ago

We have the same problem when using the HtmlSanitizer library which references the AngleSharp 0.17.1 and AngleSharp.Css 0.17.0 libraries. However, the AngleSharp.Css 0.17.0 library subsequently references the AngleSharp 0.17.0 library, which is absent in the application directory. The application directory contains the AngleSharp version 0.17.1 library instead.

Binding redirects in the .config file cannot be used, as HtmlSanitizer is not used in a standalone application, but as part of a DevOps Pipeline process with dynamically created types at multiple levels using reflection. The chain of references is as follows:

Microsoft DevOps Server Release Pipeline >

  > Pipeline Task A (PowerShell) New-Object B.dll.BClass.BMethod() >
    (1. reflection from PowerShell -> .NET Framework and dynamic type load)

    > B.dll.BClass.BMethod (.NET Framework) Assembly.LoadFrom(C.dll).CreateInstance(CClass).GetMethod(CMethod).Invoke() >
      (2. reflection from .NET Framework -> .NET Framework and dynamic type load)

      > C.dll.CClass.CMethod (.NET Framework) Assembly.LoadFrom(D.dll).CreateInstance(DClass).GetMethod(DMethod).Invoke() >
        (3. reflection from .NET Framework -> .NET Framework and dynamic type load)

        > D.dll.DClass.DMethod (.NET Framework)
---> HtmlSanitizer => FileNotFoundException [Could not load file or assembly 'AngleSharp, Version=0.17.0.0, Culture=neutral, PublicKeyToken=e83494dcdc6d31ea' or one of its dependencies. The system cannot find the file specified.]
          D.dll -> references HtmlSanitizer 8.0.865 -> references !!!AngleSharp 0.17.1 AND AngleSharp.Css 0.17.0 -> references !!!AngleSharp 0.17.0