Search code examples
google-chrome-extensioncontent-security-policychrome-extension-manifest-v3

Chrome extension manifest V3 remotely hosted code


In Chrome Extension manifest v3 remotely hosted code is no longer allowed. The migration documentation has two solutions.

Configuration-driven features and logic—In this approach, your extension loads a remote configuration (for example a JSON file) at runtime and caches the configuration locally. The extension then uses this cached configuration to decide which features to enable.

Externalize logic with a remote service—Consider migrating application logic from the extension to a remote web service that your extension can call. (Essentially a form of message passing.) This provides you the ability to keep code private and change the code on demand while avoiding the extra overhead of resubmitting to the Chrome Web Store.

Has anyone seen any samples of these two types of configurations?

At first I was trying to mess with the CSP given this error, but now don't think that is even possible so the error is a bit misleading in the first place.

Refused to load the script 'https://code.jquery.com/jquery-3.5.1.slim.min.js' because it violates the following Content Security Policy directive: "script-src 'self'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.

This is my CSP policy I was trying to get working and now doubtful will work.

    "content_security_policy": {
    "script-src": "'self' 'unsafe-eval' https://unpkg.com https://code.jquery.com https://stackpath.bootstrapcdn.com https://cdn.jsdelivr.net/ https://cdn.datatables.net https://cdnjs.cloudflare.com https://cdn.rawgit.com; object-src 'self'"
},

There is a really good stack overflow thread on this, but it is for manifest v2.

Thanks


Solution

  • I was able to get this working and now the extension doesn't require any external source once it's built. It took a while and there were no answers here so I'm posting my solution here.

    I created this shell script to download the external packages to a folder called third party.

    parts of package.json

      scripts {
            "build_myapp": "npm install && npm run build_prod",
    
            "build_prod": "./getexternalscripts.sh & npm run build_myapp",
    
            "tar2zip": "tarball=$(npm list --depth 0 | sed 's/@/-/g; s/ .*/.tgz/g; 1q;'); tar -tf $tarball | sed 's/^package\\///' | zip -@r package; rm $tarball",
    
            "package": "npm run build_prod && npm pack && npm run tar2zip && mv package.zip myapp-$npm_package_version.zip"
     
        }
    

    getexternalscripts.sh

    #!/bin/bash
    wget -N https://code.jquery.com/jquery-3.5.1.slim.min.js -P ./thirdparty/
    wget -N https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js  -P ./thirdparty/
    wget -N https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js -P ./thirdparty/
    wget -N https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js -P ./thirdparty/
    

    When referencing these in my html files it looks like this

    <head>
        <script src="/thirdparty/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"></script>
        <script src="/thirdparty/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"></script>
        <script src="/thirdparty/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI"></script>
        <script src="/thirdparty/axios.min.js"></script>
    </head>