Skip to content

Commit

Permalink
fix(proxy): replace changeOrigin changes in 5.3.0 with new rewriteWsO…
Browse files Browse the repository at this point in the history
…rigin option (#17563)

Co-authored-by: John Hunter <john.hunter@arenko.group>
  • Loading branch information
johnhunter and johnhunterarenko committed Jul 2, 2024
1 parent 055f1c1 commit 14c3d49
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 11 deletions.
4 changes: 3 additions & 1 deletion docs/config/server-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Configure custom proxy rules for the dev server. Expects an object of `{ key: op

Note that if you are using non-relative [`base`](/config/shared-options.md#base), you must prefix each key with that `base`.

Extends [`http-proxy`](https://github.com/http-party/node-http-proxy#options). Additional options are [here](https://github.com/vitejs/vite/blob/main/packages/vite/src/node/server/middlewares/proxy.ts#L13). Note that [unlike http-proxy](https://github.com/http-party/node-http-proxy/issues/1669), the `changeOrigin` option will change both host and origin headers to match the target.
Extends [`http-proxy`](https://github.com/http-party/node-http-proxy#options). Additional options are [here](https://github.com/vitejs/vite/blob/main/packages/vite/src/node/server/middlewares/proxy.ts#L13).

In some cases, you might also want to configure the underlying dev server (e.g. to add custom middlewares to the internal [connect](https://github.com/senchalabs/connect) app). In order to do that, you need to write your own [plugin](/guide/using-plugins.html) and use [configureServer](/guide/api-plugin.html#configureserver) function.

Expand Down Expand Up @@ -123,9 +123,11 @@ export default defineConfig({
},
},
// Proxying websockets or socket.io: ws://localhost:5173/socket.io -> ws://localhost:5174/socket.io
// Exercise caution using `rewriteWsOrigin` as it can leave the proxying open to CSRF attacks.
'/socket.io': {
target: 'ws://localhost:5174',
ws: true,
rewriteWsOrigin: true,
},
},
},
Expand Down
31 changes: 21 additions & 10 deletions packages/vite/src/node/server/middlewares/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,35 @@ export interface ProxyOptions extends HttpProxy.ServerOptions {
res: http.ServerResponse,
options: ProxyOptions,
) => void | null | undefined | false | string
/**
* rewrite the Origin header of a WebSocket request to match the the target
*
* **Exercise caution as rewriting the Origin can leave the proxying open to [CSRF attacks](https://owasp.org/www-community/attacks/csrf).**
*/
rewriteWsOrigin?: boolean | undefined
}

const setOriginHeader = (
const rewriteOriginHeader = (
proxyReq: http.ClientRequest,
options: HttpProxy.ServerOptions,
options: ProxyOptions,
config: ResolvedConfig,
) => {
// Browsers may send Origin headers even with same-origin
// requests. It is common for WebSocket servers to check the Origin
// header, so if changeOrigin is true we change the Origin to match
// header, so if rewriteWsOrigin is true we change the Origin to match
// the target URL.
// https://github.com/http-party/node-http-proxy/issues/1669
if (options.changeOrigin) {
if (options.rewriteWsOrigin) {
const { target } = options

if (proxyReq.headersSent) {
config.logger.warn(
colors.yellow(
`Unable to rewrite Origin header as headers are already sent.`,
),
)
return
}

if (proxyReq.getHeader('origin') && target) {
const changedOrigin =
typeof target === 'object'
Expand Down Expand Up @@ -112,12 +127,8 @@ export function proxyMiddleware(
}
})

proxy.on('proxyReq', (proxyReq, req, res, options) => {
setOriginHeader(proxyReq, options)
})

proxy.on('proxyReqWs', (proxyReq, req, socket, options, head) => {
setOriginHeader(proxyReq, options)
rewriteOriginHeader(proxyReq, options, config)

socket.on('error', (err) => {
config.logger.error(
Expand Down

0 comments on commit 14c3d49

Please sign in to comment.