fix(vite,webpack): restrict access via cors to local origins + allow configuration via devServer.cors

This commit is contained in:
Daniel Roe 2025-01-24 16:37:27 +00:00
parent 94ba2ea0b6
commit 406db5b4d2
No known key found for this signature in database
GPG Key ID: 3714AB03996F442B
3 changed files with 22 additions and 7 deletions

View File

@ -39,5 +39,13 @@ export default defineUntypedSchema({
* @type {(data: { loading?: string }) => string} * @type {(data: { loading?: string }) => string}
*/ */
loadingTemplate, loadingTemplate,
/**
* Set CORS options for the dev server
* @type {typeof import('h3').H3CorsOptions}
*/
cors: {
origin: [/^https?:\/\/(?:(?:[^:]+\.)?localhost|127\.0\.0\.1|\[::1\])(?::\d+)?$/],
},
}, },
}) })

View File

@ -9,7 +9,7 @@ import { getPort } from 'get-port-please'
import { joinURL, withoutLeadingSlash } from 'ufo' import { joinURL, withoutLeadingSlash } from 'ufo'
import { defu } from 'defu' import { defu } from 'defu'
import { env, nodeless } from 'unenv' import { env, nodeless } from 'unenv'
import { appendCorsHeaders, appendCorsPreflightHeaders, defineEventHandler } from 'h3' import { defineEventHandler, handleCors, setHeader } from 'h3'
import type { ViteConfig } from '@nuxt/schema' import type { ViteConfig } from '@nuxt/schema'
import type { ViteBuildContext } from './vite' import type { ViteBuildContext } from './vite'
import { devStyleSSRPlugin } from './plugins/dev-ssr-css' import { devStyleSSRPlugin } from './plugins/dev-ssr-css'
@ -255,11 +255,11 @@ export async function buildClient (ctx: ViteBuildContext) {
// @ts-expect-error _skip_transform is a private property // @ts-expect-error _skip_transform is a private property
event.node.req._skip_transform = true event.node.req._skip_transform = true
} else if (!useViteCors) { } else if (!useViteCors) {
if (event.method === 'OPTIONS') { const isPreflight = handleCors(event, ctx.nuxt.options.devServer.cors)
appendCorsPreflightHeaders(event, {}) if (isPreflight) {
return null return null
} }
appendCorsHeaders(event, {}) setHeader(event, 'Vary', 'Origin')
} }
// Workaround: vite devmiddleware modifies req.url // Workaround: vite devmiddleware modifies req.url

View File

@ -1,5 +1,6 @@
import pify from 'pify' import pify from 'pify'
import { defineEventHandler, fromNodeMiddleware } from 'h3' import { defineEventHandler, fromNodeMiddleware, handleCors, setHeader } from 'h3'
import type { H3CorsOptions } from 'h3'
import type { IncomingMessage, MultiWatching, ServerResponse } from 'webpack-dev-middleware' import type { IncomingMessage, MultiWatching, ServerResponse } from 'webpack-dev-middleware'
import webpackDevMiddleware from 'webpack-dev-middleware' import webpackDevMiddleware from 'webpack-dev-middleware'
import webpackHotMiddleware from 'webpack-hot-middleware' import webpackHotMiddleware from 'webpack-hot-middleware'
@ -100,7 +101,7 @@ async function createDevMiddleware (compiler: Compiler) {
}) })
// Register devMiddleware on server // Register devMiddleware on server
const devHandler = wdmToH3Handler(devMiddleware) const devHandler = wdmToH3Handler(devMiddleware, nuxt.options.devServer.cors)
const hotHandler = fromNodeMiddleware(hotMiddleware) const hotHandler = fromNodeMiddleware(hotMiddleware)
await nuxt.callHook('server:devHandler', defineEventHandler(async (event) => { await nuxt.callHook('server:devHandler', defineEventHandler(async (event) => {
const body = await devHandler(event) const body = await devHandler(event)
@ -114,8 +115,14 @@ async function createDevMiddleware (compiler: Compiler) {
} }
// TODO: implement upstream in `webpack-dev-middleware` // TODO: implement upstream in `webpack-dev-middleware`
function wdmToH3Handler (devMiddleware: webpackDevMiddleware.API<IncomingMessage, ServerResponse>) { function wdmToH3Handler (devMiddleware: webpackDevMiddleware.API<IncomingMessage, ServerResponse>, corsOptions: H3CorsOptions) {
return defineEventHandler(async (event) => { return defineEventHandler(async (event) => {
const isPreflight = handleCors(event, corsOptions)
if (isPreflight) {
return null
}
setHeader(event, 'Vary', 'Origin')
event.context.webpack = { event.context.webpack = {
...event.context.webpack, ...event.context.webpack,
devMiddleware: devMiddleware.context, devMiddleware: devMiddleware.context,