Skip to content

Commit 406db5b

Browse files
committed
fix(vite,webpack): restrict access via cors to local origins + allow configuration via devServer.cors
1 parent 94ba2ea commit 406db5b

3 files changed

Lines changed: 22 additions & 7 deletions

File tree

packages/schema/src/config/dev.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,13 @@ export default defineUntypedSchema({
3939
* @type {(data: { loading?: string }) => string}
4040
*/
4141
loadingTemplate,
42+
43+
/**
44+
* Set CORS options for the dev server
45+
* @type {typeof import('h3').H3CorsOptions}
46+
*/
47+
cors: {
48+
origin: [/^https?:\/\/(?:(?:[^:]+\.)?localhost|127\.0\.0\.1|\[::1\])(?::\d+)?$/],
49+
},
4250
},
4351
})

packages/vite/src/client.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { getPort } from 'get-port-please'
99
import { joinURL, withoutLeadingSlash } from 'ufo'
1010
import { defu } from 'defu'
1111
import { env, nodeless } from 'unenv'
12-
import { appendCorsHeaders, appendCorsPreflightHeaders, defineEventHandler } from 'h3'
12+
import { defineEventHandler, handleCors, setHeader } from 'h3'
1313
import type { ViteConfig } from '@nuxt/schema'
1414
import type { ViteBuildContext } from './vite'
1515
import { devStyleSSRPlugin } from './plugins/dev-ssr-css'
@@ -255,11 +255,11 @@ export async function buildClient (ctx: ViteBuildContext) {
255255
// @ts-expect-error _skip_transform is a private property
256256
event.node.req._skip_transform = true
257257
} else if (!useViteCors) {
258-
if (event.method === 'OPTIONS') {
259-
appendCorsPreflightHeaders(event, {})
258+
const isPreflight = handleCors(event, ctx.nuxt.options.devServer.cors)
259+
if (isPreflight) {
260260
return null
261261
}
262-
appendCorsHeaders(event, {})
262+
setHeader(event, 'Vary', 'Origin')
263263
}
264264

265265
// Workaround: vite devmiddleware modifies req.url

packages/webpack/src/webpack.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import pify from 'pify'
2-
import { defineEventHandler, fromNodeMiddleware } from 'h3'
2+
import { defineEventHandler, fromNodeMiddleware, handleCors, setHeader } from 'h3'
3+
import type { H3CorsOptions } from 'h3'
34
import type { IncomingMessage, MultiWatching, ServerResponse } from 'webpack-dev-middleware'
45
import webpackDevMiddleware from 'webpack-dev-middleware'
56
import webpackHotMiddleware from 'webpack-hot-middleware'
@@ -100,7 +101,7 @@ async function createDevMiddleware (compiler: Compiler) {
100101
})
101102

102103
// Register devMiddleware on server
103-
const devHandler = wdmToH3Handler(devMiddleware)
104+
const devHandler = wdmToH3Handler(devMiddleware, nuxt.options.devServer.cors)
104105
const hotHandler = fromNodeMiddleware(hotMiddleware)
105106
await nuxt.callHook('server:devHandler', defineEventHandler(async (event) => {
106107
const body = await devHandler(event)
@@ -114,8 +115,14 @@ async function createDevMiddleware (compiler: Compiler) {
114115
}
115116

116117
// TODO: implement upstream in `webpack-dev-middleware`
117-
function wdmToH3Handler (devMiddleware: webpackDevMiddleware.API<IncomingMessage, ServerResponse>) {
118+
function wdmToH3Handler (devMiddleware: webpackDevMiddleware.API<IncomingMessage, ServerResponse>, corsOptions: H3CorsOptions) {
118119
return defineEventHandler(async (event) => {
120+
const isPreflight = handleCors(event, corsOptions)
121+
if (isPreflight) {
122+
return null
123+
}
124+
setHeader(event, 'Vary', 'Origin')
125+
119126
event.context.webpack = {
120127
...event.context.webpack,
121128
devMiddleware: devMiddleware.context,

0 commit comments

Comments
 (0)