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

CORS policy blocks script access in development #971

Open
1 of 2 tasks
aqiongbei opened this issue Jan 20, 2025 · 12 comments
Open
1 of 2 tasks

CORS policy blocks script access in development #971

aqiongbei opened this issue Jan 20, 2025 · 12 comments

Comments

@aqiongbei
Copy link

Build tool

Vite

Where do you see the problem?

  • In the browser
  • In the terminal

Describe the bug

i create a react crx demo according to this guide Get Started with React, when i run pnpm dev, i found this error info in chrome extension inspect page(chrome://extensions/?errors=gbfkgllkhphjnpfpgfgmpahkbekgeenh)

Image

the service-worker-loader.js's content is

import 'http://localhost:5173/@vite/env';
import 'http://localhost:5173/@crx/client-worker';

my chrome version is 131.0.6778.265 (arm64)

Reproduction

do according to Get Started with React.

Logs

Access to script at 'http://localhost:5173/@crx/client-worker' from origin 'chrome-extension://gbfkgllkhphjnpfpgfgmpahkbekgeenh' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

System Info

System:
    OS: macOS 12.7.6
    CPU: (8) arm64 Apple M1 Pro
    Memory: 121.64 MB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh
  npmPackages:
    @crxjs/vite-plugin: 2.0.0-beta.30 => 2.0.0-beta.30 
    @eslint/js: ^9.17.0 => 9.18.0 
    @types/react: ^18.3.18 => 18.3.18 
    @types/react-dom: ^18.3.5 => 18.3.5 
    @vitejs/plugin-react: ^4.3.4 => 4.3.4 
    eslint: ^9.17.0 => 9.18.0 
    eslint-plugin-react-hooks: ^5.0.0 => 5.1.0 
    eslint-plugin-react-refresh: ^0.4.16 => 0.4.18 
    globals: ^15.14.0 => 15.14.0 
    react: ^18.3.1 => 18.3.1 
    react-dom: ^18.3.1 => 18.3.1 
    typescript: ~5.6.2 => 5.6.3 
    typescript-eslint: ^8.18.2 => 8.20.0 
    vite: ^6.0.5 => 6.0.9

Severity

annoyance

@aqiongbei aqiongbei changed the title 2.0.0-bate.30 request js has been blocked by CORS policy 2.0.0-bate.30 request background has been blocked by CORS policy Jan 21, 2025
@Maks-Yaremenko
Copy link

Maks-Yaremenko commented Jan 21, 2025

managed to resolve by adding "host_permissions": ["<all_urls>"] to the manifest file, but now I have another issue, when I'm trying to load the extension it refreshes infinitely, and finally, I'm getting the error:

WebSocket connection to 'ws://localhost:5173/' failed: Error during WebSocket handshake: Unexpected response code: 400 

@aqiongbei
Copy link
Author

managed to resolve by adding "host_permissions": ["<all_urls>"] to the manifest file, but now I have another issue, when I'm trying to load the extension it refreshes infinitely, and finally, I'm getting the error:

WebSocket connection to 'ws://localhost:5173/' failed: Error during WebSocket handshake: Unexpected response code: 400 

now, we have another issue.

@aqiongbei aqiongbei reopened this Jan 21, 2025
@liuwilliamBUPT
Copy link

liuwilliamBUPT commented Jan 21, 2025

i just encounter this same issue about websocket and take a lot time to find the reason. luckily, i found it.

because of the update of vite. they add
a new mechanism that used to enhance the security of websocket.

following this link

https://github.com/vitejs/vite/blob/9654348258eaa0883171533a2b74b4e2825f5fb6/packages/vite/src/node/config.ts#L535

* In Vite 6.0.8 and below, WebSocket server was able to connect from any web pages. However,
   * that could be exploited by a malicious web page.
   *
   * In Vite 6.0.9+, the WebSocket server now requires a token to connect from a web page.
   * But this may break some plugins and frameworks that connects to the WebSocket server
   * on their own. Enabling this option will make Vite skip the token check.
   *
   * **We do not recommend enabling this option unless you are sure that you are fine with
   * that security weakness.**

so the resolution is adding the legacy option to your vite config to close token verifying, then the problem solved.

@aqiongbei
Copy link
Author

aqiongbei commented Jan 21, 2025

@liuwilliamBUPT you resolve my problem, thx you bro. You're really amazing!
so guys, add"host_permissions": ["<all_urls>"]to the manifest file and add the follow config in your vite.config.ts will resolve the issue.

legacy: {
    skipWebSocketTokenCheck: true,
}

@jacksteamdev
Copy link
Contributor

jacksteamdev commented Jan 21, 2025

Amazing work @liuwilliamBUPT and @aqiongbei

I'm going to reopen this because this is a significant breaking change in Vite that's affecting Chrome Extension development workflows. If you've updated Vite recently and your extension development suddenly stopped working, this is why.

What's Happening

Starting with these Vite versions:

  • =6.0.9

  • =5.4.12, <6.0.0

  • =4.5.6, <5.0.0

Vite changed default CORS policies in the dev server, which breaks CRXJS's development workflow. While this was done for security reasons, it's causing real issues for extension developers.

Quick Fix

If you need to get back to work immediately, you can add this to your vite.config.js:

export default defineConfig({
  // ... existing config
  legacy: {
    skipWebSocketTokenCheck: true
  }
})

Long-term Solution

CRXJS should update to properly handle Vite's new WebSocket security requirements. Something like this might work:

// vite.config.js
export default defineConfig({
  server: {
    cors: {
      origin: [
        'chrome-extension://',  // Allow all extensions in dev
        // Or for production, specific extension IDs:
        // 'chrome-extension://<your-extension-id>'
      ]
    }
  }
})

Related Links

Would appreciate feedback from extension developers on these solutions, particularly if you're working with different Chrome extension configurations.

@jacksteamdev jacksteamdev reopened this Jan 21, 2025
@jacksteamdev jacksteamdev changed the title 2.0.0-bate.30 request background has been blocked by CORS policy CORS policy blocks script access in development Jan 21, 2025
@jacksteamdev jacksteamdev pinned this issue Jan 21, 2025
@sapphi-red
Copy link

sapphi-red commented Jan 23, 2025

Sorry for the breakage. For the websocket connection, passing the token here would probably work:

const socket = new WebSocket(`${socketProtocol}://${socketHost}`, 'vite-hmr')

In other words, it can probably be fixed by updating this line to new WebSocket(`${socketProtocol}://${socketHost}?token=${token}`, 'vite-hmr'). You can get the token from config.webSocketToken in the configResolved hook.
Ideally, it should not connect to the WebSocket server on its own and instead use import.meta.hot. I assume it's related to that fact that ESM support in extensions are not good. Is that the reason why it's connecting on its own?

For server.cors, I'd recommend adding "host_permissions": ["http://localhost:5173"] to the manifest rather than adding chrome-extension:// to the server.cors.origin. This way you can block requests from extensions without host_permissions.

@nechmads
Copy link

I have the same problem, even after adding the following to the vite.config.ts
legacy: {
skipWebSocketTokenCheck: true
}

It seems that just when I add the "host_permissions": ["<all_urls>"] to the manifest the problem is solved. But obviously, I don't want to ask for this kind of permission. Asking for permissions to all websites get Google to take ages when reviewing every update + it can show a warning to users.

Is there another way to solve this for now?

@vitorgamer58
Copy link

@nechmads I believe it is possible to generate the manifest.json dynamically, where it is possible to configure this permission only when the environment is development, and then not add this line in the manifest.json of the build (production). I saw this in some code where the extension generated the manifest dynamically depending on the target browser and the environment.

Including the background permission itself is an example, you may not need it in production.

And here we are dealing with a problem when connecting to the Vite server to hot reload the extension while we are developing, it is not necessary in production because everything will be in the .js files.

@ch0c0l8ra1n
Copy link

@aqiongbei Use npm init vite@^3.0

crxjs's website says it only supports vite 2 and 3 (3 is beta)

@vitorgamer58
Copy link

vitorgamer58 commented Jan 27, 2025

I kept getting CORS error until I added this in defineConfig of vite.config.js file

  server: {
    cors: {
      origin: '*'
    }
  },

@aqiongbei @jacksteamdev

@JacobGrady
Copy link

JacobGrady commented Jan 28, 2025

Wasted a few hours trying to fix this issue today "Error during WebSocket handshake: Unexpected response code: 400"
luckily came across this thread, and this fixed it! Thank you!

Quick Fix

If you need to get back to work immediately, you can add this to your vite.config.js:

  // ... existing config
  legacy: {
    skipWebSocketTokenCheck: true
  }

@salmin89
Copy link

Long-term Solution

Let us know when the long-term solution is available

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants