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

[1.x] Add default CORS origins #318

Merged
merged 5 commits into from
Jan 21, 2025
Merged

[1.x] Add default CORS origins #318

merged 5 commits into from
Jan 21, 2025

Conversation

timacdonald
Copy link
Member

@timacdonald timacdonald commented Jan 21, 2025

The issue

Vite recently patched a vulnerability in their dev server (GHSA-vg6x-rcgg-rjx6).

The tl;dr; of the vulnerability: is allows any website to listen to a running dev server on the user's local computer and access the source code.

On my local machine, when I'm running npm run dev I could visit the following HTML hosted on any website, e.g., https://tim.macdonald.au/vite-listener, and the site would be able to listen to the dev server and potentially access source code.

Screenshot 2025-01-21 at 13 24 17

This issue was caused by Vite allowing '*' as the CORS origin by default. Now, applications must specify the allowed origins.

The result of this patch for Laravel applications is that we now get CORS errors when running the dev server.

The manual solution

Specify the Laravel application's origin in the Vite config:

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.js'],
            refresh: true,
        }),
    ],
+
+   server: {
+       cors: {
+           origin: 'https://my-app.test'
+       },
+   },
});

I don't love that this config needs to be in place in the default laravel/laravel config file. Additionally, I don't love that this fix needs to be done manually across all existing Laravel applications because we don't know what host the site is being accessed through.

Hardcoding is also not great when developers may run their web server in different ways, e.g., Herd or Artisan serve, resulting in different origins.

We could read the APP_URL but it is often not updated, and does not need to be, in order for the app to work.

The conventional solution

The goal of this PR is to provide a config-free solution for the 80% use case while still offering the above manual solution for applications with unique requirements.

Out of the box, the laravel-vite-plugin will autofill the server.cors.origin config allowing the following CORS origins:

  • APP_URL
  • http(s)://127.0.0.1
  • http(s)://localhost
  • http(s)://{PROJECT_DIRECTORY}.test

All of these also allow for a port to be specified.

With this in place, we should have out-of-the-box CORS support for:

  • Artisan serve
  • Sail (Docker)
  • Herd / Valet
  • Anything else via the APP_URL

These also feel like safe defaults that should not expose us to the Vite vulnerability.

Vite also allows .localhost domains out of the box.

These defaults do not work for me

If you set your APP_URL to whatever domain you server Laravel from, things should work as you need. If you really need special CORS customisations while locally running the dev server, you may add your own config:

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.js'],
            refresh: true,
        }),
    ],
+
+   server: {
+       cors: {
+           origin: 'https://my-app.au-1.sharedwithexpose.com'
+       },
+   },
});

@timacdonald timacdonald changed the title Add default CORS origins [1.x] Add default CORS origins Jan 21, 2025
@timacdonald timacdonald force-pushed the breaking-fixes branch 3 times, most recently from 076c6cd to 5777535 Compare January 21, 2025 03:29
@timacdonald timacdonald marked this pull request as ready for review January 21, 2025 03:34
@timacdonald
Copy link
Member Author

Moving to draft while the Vite team is working on an internal fix for some of these addresses: vitejs/vite#19249

@onlime
Copy link

onlime commented Jan 21, 2025

@timacdonald I like this solution a lot 👏 and hope you can merge it soon, as the .test TLD is probably not going to be added by default to server.cors.origin in Vite vitejs/vite#19250

But let's wait some more time until all opinions have settled.

@timacdonald
Copy link
Member Author

Update

vitejs/vite#19249 has been merged and contains some of the original work here and some more. I've included their default value instead of building out own.

I've also opened a PR to export the default value so it doesn't drift from what Vite ships with.

@@ -152,6 +152,13 @@ function resolveLaravelPlugin(pluginConfig: Required<PluginConfig>): LaravelPlug
},
server: {
origin: userConfig.server?.origin ?? '__laravel_vite_placeholder__',
cors: userConfig.server?.cors ?? {
origin: userConfig.server?.origin ?? [
/^https?:\/\/(?:(?:[^:]+\.)?localhost|127\.0\.0\.1|\[::1\])(?::\d+)?$/,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hoping vitejs/vite#19259 will get merged and we can remove this copy / pasted default.

@timacdonald timacdonald marked this pull request as ready for review January 21, 2025 23:01
@taylorotwell taylorotwell merged commit b3a3abf into 1.x Jan 21, 2025
4 checks passed
@taylorotwell taylorotwell deleted the breaking-fixes branch January 21, 2025 23:25
@jsandfordhughescoop
Copy link

@timacdonald - I am still having an issue after upgrading the plugin where the websocket does not connect.

I have managed to get it working by overriding the allowedHosts in the Vite server config but wondering what would be causing this?

server: {
   allowedHosts: true,
},

@timacdonald
Copy link
Member Author

@jsandfordhughescoop, I'm not seeing that issue.

Can you please let me know the setup you have, including the URLs for the dev server and the host in your browser?

It is possible we will need to include the same list in the allowedHosts, however I'm not seeing the issue so I want to be able to replicate the issue first.

@jsandfordhughescoop
Copy link

jsandfordhughescoop commented Jan 23, 2025

@jsandfordhughescoop, I'm not seeing that issue.

Can you please let me know the setup you have, including the URLs for the dev server and the host in your browser?

It is possible we will need to include the same list in the allowedHosts, however I'm not seeing the issue so I want to be able to replicate the issue first.

@timacdonald - Just a standard Vite setup with the Laravel plugin.

The APP_URL is https://bddbusinessmanagement.test and the host in the browser matches that.

The dev server is reporting https://BDDBusinessManagement.test:5173/ which has uppercase letters. I wonder if that matters?

@timacdonald
Copy link
Member Author

@jsandfordhughescoop, it does look like the capitalisation is the issue here.

I was able to replicate this locally.

Assuming you are using Valet / Herd, I recommend unsecuring the site and re-running the secure command with the lower case version.

cd BDDBusinessManagement
herd unsecure
herd secure bddbusinessmanagement

Hopefully that helps.

@jsandfordhughescoop
Copy link

@jsandfordhughescoop, it does look like the capitalisation is the issue here.

I was able to replicate this locally.

Assuming you are using Valet / Herd, I recommend unsecuring the site and re-running the secure command with the lower case version.

cd BDDBusinessManagement
herd unsecure
herd secure bddbusinessmanagement

Hopefully that helps.

Thanks for the help @timacdonald.

Unfortunately, no matter what I do, when I secure the site via herd, Vite sets the dev server with the uppercase path. If I unsecure the site, everything works fine as it uses localhost.

Either way, totally not an issue with this package.

Joe

@timacdonald
Copy link
Member Author

@jsandfordhughescoop, have you tried renaming the directory to not be uppercase (I assume it is uppercase on your filesystem)? That could work.

@jsandfordhughescoop
Copy link

@jsandfordhughescoop, have you tried renaming the directory to not be uppercase (I assume it is uppercase on your filesystem)? That could work.

@timacdonald - That has fixed it.

Would a PR be accepted to make this regex case insensitive?

@jsandfordhughescoop
Copy link

@jsandfordhughescoop, have you tried renaming the directory to not be uppercase (I assume it is uppercase on your filesystem)? That could work.

@timacdonald - That has fixed it.

Would a PR be accepted to make this regex case insensitive?

Having a play around with this and even manually adding the uppercase and lowercase CORS origins, it still fails.

The only was is to either rename the directory or override the server.host

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

Successfully merging this pull request may close these issues.

5 participants