Skip to content

Add the ability to pass a CSP nonce to flutter.js that will be used when loading additional scripts #126977

Closed
flutter-team-archive/engine
#42829

Description

@jacobsimionato

Strict CSPs require that any script tags that are created have a nonce attribute that specifies the same nonce included in the CSP header, to ensure all scripts that are loaded are trusted. Currently, Flutter is only compatible with the weaker strict-dynamic mode.

Flutter loads many scripts dynamically, e.g. flutter.js loads main.dart.js, and main.dart.js loads additional parts. And the engine loads canvaskit etc. It'd be great if the developer could pass flutter.js a nonce, and then Flutter could use that when loading all additional scripts. E.g.

_flutter.loader.loadEntrypoint({
          entrypointUrl: 'my_app/main.dart.js',
          nonce: my_nonce,
          onEntrypointLoaded: function(engineInitializer) {
            engineInitializer.initializeEngine().then(function(appRunner) {
              appRunner.runApp();
            });
          }
        });

It's worth considering if Flutter can automatically find the right nonce to use somehow e.g. there are approaches internally that copy the nonce from other script tags in the DOM. Overall, though, I think adding it as an explicit parameter passed by the app developer seems less likely to cause breakages and confusion.

This is not blocking anyone at the moment, but it likely will eventually when an app that is already using a strict CSP wants to integrate Flutter without accepting a security regression.

See internal bug b/274360267 for more details.

Activity

  1. added
    P2Important issues not at the top of the work list
    on May 18, 2023
  2. ditman commented on Jun 1, 2023

    @ditman
    Member

    This could be a potential fix for a big part of: #80221

  3. self-assigned this
    on Jun 1, 2023
  4. ditman commented on Jun 30, 2023

    @ditman
    Member

    This should be available soon in master!

  5. github-actions commented on Jul 14, 2023

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  6. locked as resolved and limited conversation to collaborators on Jul 14, 2023
  7. jacobsimionato commented on Oct 12, 2023

    @jacobsimionato
    ContributorAuthor

    David, I tried this out, but I got an error where main.dart.js could not be loaded because there is no nonce on that script tag.

    I think perhaps we need to move the nonce parameter to loadEntrypoint rather than initializeEngine because we need it before main.dart is even loaded. See internal change cl/572795063 as an example. This worked for me locally. I'd send a PR, but I'm not sure if there are other places that rely on the current behavior, or if maybe I'm missing something?

  8. ditman commented on Oct 12, 2023

    @ditman
    Member

    @jacobsimionato what's the CSP configuration that we want to support? Currently, it's this:

    script-src 'self' 'nonce-YOUR_NONCE_VALUE' 'wasm-unsafe-eval';
    font-src https://fonts.gstatic.com;
    style-src 'nonce-YOUR_NONCE_VALUE';
    

    Do we want to remove 'self' from script-src?

  9. jacobsimionato commented on Oct 13, 2023

    @jacobsimionato
    ContributorAuthor

    Yeah I think so! I'm struggling to figure out what the implications of that are though. I thought nonces were required for every script tag, regardless of whether 'self' is present here?

    This is the content security policy for the app that is failing:

    Content-Security-Policy: require-trusted-types-for 'script'
    Content-Security-Policy: script-src 'report-sample' 'nonce-YOUR_NONCE_VALUE' 'unsafe-inline' 'unsafe-eval';object-src 'none';base-uri 'self';report-uri
    

    I get the error:

    Refused to load the script 'https://<URL of the app>/web/main.dart.js' because it violates the following Content Security Policy directive: "script-src 'report-sample' 'nonce-HA8EXnECp_fqWPFwvPxA6A' 'unsafe-inline' 'unsafe-eval'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
    
  10. unlocked this conversation on Oct 13, 2023
  11. ditman commented on Oct 20, 2023

    @ditman
    Member

    This is a good proposal, I think I can add a nonce to loadEntrypoint that then gets forwarded automagically to initializeEngine. I think the change should only affect flutter.js, actually!

  12. jacobsimionato commented on Oct 20, 2023

    @jacobsimionato
    ContributorAuthor

    That sounds ideal! Thank you :-D

  13. ditman commented on Oct 25, 2023

    @ditman
    Member

    then gets forwarded automagically to initializeEngine

    I spoke too soon, and the code to achieve this is a big mess. For now, the nonce will need to be set in 2 places :/

  14. github-actions commented on Nov 10, 2023

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  15. locked as resolved and limited conversation to collaborators on Nov 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

P2Important issues not at the top of the work listcustomer: googleVarious Google teamsplatform-webWeb applications specifically

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions