{"id":"CVE-2023-49293","aliases":["CLSA-2026-1792163424","EUVD-2023-3168","GHSA-92r3-m2mg-pj97"],"status":"published","title":"Cross-site Scripting in `server.transformIndexHtml` via URL payload in vite","description":"Vite is a website frontend framework. When Vite's HTML transformation is invoked manually via `server.transformIndexHtml`, the original request URL is passed in unmodified, and the `html` being transformed contains inline module scripts (`\u003cscript type=\"module\"\u003e...\u003c/script\u003e`), it is possible to inject arbitrary HTML into the transformed output by supplying a malicious URL query string to `server.transformIndexHtml`. Only apps using `appType: 'custom'` and using the default Vite HTML middleware are affected. The HTML entry must also contain an inline script. The attack requires a user to click on a malicious URL while running the dev server. Restricted files aren't exposed to the attacker. This issue has been addressed in vite@5.0.5, vite@4.5.1, and vite@4.4.12. There are no known workarounds for this vulnerability.","severity":{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-09","score":0.00997,"percentile":0.62958,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-79"],"published":"2023-12-04T23:03:30Z","modified":"2026-11-04T10:45:29Z","exploits":[{"source":"nuclei","id":"CVE-2023-49293","title":"Vite dev server - Cross-Site Scripting","type":"detection template","url":"https://github.com/projectdiscovery/nuclei-templates/blob/main/http/cves/2023/CVE-2023-49293.yaml"}],"fixes":[{"ecosystem":"npm","package":"vite","fixed_in":["4.4.12","4.5.1","5.0.5"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"npm","package":"vite","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"4.4.0"},{"fixed":"4.4.12"}]}]},{"source":"ghsa","ecosystem":"npm","package":"vite","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"4.5.0"},{"last_affected":"4.5.0"},{"fixed":"4.5.1"}]}],"versions":["4.5.0"]},{"source":"ghsa","ecosystem":"npm","package":"vite","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"5.0.0"},{"fixed":"5.0.5"}]}]},{"source":"osv","ecosystem":"TuxCare:npm","package":"vite","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"4.5.0-tuxcare.0"},{"fixed":"4.5.0-tuxcare.4"}]}],"versions":["4.5.0","4.5.0-tuxcare.1","4.5.0-tuxcare.2","4.5.0-tuxcare.3"],"bundled":4},{"source":"osv","ecosystem":"npm","package":"vite","ranges":[{"type":"SEMVER","events":[{"introduced":"4.4.0"},{"fixed":"4.4.12"}]}]},{"source":"osv","ecosystem":"npm","package":"vite","ranges":[{"type":"SEMVER","events":[{"introduced":"4.5.0"},{"fixed":"4.5.1"}]}],"versions":["4.5.0"]},{"source":"osv","ecosystem":"npm","package":"vite","ranges":[{"type":"SEMVER","events":[{"introduced":"5.0.0"},{"fixed":"5.0.5"}]}]}],"products":[{"vendor":"vitejs","product":"vite"}],"references":[{"url":"https://github.com/vitejs/vite/security/advisories/GHSA-92r3-m2mg-pj97","tags":["x_refsource_CONFIRM","x_transferred","Exploit","Third Party Advisory","advisory","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2023-49293","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-92r3-m2mg-pj97"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2023/49xxx/CVE-2023-49293.json","tags":["advisory"]},{"url":"https://github.com/vitejs/vite","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2023-49293","title":"Cross-site Scripting in `server.transformIndexHtml` via URL payload in vite","description":"Vite is a website frontend framework. When Vite's HTML transformation is invoked manually via `server.transformIndexHtml`, the original request URL is passed in unmodified, and the `html` being transformed contains inline module scripts (`\u003cscript type=\"module\"\u003e...\u003c/script\u003e`), it is possible to inject arbitrary HTML into the transformed output by supplying a malicious URL query string to `server.transformIndexHtml`. Only apps using `appType: 'custom'` and using the default Vite HTML middleware are affected. The HTML entry must also contain an inline script. The attack requires a user to click on a malicious URL while running the dev server. Restricted files aren't exposed to the attacker. This issue has been addressed in vite@5.0.5, vite@4.5.1, and vite@4.4.12. There are no known workarounds for this vulnerability.","status":"published","published":"2023-12-04T23:03:30.752Z","modified":"2025-05-29T13:40:53.278Z","cvss":[{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium","assessor":"cna"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T14:35:12.596526Z"}],"euvd":[{"id":"EUVD-2023-3168","description":"Vite is a website frontend framework. When Vite's HTML transformation is invoked manually via `server.transformIndexHtml`, the original request URL is passed in unmodified, and the `html` being transformed contains inline module scripts (`\u003cscript type=\"module\"\u003e...\u003c/script\u003e`), it is possible to inject arbitrary HTML into the transformed output by supplying a malicious URL query string to `server.transformIndexHtml`. Only apps using `appType: 'custom'` and using the default Vite HTML middleware are affected. The HTML entry must also contain an inline script. The attack requires a user to click on a malicious URL while running the dev server. Restricted files aren't exposed to the attacker. This issue has been addressed in vite@5.0.5, vite@4.5.1, and vite@4.4.12. There are no known workarounds for this vulnerability.","status":"published","published":"2023-12-04T23:03:30Z","modified":"2025-05-29T13:40:53Z","cvss":[{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"updated_at":"2026-11-02T20:32:35.823426Z"}],"ghsa":[{"id":"GHSA-92r3-m2mg-pj97","title":"Vite XSS vulnerability in `server.transformIndexHtml` via URL payload","description":"### Summary\nWhen Vite's HTML transformation is invoked manually via `server.transformIndexHtml`, the original request URL is passed in unmodified, and the `html` being transformed contains inline module scripts (`\u003cscript type=\"module\"\u003e...\u003c/script\u003e`), it is possible to inject arbitrary HTML into the transformed output by supplying a malicious URL query string to `server.transformIndexHtml`.\n\n### Impact\nOnly apps using `appType: 'custom'` and using the default Vite HTML middleware are affected. The HTML entry must also contain an inline script. The attack requires a user to click on a malicious URL while running the dev server. Restricted files aren't exposed to the attacker.\n\n### Patches\nFixed in vite@5.0.5, vite@4.5.1, vite@4.4.12\n\n### Details\nSuppose `index.html` contains an inline module script:\n\n```html\n\u003cscript type=\"module\"\u003e\n  // Inline script\n\u003c/script\u003e\n```\n\nThis script is transformed into a proxy script like\n\n```html\n\u003cscript type=\"module\" src=\"/index.html?html-proxy\u0026index=0.js\"\u003e\u003c/script\u003e\n```\n\ndue to Vite's HTML plugin:\n\nhttps://github.com/vitejs/vite/blob/7fd7c6cebfcad34ae7021ebee28f97b1f28ef3f3/packages/vite/src/node/plugins/html.ts#L429-L465\n\nWhen `appType: 'spa' | 'mpa'`, Vite serves HTML itself, and `htmlFallbackMiddleware` rewrites `req.url` to the canonical path of `index.html`,\n\nhttps://github.com/vitejs/vite/blob/73ef074b80fa7252e0c46a37a2c94ba8cba46504/packages/vite/src/node/server/middlewares/htmlFallback.ts#L44-L47\n\nso the `url` passed to `server.transformIndexHtml` is `/index.html`.\n\nHowever, if `appType: 'custom'`, HTML is served manually, and if `server.transformIndexHtml` is called with the unmodified request URL (as the SSR docs suggest), then the path of the transformed `html-proxy` script varies with the request URL. For example, a request with path `/` produces\n\n```html\n\u003cscript type=\"module\" src=\"/@id/__x00__/index.html?html-proxy\u0026index=0.js\"\u003e\u003c/script\u003e\n```\n\nIt is possible to abuse this behavior by crafting a request URL to contain a malicious payload like\n\n```\n\"\u003e\u003c/script\u003e\u003cscript\u003ealert('boom')\u003c/script\u003e\n```\n\nso a request to http://localhost:5173/?%22%3E%3C/script%3E%3Cscript%3Ealert(%27boom%27)%3C/script%3E produces HTML output like\n\n```html\n\u003cscript type=\"module\" src=\"/@id/__x00__/?\"\u003e\u003c/script\u003e\u003cscript\u003ealert(\"boom\")\u003c/script\u003e?html-proxy\u0026index=0.js\"\u003e\u003c/script\u003e\n```\n\nwhich demonstrates XSS.\n\n### PoC\n\n- Example 1. Serving HTML from `vite dev` middleware with `appType: 'custom'`\n    - Go to https://stackblitz.com/edit/vitejs-vite-9xhma4?file=main.js\u0026terminal=dev-html\n    - \"Open in New Tab\"\n    - Edit URL to set query string to `?%22%3E%3C/script%3E%3Cscript%3Ealert(%27boom%27)%3C/script%3E` and navigate\n    - Witness XSS:\n    - ![image](https://user-images.githubusercontent.com/2456381/287434281-13757894-7a63-4a73-b1e9-d2b024c19d14.png)\n- Example 2. Serving HTML from SSR-style Express server (Vite dev server runs in middleware mode):\n    - Go to https://stackblitz.com/edit/vitejs-vite-9xhma4?file=main.js\u0026terminal=server\n    - (Same steps as above)\n- Example 3. Plain `vite dev` (this shows that vanilla `vite dev` is _not_ vulnerable, provided `htmlFallbackMiddleware` is used)\n    - Go to https://stackblitz.com/edit/vitejs-vite-9xhma4?file=main.js\u0026terminal=dev\n    - (Same steps as above)\n    - You should _not_ see the alert box in this case\n\n### Detailed Impact\n\nThis will probably predominantly affect [development-mode SSR](https://vitejs.dev/guide/ssr#setting-up-the-dev-server), where `vite.transformHtml` is called using the original `req.url`, per the docs:\n\nhttps://github.com/vitejs/vite/blob/7fd7c6cebfcad34ae7021ebee28f97b1f28ef3f3/docs/guide/ssr.md?plain=1#L114-L126\n\nHowever, since this vulnerability affects `server.transformIndexHtml`, the scope of impact may be higher to also include other ad-hoc calls to `server.transformIndexHtml` from outside of Vite's own codebase.\n\nMy best guess at bisecting which versions are vulnerable involves the following test script\n\n```js\nimport fs from 'node:fs/promises';\nimport * as vite from 'vite';\n\nconst html = `\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n  \u003chead\u003e\n    \u003cmeta charset=\"UTF-8\" /\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003cscript type=\"module\"\u003e\n      // Inline script\n    \u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n`;\nconst server = await vite.createServer({ appType: 'custom' });\nconst transformed = await server.transformIndexHtml('/?%22%3E%3C/script%3E%3Cscript%3Ealert(%27boom%27)%3C/script%3E', html);\nconsole.log(transformed);\nawait server.close();\n```\n\nand using it I was able to narrow down to #13581. If this is correct, then vulnerable Vite versions are 4.4.0-beta.2 and higher (which includes 4.4.0).","status":"published","published":"2023-12-05T23:31:34Z","modified":"2023-12-05T23:31:34Z","cvss":[{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T14:37:23.843848Z"}],"nvd":[{"id":"CVE-2023-49293","description":"Vite is a website frontend framework. When Vite's HTML transformation is invoked manually via `server.transformIndexHtml`, the original request URL is passed in unmodified, and the `html` being transformed contains inline module scripts (`\u003cscript type=\"module\"\u003e...\u003c/script\u003e`), it is possible to inject arbitrary HTML into the transformed output by supplying a malicious URL query string to `server.transformIndexHtml`. Only apps using `appType: 'custom'` and using the default Vite HTML middleware are affected. The HTML entry must also contain an inline script. The attack requires a user to click on a malicious URL while running the dev server. Restricted files aren't exposed to the attacker. This issue has been addressed in vite@5.0.5, vite@4.5.1, and vite@4.4.12. There are no known workarounds for this vulnerability.","status":"published","published":"2023-12-04T23:15:27.73Z","modified":"2026-06-17T06:35:47.193Z","cvss":[{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium","assessor":"secondary"},{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium","assessor":"primary"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T14:08:52.544469Z"}],"osv":[{"id":"CVE-2023-49293","title":"Cross-site Scripting in `server.transformIndexHtml` via URL payload in vite","description":"Vite is a website frontend framework. When Vite's HTML transformation is invoked manually via `server.transformIndexHtml`, the original request URL is passed in unmodified, and the `html` being transformed contains inline module scripts (`\u003cscript type=\"module\"\u003e...\u003c/script\u003e`), it is possible to inject arbitrary HTML into the transformed output by supplying a malicious URL query string to `server.transformIndexHtml`. Only apps using `appType: 'custom'` and using the default Vite HTML middleware are affected. The HTML entry must also contain an inline script. The attack requires a user to click on a malicious URL while running the dev server. Restricted files aren't exposed to the attacker. This issue has been addressed in vite@5.0.5, vite@4.5.1, and vite@4.4.12. There are no known workarounds for this vulnerability.","status":"published","published":"2023-12-04T23:03:30.752Z","modified":"2026-11-04T10:45:29.708790202Z","cvss":[{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"cwes":["CWE-79"],"updated_at":"2026-11-04T11:07:20.833685Z"},{"id":"GHSA-92r3-m2mg-pj97","title":"Vite XSS vulnerability in `server.transformIndexHtml` via URL payload","description":"### Summary\nWhen Vite's HTML transformation is invoked manually via `server.transformIndexHtml`, the original request URL is passed in unmodified, and the `html` being transformed contains inline module scripts (`\u003cscript type=\"module\"\u003e...\u003c/script\u003e`), it is possible to inject arbitrary HTML into the transformed output by supplying a malicious URL query string to `server.transformIndexHtml`.\n\n### Impact\nOnly apps using `appType: 'custom'` and using the default Vite HTML middleware are affected. The HTML entry must also contain an inline script. The attack requires a user to click on a malicious URL while running the dev server. Restricted files aren't exposed to the attacker.\n\n### Patches\nFixed in vite@5.0.5, vite@4.5.1, vite@4.4.12\n\n### Details\nSuppose `index.html` contains an inline module script:\n\n```html\n\u003cscript type=\"module\"\u003e\n  // Inline script\n\u003c/script\u003e\n```\n\nThis script is transformed into a proxy script like\n\n```html\n\u003cscript type=\"module\" src=\"/index.html?html-proxy\u0026index=0.js\"\u003e\u003c/script\u003e\n```\n\ndue to Vite's HTML plugin:\n\nhttps://github.com/vitejs/vite/blob/7fd7c6cebfcad34ae7021ebee28f97b1f28ef3f3/packages/vite/src/node/plugins/html.ts#L429-L465\n\nWhen `appType: 'spa' | 'mpa'`, Vite serves HTML itself, and `htmlFallbackMiddleware` rewrites `req.url` to the canonical path of `index.html`,\n\nhttps://github.com/vitejs/vite/blob/73ef074b80fa7252e0c46a37a2c94ba8cba46504/packages/vite/src/node/server/middlewares/htmlFallback.ts#L44-L47\n\nso the `url` passed to `server.transformIndexHtml` is `/index.html`.\n\nHowever, if `appType: 'custom'`, HTML is served manually, and if `server.transformIndexHtml` is called with the unmodified request URL (as the SSR docs suggest), then the path of the transformed `html-proxy` script varies with the request URL. For example, a request with path `/` produces\n\n```html\n\u003cscript type=\"module\" src=\"/@id/__x00__/index.html?html-proxy\u0026index=0.js\"\u003e\u003c/script\u003e\n```\n\nIt is possible to abuse this behavior by crafting a request URL to contain a malicious payload like\n\n```\n\"\u003e\u003c/script\u003e\u003cscript\u003ealert('boom')\u003c/script\u003e\n```\n\nso a request to http://localhost:5173/?%22%3E%3C/script%3E%3Cscript%3Ealert(%27boom%27)%3C/script%3E produces HTML output like\n\n```html\n\u003cscript type=\"module\" src=\"/@id/__x00__/?\"\u003e\u003c/script\u003e\u003cscript\u003ealert(\"boom\")\u003c/script\u003e?html-proxy\u0026index=0.js\"\u003e\u003c/script\u003e\n```\n\nwhich demonstrates XSS.\n\n### PoC\n\n- Example 1. Serving HTML from `vite dev` middleware with `appType: 'custom'`\n    - Go to https://stackblitz.com/edit/vitejs-vite-9xhma4?file=main.js\u0026terminal=dev-html\n    - \"Open in New Tab\"\n    - Edit URL to set query string to `?%22%3E%3C/script%3E%3Cscript%3Ealert(%27boom%27)%3C/script%3E` and navigate\n    - Witness XSS:\n    - ![image](https://user-images.githubusercontent.com/2456381/287434281-13757894-7a63-4a73-b1e9-d2b024c19d14.png)\n- Example 2. Serving HTML from SSR-style Express server (Vite dev server runs in middleware mode):\n    - Go to https://stackblitz.com/edit/vitejs-vite-9xhma4?file=main.js\u0026terminal=server\n    - (Same steps as above)\n- Example 3. Plain `vite dev` (this shows that vanilla `vite dev` is _not_ vulnerable, provided `htmlFallbackMiddleware` is used)\n    - Go to https://stackblitz.com/edit/vitejs-vite-9xhma4?file=main.js\u0026terminal=dev\n    - (Same steps as above)\n    - You should _not_ see the alert box in this case\n\n### Detailed Impact\n\nThis will probably predominantly affect [development-mode SSR](https://vitejs.dev/guide/ssr#setting-up-the-dev-server), where `vite.transformHtml` is called using the original `req.url`, per the docs:\n\nhttps://github.com/vitejs/vite/blob/7fd7c6cebfcad34ae7021ebee28f97b1f28ef3f3/docs/guide/ssr.md?plain=1#L114-L126\n\nHowever, since this vulnerability affects `server.transformIndexHtml`, the scope of impact may be higher to also include other ad-hoc calls to `server.transformIndexHtml` from outside of Vite's own codebase.\n\nMy best guess at bisecting which versions are vulnerable involves the following test script\n\n```js\nimport fs from 'node:fs/promises';\nimport * as vite from 'vite';\n\nconst html = `\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n  \u003chead\u003e\n    \u003cmeta charset=\"UTF-8\" /\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003cscript type=\"module\"\u003e\n      // Inline script\n    \u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n`;\nconst server = await vite.createServer({ appType: 'custom' });\nconst transformed = await server.transformIndexHtml('/?%22%3E%3C/script%3E%3Cscript%3Ealert(%27boom%27)%3C/script%3E', html);\nconsole.log(transformed);\nawait server.close();\n```\n\nand using it I was able to narrow down to #13581. If this is correct, then vulnerable Vite versions are 4.4.0-beta.2 and higher (which includes 4.4.0).","status":"published","published":"2023-12-05T23:31:34Z","modified":"2023-12-06T00:11:36.913866Z","cvss":[{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T15:46:43.123867Z"},{"id":"CLSA-2026-1792163424","title":"TuxCare security update for vite (4 CVEs)","description":"TuxCare rebuilt vite to address 4 CVEs. Fixed in 4.5.0-tuxcare.4.","status":"published","published":"2026-10-16T15:10:24Z","modified":"2026-10-16T16:31:39.757399382Z","updated_at":"2026-11-02T15:43:51.466048Z"}]}}
