mrpmorris / Fluxor

Fluxor is a zero boilerplate Flux/Redux library for Microsoft .NET and Blazor.
MIT License
1.22k stars 139 forks source link

Fluxor.Blazor.Web.ReduxDevTools requires script-src 'unsafe-eval' on CSP #466

Closed christianzingg closed 3 months ago

christianzingg commented 5 months ago

With .NET 8 Blazor WebAssembly no longer requires script-src 'unsafe-eval' on CSP (see https://learn.microsoft.com/en-us/aspnet/core/blazor/security/content-security-policy?view=aspnetcore-8.0#client-side-blazor-apps)

After changing the CSP to the .NET 8 recommendation our blazor app throws an exception because Fluxor.Blazor.Web.ReduxDevTools requires 'unsafe-eval'. Removing Fluxor.Blazor.Web.ReduxDevTools from our project and only using Fluxor.Blazor.Web solved the issue.

It there a reason why 'unsafe-eval' is required for Fluxor.Blazor.Web.ReduxDevTools?

For completeness there is the console exception output:

blazor.webassembly.js:1 crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: JavaScript error
Fluxor.Exceptions.StoreInitializationException: JavaScript error
 ---> Microsoft.JSInterop.JSException: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' 'wasm-unsafe-eval'".

EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' 'wasm-unsafe-eval'".

    at eval (<anonymous>)
    at https://localhost:7294/_framework/blazor.webassembly.js:1:2878
    at new Promise (<anonymous>)
    at b.beginInvokeJSFromDotNet (https://localhost:7294/_framework/blazor.webassembly.js:1:2835)
    at Object.gn [as invokeJSJson] (https://localhost:7294/_framework/blazor.webassembly.js:1:58889)
    at https://localhost:7294/_framework/dotnet.runtime.8.0.1.rswtxkdyko.js:3:177853
    at Ul (https://localhost:7294/_framework/dotnet.runtime.8.0.1.rswtxkdyko.js:3:178687)
    at wasm://wasm/00b1ee2e:wasm-function[350]:0x1faef
    at wasm://wasm/00b1ee2e:wasm-function[246]:0x1bf8c
    at wasm://wasm/00b1ee2e:wasm-function[239]:0xf173
   at Microsoft.JSInterop.JSRuntime.<InvokeAsync>d__16`1[[Microsoft.JSInterop.Infrastructure.IJSVoidResult, Microsoft.JSInterop, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].MoveNext()
   at Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(IJSRuntime jsRuntime, String identifier, Object[] args)
   at Fluxor.Blazor.Web.StoreInitializer.OnAfterRenderAsync(Boolean firstRender) in C:\Data\Mine\Code\Fluxor\Source\Lib\Fluxor.Blazor.Web\StoreInitializer.cs:line 74
   --- End of inner exception stack trace ---
   at Fluxor.Blazor.Web.StoreInitializer.OnAfterRenderAsync(Boolean firstRender) in C:\Data\Mine\Code\Fluxor\Source\Lib\Fluxor.Blazor.Web\StoreInitializer.cs:line 81
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
mrpmorris commented 3 months ago

Fluxor middlewares can specify their own scripts to include during the initialisation phase. These won't be invoked by the browser if injected as source, so I have to call Eval() to execute the generated scripts.

You should only use the devtools in development. Can you make the unsafe-eval conditional?