StubbleOrg / Stubble

Trimmed down {{mustache}} templates in .NET
Other
399 stars 58 forks source link

System.Security.VerificationException: Operation could destabilize the runtime. #146

Closed janis-veinbergs closed 2 months ago

janis-veinbergs commented 3 months ago

The exception mentioned in title: System.Security.VerificationException: Operation could destabilize the runtime. is thrown when using sections: {{#list}}{{/list}} in a limited execution/sandbox environment as a Dataverse Plugin. Particularly it is thrown when checking SectionBlacklistTypes: https://github.com/StubbleOrg/Stubble/blob/7e5bab6c69d90ab898b84c158969495c0e05bbac/src/Stubble.Core/Renderers/StringRenderer/TokenRenderers/SectionTokenRenderer.cs#L45

And this fixes it: https://github.com/StubbleOrg/Stubble/commit/8c4ef7c3de390792f9e30480168e387ddbf09ca7

This only applies to .NET legacy Framework as CAS policy framework is no more in Core.

Initially I thought it is this issue: https://stackoverflow.com/questions/378895/operation-could-destabilize-the-runtime so I tried to overcome it by not using Linq. But it turns out it is due to how ImmutableHashSet is implemented. I also tried ImmutableArray before deciding Immutables are no-go within low trust environment.

I verified that working with HashSet it succeeds without exceptions.

I know this project couldn't be bothered with limitations particular environments have, however this is lightweight project which doesn't take much to be compatible. I tried Handlebars.NET, but there are severe incompatibilitiies, so just seeing whether it is acceptable for upstream maintainer to change settings from ImmutableHashSet to HashSet... I suspect this breaks public API and probably not something you'd want to do...

What would be your thoughts?

Exception stack trace:

>System.Security.VerificationException: Operation could destabilize the runtime.
>   at System.Collections.Immutable.ImmutableHashSet`1.HashBucket.Enumerator.MoveNext()
>   at System.Collections.Immutable.ImmutableHashSet`1.Enumerator.MoveNext()
>   at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate)
>   at Stubble.Core.Renderers.StringRenderer.TokenRenderers.SectionTokenRenderer.Write(StringRender renderer, SectionToken obj, Context context)
>   at Stubble.Core.Renderers.MustacheTokenRenderer`3.Write(RendererBase`1 renderer, MustacheToken obj, TContext context)
>   at Stubble.Core.Renderers.RendererBase`1.Write[T](T obj, TContext context)
>   at Stubble.Core.Renderers.StringRenderer.TextRendererBase.Render(BlockToken block, Context context)
>   at Stubble.Core.StubbleVisitorRenderer.Render(String template, Object view, IDictionary`2 partials, RenderSettings settings)
>   at Stubble.Core.StubbleVisitorRenderer.Render(String template, Object view)
Romanx commented 3 months ago

Hi there,

Thanks for the writeup. I'd rather not change the public interface on the settings object since it would break people if they were using it.

I've never actually seen this exception before and can't seem to find much detail about what causes it apart from some things to do with [SecurityCritical]. If you've got more context about why HashSet<T> works i'd love to know.

We probably wouldn't change the collection type now but you're welcome to take a soft fork and change the type yourself. The library doesn't change majorly these days so there shouldn't be too much risk.

janis-veinbergs commented 2 months ago

Thank you for your comment. Yes, fork is probably the way to go for me.