clerk/javascript

Cloudflare Turnstile Incompatible with Manifest v3 (MV3) (aka Blue Argon Error)

Opened this issue · 12 comments

Preliminary Checks

The Chrome Web Store Rejection:

CleanShot 2024-11-03 at 16 11 05@2x

Reproduction

https://github.com/clerk/clerk-chrome-extension-starter

Publishable key

pk_test_YmFsYW5jZWQtbW9sbHktODMuY2xlcmsuYWNjb3VudHMuZGV2JA

Description

Steps to reproduce:

  1. Clone the chrome-extension-starter repo
  2. Install packages with npm i
  3. Build the extension code with npm run build
  4. Check out the /build directory's output. It contains remotely executed code ...https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit..., which is a violation of the Chrome Web Store policies.

Expected behavior:

Building a chrome extension with @clerk/chrome-extension should yield code acceptable to the Chrome Web Store so that the extension may become public.

Actual behavior:

Building a chrome extension with @clerk/chrome-extension yields code unacceptable to the Chrome Web Store and any chrome extensions published with it will get rejected by the Chrome Web Store.

Other thoughts

This affects both 0.x and 1.x versions of @clerk/chrome-extension due to their dependency on @clerk/clerk-js version >4.45

Environment

ENV1  

System:
    OS: macOS 14.6.1
    CPU: (12) arm64 Apple M2 Max
    Memory: 195.84 MB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.11.0 - ~/.nvm/versions/node/v20.11.0/bin/node
    Yarn: 1.22.21 - ~/.nvm/versions/node/v20.11.0/bin/yarn
    npm: 10.8.3 - ~/.nvm/versions/node/v20.11.0/bin/npm
    pnpm: 8.14.1 - /opt/homebrew/bin/pnpm
  Browsers:
    Chrome: 130.0.6723.92
    Chrome Canary: 132.0.6815.0
    Safari: 17.6
  npmPackages:
    @clerk/chrome-extension: 0.3.14 => 0.3.14 
    @testing-library/jest-dom: ^5.16.5 => 5.16.5 
    @testing-library/react: ^13.4.0 => 13.4.0 
    @testing-library/user-event: ^13.5.0 => 13.5.0 
    @types/jest: ^27.5.2 => 27.5.2 
    @types/node: ^16.18.12 => 16.18.12 
    @types/react: ^18.0.28 => 18.0.28 
    @types/react-dom: ^18.0.11 => 18.0.11 
    react: ^18.2.0 => 18.2.0 
    react-dom: ^18.2.0 => 18.2.0 
    react-router-dom: ^6.9.0 => 6.10.0 
    react-scripts: 5.0.1 => 5.0.1 
    typescript: ^4.9.5 => 4.9.5 
    web-vitals: ^2.1.4 => 2.1.4 

ENV2

  System:
    OS: macOS 14.6.1
    CPU: (12) arm64 Apple M2 Max
    Memory: 185.83 MB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 18.20.4 - ~/.nvm/versions/node/v18.20.4/bin/node
    Yarn: 1.22.21 - ~/.nvm/versions/node/v20.11.0/bin/yarn
    npm: 10.9.0 - ~/code/ezbot/visual-editor-extension/node_modules/.bin/npm
  Browsers:
    Chrome: 130.0.6723.92
    Chrome Canary: 132.0.6815.0
    Firefox: 131.0.3
    Safari: 17.6
  npmPackages:
    @babel/core: ^7.11.6 => 7.16.7 
    @babel/preset-env: ^7.11.5 => 7.16.7 
    @babel/preset-typescript: ^7.10.4 => 7.16.7 
    @clerk/chrome-extension: 0.6.22 => 0.6.22 
    @clerk/clerk-js: ^5.27.0 => 5.27.0 
    @emotion/react: ^11.13.3 => 11.13.3 
    @radix-ui/react-checkbox: ^1.1.2 => 1.1.2 
    @radix-ui/react-icons: ^1.3.0 => 1.3.0 
    @radix-ui/themes: ^3.1.4 => 3.1.4 
    @storybook/addon-essentials: ^6.4.9 => 6.4.9 
    @storybook/addon-interactions: ^6.4.9 => 6.4.9 
    @storybook/builder-webpack5: ^6.4.9 => 6.4.9 
    @storybook/manager-webpack5: ^6.4.9 => 6.4.9 
    @storybook/react: ^6.4.9 => 6.4.9 
    @storybook/testing-library: ^0.0.7 => 0.0.7 
    @types/chrome: ^0.0.279 => 0.0.279 
    @types/jest: ^26.0.14 => 26.0.24 
    @types/js-cookie: ^3.0.6 => 3.0.6 
    @types/node: ^14.11.8 => 14.18.4 
    @types/react: ^18.2.0 => 18.3.11 
    @types/react-dom: ^18.2.0 => 18.3.1 
    @types/react-test-renderer: ^17.0.1 => 17.0.1 
    @types/uuid: ^10.0.0 => 10.0.0 
    @types/webextension-polyfill: ^0.9.0 => 0.9.0 
    @typescript-eslint/eslint-plugin: ^4.4.1 => 4.33.0 
    @typescript-eslint/parser: ^4.4.1 => 4.33.0 
    autoprefixer: ^10.4.1 => 10.4.1 
    awesome-typescript-loader: ^5.2.1 => 5.2.1 
    axios: ^1.7.7 => 1.7.7 
    babel-core: ^6.26.3 => 6.26.3 
    babel-jest: ^26.5.2 => 26.6.3 
    babel-loader: ^8.1.0 => 8.2.3 
    css-loader: ^4.3.0 => 4.3.0 
    eslint: ^7.11.0 => 7.32.0 
    eslint-config-prettier: ^6.12.0 => 6.15.0 
    eslint-plugin-prettier: ^3.1.4 => 3.4.1 
    eslint-plugin-react: ^7.21.4 => 7.28.0 
    i: ^0.3.7 => 0.3.7 
    jest: ^26.5.3 => 26.6.3 
    jest-css-modules: ^2.1.0 => 2.1.0 
    motion: ^10.18.0 => 10.18.0 
    npm: ^10.9.0 => 10.9.0 
    postcss: ^8.4.31 => 8.4.31 
    postcss-loader: ^6.2.1 => 6.2.1 
    prettier: ^2.1.2 => 2.5.1 
    react: ^18.2.0 => 18.3.1 
    react-awesome-reveal: ^4.2.14 => 4.2.14 
    react-colorful: ^5.6.1 => 5.6.1 
    react-dom: ^18.2.0 => 18.3.1 
    react-router-dom: ^6.23.1 => 6.27.0 
    react-test-renderer: ^17.0.2 => 17.0.2 
    tailwindcss: ^3.4.14 => 3.4.14 
    ts-jest: ^26.4.1 => 26.5.6 
    ts-loader: ^8.0.5 => 8.3.0 
    typescript: ^5.6.3 => 5.6.3 
    use-long-press: ^3.2.0 => 3.2.0 
    uuid: ^10.0.0 => 10.0.0 
    webext-zustand: ^0.2.0 => 0.2.0 
    webextension-polyfill: ^0.12.0 => 0.12.0 
    webpack: ^5.76.0 => 5.76.0 
    webpack-bundle-analyzer: ^4.10.2 => 4.10.2 
    webpack-cli: ^4.9.1 => 4.9.1 
    webpack-merge: ^5.8.0 => 5.8.0 
    zustand: ^5.0.0 => 5.0.0

I also created another Repro Repo using the latest version of @clerk/chrome-extension, version 1.3.27. Same issue. It builds code that will not be accepted by the Chrome Web Store. https://github.com/griffin-ezbot/clerk-chrome-extension-starter

Hey @griffin-ezbot - we're so sorry about this. The recent changes to chrome's extension policies have broken the way our extension sdk works by default. Our team is actively looking into ways that we can fix this up such that extensions still get bot protections, but without causing this problem. We'll get an update out as soon as we can!

Sounds good. I'm thinking about removing all Clerk libraries, creating a Clerk OAuth App and using Chrome's Identity API with it for now.

Do you know if that's a good work around for now @jescalan?

Are you able to give us a day or two to tinker on this one? We may well have a fix out for you by then. If it's super time-pressing though, I understand and its worth a shot!

@jescalan – yes. I'll tinker as well during that time. FYI – that cloudflare package even shows up in your headless package.

I tried using the resources I mentioned in my last message. Getting an authorization code flow going with Clerk isn't easy, but I was able to do it. I couldn't find any documentation on how to exchange an Authorization Code for an Access Token and a Refresh Token.

TLDR; I'm really hoping there's something you guys can do with this package to make it past muster with MVC3; using Clerk with the Chrome Identity API is challenging.

Discussion at the moment is trending in the direction of removing bot protection from our chrome extension SDK since it's unsupported by chrome now. I'll keep you updated when we get something out here!

That would work for me. Unfortunately, as is, clerk is the sole blocker to releasing my chrome extension :/ and this issue was unexpected, making it even more inconvenient. Can you suggest a workaround?

I don't think we have a workaround at the moment, I'm so sorry! We were caught off guard a bit by the policy change and are working to get this fixed as quick as we can!

Thank you! I appreciate the support.

To give more context:

My users sign up directly on my website, rather than through the Chrome extension. I don’t utilize the <SignUp /> component in my extension, which involves CAPTCHA / remote code execution.

While examining your code to temporarily strip out CAPTCHA-related elements for my setup, I noticed another potential issue with your function loadScript. This function is called to load Clerk’s JavaScript from a CDN, which also isn’t permitted under Manifest V3 (MV3) guidelines.

In other words, to adapt your chrome-extension package, you'll need to remove any instances of remote code execution—including calls to load Clerk’s JavaScript and to Captcha providers. I think Google One Tap support is also problematic.

Hi @griffin-ezbot. I wanted to touch base here with an update. We are close to a snapshot to test with changes around remote code. This will remove the code that other SDKs use to remotely load clerk-js (the extension always bundled it, but the conditional code was present which is what you spotted and Google has rejected for other users), Google One Tap, Coinbase and Bot protection. This change will affect the Chrome Extension SDK, as well as other packages like @clerk/clerk-js and @clerk/shared.

This is the last blocker for a significant update to the SDK and a new 2.0 major release. This release will also include changing syncSessionWithTab (which I believe you are using) to synchost and improvements around sharing sessions and the introduction of createClerkClient() which is designed specifically for service workers in extensions.

Awesome! That all sounds great. I will be eagerly waiting. Happy to test it once it's ready.