flutterfire icon indicating copy to clipboard operation
flutterfire copied to clipboard

🐛 [firebase_core] CSP Violation in Firebase Core

Open ActuallyHappening opened this issue 2 years ago • 15 comments

I am building a flutter app for a chrome extension, which does not allow ANY CSP violations at all (using manifest v3). Recently I integrated firebase firestore, however I would get console errors refusing to execute scripts due to CSP in production builds. This broke the app, which loaded with only a white background.

These were the scripts added: image (I am using firebase_core and cloud_firestore)

These are the console errors: image (Note the 'DIRTY_manual_CSP_fix.js' errors)

DIRTY_manual_CSP_fix.js

My initial thought was 'well, lets add this code manually into a script and execute it myself' since the main.dart.js build obviously depended on window.ff_trigger_firebase_* to properly execute. This is the file mentioned above, but this only kicks the problem upstairs and still violates CSP as it dynamically imports files from 'https://www.gstatic.com/firebasejs/9.9.0/firebase-*' which chrome does not like (errors above)

For reference, my file 'DIRTY_manual_CSP_fix.js is pasted below:

[
  ["firebase_core", "https://www.gstatic.com/firebasejs/9.9.0/firebase-app.js"],
  ["firebase_core", "https://www.gstatic.com/firebasejs/9.9.0/firebase-app.js"],
  ["app_check", "https://www.gstatic.com/firebasejs/9.9.0/firebase-remote-config.js"]
].forEach((b) => {
  window["ff_trigger_" + b[0]] = async (callback) => {
    callback(await import(b[1])); // <-- Errors on this line, line 8
  }; // <-- Some errors on this line, assuming from callback inside main.dart.js? line 9
});

--csp flag for flutter builds

You might be thinking, 'why don't you add the --csp flag when building?' Simply to get anything to work as a chrome extension I have been doing this from the start. To confirm: ALL of these builds are with the --csp flag enabled. The full build command I use it: flutter build web --web-renderer html --csp

Other references:

This is not the first mention of this issue, issue #80221 mentions nearly the exact build finding the same issue and cause:

    The HTML renderer has issues with `style-src: self`:

image This is the code causing the issue: image

When building with --profile the CSP error is caused somewhere in file html_dart2js.dart

Originally posted by @codemasterover9000 in https://github.com/flutter/flutter/issues/80221#issuecomment-922924596

Potential Solution

There is only one solution to using the firebase client library in flutter and a strict CSP policy, which I am forced to do. This is to manually copy the script files and include them in the production bundle, which is possible but not a good nor elegant solution.

Reproduction:

I have added a minimal reproducible repository here: https://github.com/ActuallyHappening/SchoolBoxStyling/tree/master/csp_firebase_bug

I have included the faulty build, with the --csp flag enabled (full build command used flutter build web --csp --web-renderer html). To see error, open chrome://extensions/ (chrome extensions page), turn on dev mode, and select 'load unpacked', choosing the build/web folder. When you click the extensions icon, you should see a white screen. Right click and inspect, view console, and share in my annoyance. The same errors appear.

For reference:

The manifest file I used is pasted below. Note that adding a CSP option is optional, as it is implied.

{
    "manifest_version": 3,
    "version": "1.0",
    "name": "csp_firebase_bug",
    "description": "A new Flutter project.",

    "action": {
        "default_popup": "index.html"
    }
}

My actual manifest includes an explicit "content_security_policy" (CSP) key, pasted below. Removing this does nothing to solve the issue, as chrome implies this anyway. Adding a nonce or extra keys to the 'script-src' or 'object-src' results in chrome not even parsing the manifest when loading the extension.

    "content_security_policy": {
        "extension_pages": "script-src 'self' ; object-src 'self'"
    },

The dart code that triggers the firebase_core plugin to inject its own script DOM nodes seems to be this:

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(const MyApp());
}
// ... boilerplate template code below, using flutter create

In the minimal reproducible example, the console logs and script tags added were: image image (all) image (just scripts)

This is my pubspec.yaml from the example repo. I have 1 extra dependancy, firebase_core, and nothing else:

dependencies:
  flutter:
    sdk: flutter


  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.2
  firebase_core: ^2.1.0

Final thoughts

I would appreciate any insight into solving this problem, and ideally a feature flag for the firebase_core plugin that solves this CSP issue. Flutter is an amazing tool, but I have resorted to using the lower level firebase REST API to load data into my app, using dio and the dio_http_cache packages.

ActuallyHappening avatar Oct 29 '22 06:10 ActuallyHappening