Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blazor Stop Requiring unsafe-inline in CSP #36771

Merged
merged 4 commits into from
Sep 21, 2021
Merged

Conversation

TanayParikh
Copy link
Contributor

@TanayParikh TanayParikh commented Sep 20, 2021

Blazor Server

The innerHtml was triggering the CSP, thereby requiring unsafe-inline. The reconnection logic has been updated to no longer require innerHtml. This is the only place I could see innerHtml being used, aside from the browser renderer, however that doesn't appear to cause an issue as the nodes don't appear to actually be added to the page.

sharedSvgElemForParsing.innerHTML = markup || ' ';
return sharedSvgElemForParsing;
} else {
sharedTemplateElemForParsing.innerHTML = markup || ' ';

Per the Blazor docs

Specify unsafe-inline to allow the use of inline styles. The inline declaration is required for the UI in Blazor Server apps for reconnecting the client and server after the initial request. In a future release, inline styling might be removed so that unsafe-inline is no longer required.

Note, from what I found unsafe-eval doesn't appear to be an issue for Blazor Server (only WASM due to eval utilization in mono).

Validated using:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">

Blazor WASM:

Issue was with the global module script:

scriptElem.text = 'var Module; window.__wasmmodulecallback__(); delete window.__wasmmodulecallback__;';

unsafe-inline can be removed via adding the script hash to the CSP as per below:

Validated using:

    <meta http-equiv="Content-Security-Policy" 
        content="default-src 'self'; img-src https://*; child-src 'none'; script-src 'sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA=' 'self' 'unsafe-eval'">

where sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA= is the hash of the global module script.

Note: unsafe-eval is still required due to a dependency in mono. Currently the instantiate wasm call is failing without it.

compiledInstance = await compileWasmModule(dotnetWasmResource, imports);


Note, unsafe-inline also requires inline js script blocks to either have an associated hash or nonce. This means something like a Blazor.start(...) script would need to be put into a separate file. Not a big deal, just something worth noting.

Fixes: #34428

@TanayParikh TanayParikh requested a review from a team as a code owner September 20, 2021 23:14
@ghost ghost added the area-blazor Includes: Blazor, Razor Components label Sep 20, 2021
@TanayParikh TanayParikh changed the title Blazor Server Allow unsafe-inline Blazor Allow unsafe-inline Sep 21, 2021
@TanayParikh TanayParikh added feature-blazor-server feature-blazor-wasm This issue is related to and / or impacts Blazor WebAssembly labels Sep 21, 2021
@TanayParikh TanayParikh changed the title Blazor Allow unsafe-inline Blazor Stop Requiring unsafe-inline in CSP Sep 21, 2021
@TanayParikh
Copy link
Contributor Author

Note: We'll need to update the docs to reflect this change (todo after merge):

https://docs.microsoft.com/en-us/aspnet/core/blazor/security/content-security-policy?view=aspnetcore-6.0

@TanayParikh
Copy link
Contributor Author

In terms of testing, tried out some local scenarios, and didn't encounter any issues. Grep'd through the codebase to find offending functionality and made the fixes in this PR.

I looked into CSP'ifying the E2E tests, but that looks like a much more involved change (refactoring all the inline JS - or providing hashes, both of which may be cumbersome in terms of maintainability of the tests). Additionally, all the inline css would need to be stripped out of the test files as well. I'm open to exploring this path if people think it's worthwhile, personally I'm not totally sure if it's worth the time investment.

@javiercn
Copy link
Member

@TanayParikh thanks for the thorough investigation.

The fixes for Blazor server look good to me.

Do you think we could get an issue filed on the runtime repo to better understand the need for eval and determine if there are potential alternatives implementations we can take? (BTW, just to be clear, I don't think this is a 6.0 item, but something we want to work towards in 7.0)

As per the unsafe inline, I'm ok if we document this for the time being to make sure folks include the hash in their csp policy.

That said, I think we should consider removing the inline script in 7.0 (not clear how). Can you file a bug to track it?

Copy link
Member

@javiercn javiercn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look good.

@TanayParikh
Copy link
Contributor Author

That said, I think we should consider removing the inline script in 7.0 (not clear how). Can you file a bug to track it?

#36805

Do you think we could get an issue filed on the runtime repo to better understand the need for eval and determine if there are potential alternatives implementations we can take? (BTW, just to be clear, I don't think this is a 6.0 item, but something we want to work towards in 7.0)

dotnet/runtime#59416

@TanayParikh TanayParikh mentioned this pull request Sep 21, 2021
@SteveSandersonMS
Copy link
Member

@TanayParikh This is a great investigation! It's awesome that we now fully understand the gap between where we are and supporting arbitrary CSPs.

I agree with @javiercn that the Server changes look great (with a possible simplification as per comment above).

About the WebAssembly side:

  • Our own use of scriptElem.text could very likely be eliminated. If I remember correctly, it was put there as a workaround for an old Safari bug which probably no longer applies.
  • However, fixing this probably doesn't achieve anything until it becomes possible to call WebAssembly.instantiateStreaming without unsafe-eval. If this truly is an unresolved Chromium limitation, it's out of our direct control to fix.

There's no value in taking the risk of fixing our scriptElem.text code for 6.0 if it doesn't change anything about the option to avoid unsafe-eval. We could do it in main for 7.0 just as a matter of tidiness, but there's no value in bringing that change to release/6.0.

What do you think?

@SteveSandersonMS
Copy link
Member

Actually I don't even know if Chromium does have a problem with WebAssembly.compileStreaming when unsafe-eval is disallowed. Comments at WebAssembly/content-security-policy#7 (comment) suggest the error reports are inconsistent and might be bogus. We'll have to actually try it ourselves. But it sounds like we'd first need the runtime to remove its direct reference to eval anyway.

@SteveSandersonMS SteveSandersonMS self-requested a review September 21, 2021 16:17
@TanayParikh
Copy link
Contributor Author

About the WebAssembly side:

  • Our own use of scriptElem.text could very likely be eliminated. If I remember correctly, it was put there as a workaround for an old Safari bug which probably no longer applies.
  • However, fixing this probably doesn't achieve anything until it becomes possible to call WebAssembly.instantiateStreaming without unsafe-eval. If this truly is an unresolved Chromium limitation, it's out of our direct control to fix.

There's no value in taking the risk of fixing our scriptElem.text code for 6.0 if it doesn't change anything about the option to avoid unsafe-eval. We could do it in main for 7.0 just as a matter of tidiness, but there's no value in bringing that change to release/6.0.

What do you think?

I agree! I've created #36805 to track removing scriptElem.text for 7.0, as well as dotnet/runtime#59416 to request mono reevaluate the usage of eval.

TanayParikh added a commit to dotnet/AspNetCore.Docs that referenced this pull request Sep 21, 2021
Reflects changes in dotnet/aspnetcore#36771 / dotnet/aspnetcore#34428.

Created dotnet/aspnetcore#36805 to track removal of the inline script which requires the `sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA=` hash.
@TanayParikh
Copy link
Contributor Author

Documentation updates: dotnet/AspNetCore.Docs#23365

@TanayParikh TanayParikh enabled auto-merge (squash) September 21, 2021 16:46
@TanayParikh TanayParikh merged commit 2b0e81f into main Sep 21, 2021
@TanayParikh TanayParikh deleted the taparik/allowUnsafeInline branch September 21, 2021 17:41
@ghost ghost added this to the 7.0-preview1 milestone Sep 21, 2021
@TanayParikh
Copy link
Contributor Author

/backport to release/6.0

@github-actions
Copy link
Contributor

Started backporting to release/6.0: https://github.com/dotnet/aspnetcore/actions/runs/1258896840

@github-actions
Copy link
Contributor

@TanayParikh an error occurred while backporting to release/6.0, please check the run log for details!

Error: @TanayParikh is not a repo collaborator, backporting is not allowed.

@TanayParikh
Copy link
Contributor Author

TanayParikh commented Sep 21, 2021

@dotnet/aspnet-build has something changed with the backport bot? Using the same command as before.

Error: @TanayParikh is not a repo collaborator, backporting is not allowed.

Perhaps a new requirement? Do I need to be manually added somewhere?

https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/adding-outside-collaborators-to-repositories-in-your-organization

@github-actions
Copy link
Contributor

Started backporting to release/6.0: https://github.com/dotnet/aspnetcore/actions/runs/1258896840

@github-actions
Copy link
Contributor

@TanayParikh an error occurred while backporting to release/6.0, please check the run log for details!

Error: @TanayParikh is not a repo collaborator, backporting is not allowed.

@TanayParikh
Copy link
Contributor Author

/backport to release/6.0

@github-actions
Copy link
Contributor

Started backporting to release/6.0: https://github.com/dotnet/aspnetcore/actions/runs/1262562948

@github-actions
Copy link
Contributor

@TanayParikh an error occurred while backporting to release/6.0, please check the run log for details!

Error: @TanayParikh is not a repo collaborator, backporting is not allowed.

TanayParikh added a commit that referenced this pull request Sep 22, 2021
* Blazor Server Allow Unsafe Inline

For: #34428

* Update MonoPlatform.ts

* Fix DefaultReconnectDisplay.test

* PR Feedback
wtgodbe pushed a commit that referenced this pull request Sep 22, 2021
)

* Blazor Stop Requiring `unsafe-inline` in CSP (#36771)

* Blazor Server Allow Unsafe Inline

For: #34428

* Update MonoPlatform.ts

* Fix DefaultReconnectDisplay.test

* PR Feedback

* Update blazor.server.js

* Update blazor.server.js
@FelipeCostaGualberto
Copy link

Hi, is this completed?

I'm having security complains in a corporate environment because my Blazor WASM App in .NET 8 doesn't work with wasm-unsafe-eval, only with unsafe-eval.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-blazor Includes: Blazor, Razor Components feature-blazor-server feature-blazor-wasm This issue is related to and / or impacts Blazor WebAssembly
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CSP for Blazor
4 participants