npm / vite / 8.3.4

vite 8.3.4

Source
https://github.com/vitejs/vite
Tag scanned
v8.3.4
Directory
packages/vite (only this part of the repository was scanned)
Compared with
v8.3.3 (0 signals introduced since)
Files
493 scanned, 64 skipped (binary, oversized, or unrecognised)
Signals
1 critical · 0 warn · 33 info
Scan time
21.1 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 25 of 25 warn and critical signals; 24 demoted to info.
Disclude version
4.0.0
Scanned (UTC)
2026-10-14 19:39

Signals

Ordered by severity, then signals introduced in this release. Hidden characters are shown as ⟨U+…⟩.

  1. critical dynamic-execution packages/vite/src/node/utils.ts:1781:14

    `Function(...)` called with a non-literal body (ast pass, confidence 0.90)

    export function evalValue<T = any>(rawValue: string): T {
      const fn = new Function(`
        var console, exports, global, module, process, require
        return (\n${rawValue}\n)
    suspicious LLM, confidence 0.80 Builds and invokes a Function from a template string wrapping a raw value, used as an evaluator in the build tool's utils.
    Reasoning

    The function builds a Function body from a template string that wraps a raw value in a return expression, shaping it as an evaluator for config-like values. Dynamic Function construction is risky in general, and the rawValue is an untrusted-looking string parameter, so this is a real code-execution sink. However, the context (a utility named evalValue that shadows console/process/require as parameters) looks like a deliberate, bounded config-evaluation helper in a build tool rather than a hidden dropper. The static dynamic-execution signal is warranted, but the code reads as an intentional, known pattern rather than obfuscated malice. Suspicious rather than confirmed because the input source is not shown.

  2. info warn → info by review unicode-mixed-script packages/vite/README.md:12:46

    identifier `viːt` mixes scripts: Latin + Other (raw pass, confidence 0.80)

    
    Vite (French word for "quick", pronounced [`/viːt/`]https://cdn.jsdelivr.net/gh/vitejs/vite@main/docs/public/vite.mp3, like "veet") is a build tool that aims to provide a faster and leaner development experience for modern web projects. It consists of two major parts:
    dismissed LLM, confidence 0.93 IPA pronunciation transcription in the Vite README.
    Reasoning

    The flagged identifier is IPA pronunciation notation (/viːt/, with the length mark ː) in a README describing the project name. Non-Latin characters are expected in documentation about pronunciation, and there is no code execution or obfuscation.

  3. info warn → info by review dynamic-import packages/vite/src/client/bundledDevHmrClient.ts:324:13

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

        try {
          await import(/* @vite-ignore */ this.options.base + url)
        } catch {
          this.requestFullReload(`failed to import hmr patch ${url}`)
    likely benign LLM, confidence 0.85 Dynamic import of an HMR patch module URL in the Vite dev client.
    Reasoning

    Vite's HMR client loads hot-update patch modules from base plus a server-supplied URL, with a fallback to full reload on failure. The @vite-ignore comment marks it as intentional, and this is standard dev-server behavior.

  4. info warn → info by review dynamic-import packages/vite/src/client/client.ts:161:27

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

        const browserPath = wrapIdIfNeeded(acceptedPathWithoutQuery)
        const importPromise = import(
          /* @vite-ignore */
          base +
    likely benign LLM, confidence 0.85 Dynamic import of an accepted HMR module path in the Vite client.
    Reasoning

    The import specifier is base plus a wrapped module path used for HMR accept handling. The @vite-ignore annotation and surrounding HMR logic indicate normal runtime module loading in the dev client.

  5. info warn → info by review dynamic-import packages/vite/src/module-runner/esmEvaluator.ts:50:12

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

      runExternalModule(filepath: string): Promise<any> {
        return import(filepath)
      }
    }
    likely benign LLM, confidence 0.80 Evaluator method that dynamically imports an external module by file path.
    Reasoning

    This is the ESM evaluator of Vite's module runner, which imports external modules by filepath. Loading arbitrary modules is the purpose of the class, so the pattern is expected, though it is a powerful primitive for a reviewer to note.

  6. info warn → info by review dynamic-execution packages/vite/src/module-runner/utils.ts:17:40

    `atob` decodes a base64 value at runtime — common step before dynamic fetch or eval (ast pass, confidence 0.75)

      return (base64: string) =>
        textDecoder.decode(Uint8Array.from(atob(base64), (c) => c.charCodeAt(0)))
    })()
    likely benign LLM, confidence 0.85 Base64 decode helper that converts an encoded string to UTF-8 text.
    Reasoning

    atob decodes a base64 string into bytes, which are then decoded as UTF-8 text. This is a standard helper for handling inline base64 data such as source maps. It is not paired with eval or a network fetch in the snippet.

  7. info warn → info by review dynamic-import packages/vite/src/node/__tests__/environment.spec.ts:173:25

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

          const chunk = (output as RolldownOutput).output[0]
          const mod = await import(
            path.join(
              import.meta.dirname,
    likely benign LLM, confidence 0.90 Test dynamically imports a built bundle from a fixture path.
    Reasoning

    The test imports a built output file via path.join relative to import.meta.dirname, which is a normal test fixture pattern.

  8. file mixes tab and space indentation (16 tab-indented and 630 space-indented lines) (raw pass, confidence 0.40)

    import {
      convertTargets,
      createCSSResolvers,
      cssPlugin,
  9. info warn → info by review dynamic-import packages/vite/src/node/__tests__/resolve.spec.ts:294:24

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

        })
        const mod1 = await import(
          join(import.meta.dirname, 'fixtures/file-url/dist/basic/index.js')
        )
    likely benign LLM, confidence 0.90 Test imports a fixture module built for file-url resolution.
    Reasoning

    The test imports a fixture build output using join with import.meta.dirname. This is routine test setup with a fixed path.

  10. info warn → info by review dynamic-import packages/vite/src/node/__tests__/resolve.spec.ts:309:24

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

        })
        const mod2 = await import(
          join(import.meta.dirname, 'fixtures/file-url/dist/virtual/index.js')
        )
    likely benign LLM, confidence 0.90 Test imports a second fixture module for virtual file-url resolution.
    Reasoning

    The same fixture-import pattern appears with a different fixture path. It is a routine test that loads a known local file.

  11. info warn → info by review encoding-base64 packages/vite/src/node/__tests__/utils.spec.ts:45:1

    base64-like blob (1348 bytes over 22 lines, compression ratio 0.71) (raw pass, confidence 0.60)

    -----BEGIN CERTIFICATE-----
    MIID7zCCAtegAwIBAgIJS9D2rIN7tA8mMA0GCSqGSIb3DQEBCwUAMGkxFDASBgNV
    BAMTC2V4YW1wbGUub3JnMQswCQYDVQQGEwJVUzERMA8GA1UECBMIVmlyZ2luaWEx
    EzARBgNVBAcTCkJsYWNrc2J1cmcxDTALBgNVBAoTBFRlc3QxDTALBgNVBAsTBFRl
    dismissed LLM, confidence 0.95 Embedded PEM certificate fixture in a unit test.
    Reasoning

    The blob is a PEM-formatted X.509 certificate in a test file. Long base64 runs are expected for certificates, and the high compression ratio is typical for this kind of data.

  12. base64-like blob (264 bytes, compression ratio 0.79) (in comment) (raw pass, confidence 0.36)

    https://evanw.github.io/source-map-visualization/#MzQALyogY29tbWVudCAqLwpjb25zb2xlLmxvZygiZm9vIik7CjE1NgB7InZlcnNpb24iOjMsInNvdXJjZXMiOlsiL3NyYy9mb28uanMiXSwic291cmNlc0NvbnRlbnQiOlsiY29uc29sZS5sb2coXCJmb29cIik7XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQzsifQo=
  13. base64-like blob (388 bytes, compression ratio 0.76) (in comment) (raw pass, confidence 0.36)

    https://evanw.github.io/source-map-visualization/#NjMALy8gYi5qcwpjb25zb2xlLmxvZygiLi9iLmpzIik7CgovLyBhLmpzCmNvbnNvbGUubG9nKCIuL2EuanMiKTsKMjIwAHsKICAidmVyc2lvbiI6IDMsCiAgInNvdXJjZXMiOiBbImIuanMiLCAiYS5qcyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiY29uc29sZS5sb2coJy4vYi5qcycpXG4iLCAiaW1wb3J0ICcuL2IuanMnXG5jb25zb2xlLmxvZygnLi9hLm
  14. base64-like blob (440 bytes, compression ratio 0.73) (in comment) (raw pass, confidence 0.36)

    https://evanw.github.io/source-map-visualization/#NjYALmZvbyB7CiAgb3ZlcmZsb3c6IHNjcm9sbDsKICAtd2Via2l0LW92ZXJmbG93LXNjcm9sbGluZzogdG91Y2g7Cn0KMjU1AHsKICAiZmlsZSI6ICIvc3JjL3Nhc3Mvc3R5bGUuc2FzcyIsCiAgIm1hcHBpbmdzIjogIkFBQUE7RUFDRSxnQkFBZ0I7RUNEbEIsa0NBQUE7QURFQSIsCiAgIm5hbWVzIjogW10sCiAgInNvdXJjZXMiOiBbCiAgICAiL3NyYy9zYX
  15. base64-like blob (324 bytes, compression ratio 0.77) (in comment) (raw pass, confidence 0.36)

    https://evanw.github.io/source-map-visualization/#MjkALmZvbyB7CiAgb3ZlcmZsb3c6IHNjcm9sbDsKfQoyMDcAewogICJmaWxlIjogIi9zcmMvc2Fzcy9zdHlsZS5zYXNzIiwKICAibWFwcGluZ3MiOiAiQUFBQTtFQUNFIiwKICAibmFtZXMiOiBbXSwKICAic291cmNlcyI6IFsKICAgICIvc3JjL3Nhc3MvdmVuZG9yL2luZGV4LnNjc3MiCiAgXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi5mb28ge1xuICBvdm
  16. info warn → info by review dynamic-import packages/vite/src/node/config.ts:2483:24

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.80)

    
      const module = await import(
        pathToFileURL(resolvedPath).href + '?t=' + Date.now()
      )
    likely benign LLM, confidence 0.90 Dynamic import of the resolved config file with a timestamp for cache busting.
    Reasoning

    Vite loads a bundled config file by file URL with a cache-busting timestamp query. This is the standard mechanism for reloading config during dev, and the path comes from the resolved config file.

  17. info warn → info by review dynamic-import packages/vite/src/node/config.ts:2784:21

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

        try {
          return (await import(pathToFileURL(tempFileName).href)).default
        } finally {
          fs.unlink(tempFileName, () => {}) // Ignore errors
    likely benign LLM, confidence 0.88 Imports a temporary bundled config file and removes it afterward.
    Reasoning

    The code imports a temporary file containing the bundled config, then deletes it in a finally block. This is the normal flow for loading TypeScript configs with a bundler, and cleanup is handled.

  18. info warn → info by review dynamic-import packages/vite/src/node/plugins/css.ts:2556:31

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

          const sssPath = loadPreprocessorPath(PostCssDialectLang.sss, root)
          const resolved = (await import(pathToFileURL(sssPath).href)).default
          return (cachedSss = resolved)
        })()
    likely benign LLM, confidence 0.90 Dynamic import of an installed SSS preprocessor module, cached after the first load.
    Reasoning

    The code loads the Sass-like preprocessor module from a path resolved by loadPreprocessorPath and caches the result. This is the normal way to load an optional CSS preprocessor dependency.

  19. info warn → info by review dynamic-import packages/vite/src/node/plugins/css.ts:2609:39

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

        async run(sassPath, data, options) {
          const sass: typeof Sass = await import(sassPath)
          compilerPromise ??= sass.initAsyncCompiler()
          const compiler = await compilerPromise
    likely benign LLM, confidence 0.90 Loads the sass preprocessor module from a resolved path at runtime.
    Reasoning

    Vite's CSS plugin loads optional preprocessor packages (sass) by resolved path from user-installed dependencies. Dynamic import of a resolved package path is standard for optional peer dependencies and not obfuscation.

  20. info warn → info by review dynamic-import packages/vite/src/node/plugins/css.ts:2716:17

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

            try {
              await import(sassPackage.path)
            } catch (e) {
              if (/sass-embedded-[a-z0-9]+-[a-z0-9]+/i.test(e.message)) {
    likely benign LLM, confidence 0.90 Tests whether the sass-embedded package can be imported, catching errors.
    Reasoning

    Probing for the sass-embedded package by importing its resolved path inside a try/catch is a normal optional-dependency check in a build tool.

  21. info warn → info by review dynamic-import packages/vite/src/node/plugins/css.ts:2967:46

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

          ) => {
            const nodeLess: typeof Less = (await import(lessPath)).default
            const viteResolverPlugin = createViteLessPlugin(
              nodeLess,
    likely benign LLM, confidence 0.90 Loads the Less preprocessor module from a resolved path.
    Reasoning

    Less preprocessor is loaded from a resolved path, a standard optional-dependency pattern in Vite's CSS pipeline.

  22. info warn → info by review dynamic-import packages/vite/src/node/plugins/css.ts:3080:46

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

          ) => {
            const stylus: typeof Stylus = (await import(stylusPath)).default
    
            const ref = stylus(content, {
    likely benign LLM, confidence 0.90 Loads the Stylus preprocessor module from a resolved path.
    Reasoning

    Stylus preprocessor is loaded from a resolved path as an optional dependency, consistent with the other CSS preprocessor loaders in the file.

  23. info warn → info by review dynamic-import packages/vite/src/node/plugins/terser.ts:49:57

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

            ) => {
              const terser: typeof import('terser') = await import(terserPath)
              try {
                return (await terser.minify(code, options)) as TerserMinifyOutput
    likely benign LLM, confidence 0.90 Loads the terser minifier from a resolved path.
    Reasoning

    Terser is loaded from a resolved path for minification, an optional-dependency pattern. No payload or evaluation of untrusted data is involved.

  24. info warn → info by review dynamic-execution packages/vite/src/node/plugins/wasm.ts:43:28

    `atob` decodes a base64 value at runtime — common step before dynamic fetch or eval (ast pass, confidence 0.75)

        } else if (typeof atob === 'function') {
          const binaryString = atob(urlContent)
          bytes = new Uint8Array(binaryString.length)
          for (let i = 0; i < binaryString.length; i++) {
    likely benign LLM, confidence 0.85 Decodes base64-encoded wasm bytes at runtime in the wasm plugin helper.
    Reasoning

    atob decodes an inline base64 WebAssembly module in the wasm helper, a legitimate way to embed wasm bytes. The decoded bytes are used to instantiate wasm, not eval'd as script, and the pattern is common in build tooling.

  25. dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

    export async function importAction(id) {
      return await import(/* @vite-ignore */ id)
    }
    likely benign LLM, confidence 0.90 Test fixture helper performing dynamic import of a supplied id.
    Reasoning

    Test fixture intentionally exercising dynamic import of a variable id for the SSR runtime; not malicious.

  26. dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

        dynamicProcessed: await import('./simple'),
        dynamicRelative: await import(nameRelative),
        dynamicAbsolute: await import(nameAbsolute),
        dynamicAbsoluteExtension: await import(nameAbsoluteExtension),
    likely benign LLM, confidence 0.90 Test fixture dynamically imports relative module paths.
    Reasoning

    Test fixture with dynamic imports of local relative and absolute paths to verify SSR module resolution; expected behavior.

  27. dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

        dynamicRelative: await import(nameRelative),
        dynamicAbsolute: await import(nameAbsolute),
        dynamicAbsoluteExtension: await import(nameAbsoluteExtension),
        dynamicAbsoluteFull: await import(
    likely benign LLM, confidence 0.90 Test fixture dynamically imports absolute module paths.
    Reasoning

    Same test fixture covering dynamic imports of absolute paths for SSR runtime testing; benign.

  28. dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

        dynamicAbsolute: await import(nameAbsolute),
        dynamicAbsoluteExtension: await import(nameAbsoluteExtension),
        dynamicAbsoluteFull: await import(
          (process.platform === 'win32' ? '/@fs/' : '') + absolutePath
    likely benign LLM, confidence 0.90 Test fixture dynamically imports a platform-adjusted absolute path.
    Reasoning

    Test fixture building a /@fs/ prefixed path for a Windows-specific dynamic import test; benign test scaffolding.

  29. dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

        dynamicAbsoluteExtension: await import(nameAbsoluteExtension),
        dynamicAbsoluteFull: await import(
          (process.platform === 'win32' ? '/@fs/' : '') + absolutePath
        ),
    likely benign LLM, confidence 0.90 Test fixture dynamically imports an absolute path with extension.
    Reasoning

    Test fixture dynamically imports an extension-bearing absolute path as part of SSR runtime tests; benign.

  30. dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

        ),
        dynamicFileUrl: await import(fileUrl),
        static: staticModule,
      }
    likely benign LLM, confidence 0.85 Test fixture in Vite's SSR runtime that performs a dynamic import of a file URL variable.
    Reasoning

    This is a test fixture for the SSR runtime's dynamic import handling. A dynamic import with a variable specifier (fileUrl) is exactly what the fixture is meant to exercise. It is a standard pattern in a module loader test, with no encoding or hidden payload in the snippet.

  31. base64-like blob (692 bytes, compression ratio 0.70) (in comment) (raw pass, confidence 0.36)

    //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidHJhbnNwaWxlZC1pbmxpbmUudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImltcG9ydCAnbm9kZTpwYXRoJ1xuXG5leHBvcnQgdHlwZSBEdW1teSA9IHtcbiAgZm9vOiBcImZvb1wiLFxufVxuXG4vKipcbiAqIGR1bW15XG4gKiBkdW1teVxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB0ZX
  32. `btoa` encodes a value as base64 at runtime — used in exfiltration patterns (ast pass, confidence 0.55)

        `throw new Error('example')\n` +
        `//# ${SOURCEMAPPING_URL}=data:application/json;base64,${btoa(
          JSON.stringify(syntheticSourceMap),
        )}\n`
  33. orphaned high surrogate \uD800 (no matching low surrogate) (token pass, confidence 0.65)

    function isHighSurrogate(value: string): boolean {
      return value >= '\uD800' && value <= '\uDBFF'
    }
  34. orphaned high surrogate \uDBFF (no matching low surrogate) (token pass, confidence 0.65)

    function isHighSurrogate(value: string): boolean {
      return value >= '\uD800' && value <= '\uDBFF'
    }

Reproduce This Scan

Run disclude locally to verify. Add --format sarif for SARIF output. Add --llm (with an API key in the environment) to include the LLM review.

cargo install disclude --version 4.0.0
git clone https://github.com/vitejs/vite vite && cd vite
git checkout v8.3.4
disclude scan --severity info --diff v8.3.3 packages/vite