npm / vite / 6.4.5

vite 6.4.5

Source
https://github.com/vitejs/vite
Tag scanned
v6.4.5
Directory
packages/vite (only this part of the repository was scanned)
Compared with
v6.4.4 (0 signals introduced since)
Files
370 scanned, 31 skipped (binary, oversized, or unrecognised)
Signals
1 critical · 8 warn · 19 info
Scan time
11.8 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 14 of 23 warn and critical signals; 14 demoted to info.
Disclude version
4.0.0
Scanned (UTC)
2026-10-21 09:10

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:1494: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)
  2. `require` called with a non-literal specifier (ast pass, confidence 0.60)

              // eslint-disable-next-line no-restricted-globals -- this function runs inside cjs
              const terser = require(terserPath)
              return terser.minify(code, options) as Terser.MinifyOutput
            },
  3. `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++) {
  4. dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

    export async function importAction(id) {
    	return await import(/* @vite-ignore */ id);
    }
  5. 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),
  6. 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((process.platform === 'win32' ? '/@fs/' : '') + absolutePath),
  7. 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),
        dynamicFileUrl: await import(fileUrl),
  8. dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

        dynamicAbsoluteExtension: await import(nameAbsoluteExtension),
        dynamicAbsoluteFull: await import((process.platform === 'win32' ? '/@fs/' : '') + absolutePath),
        dynamicFileUrl: await import(fileUrl),
        static: staticModule,
  9. dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

        dynamicAbsoluteFull: await import((process.platform === 'win32' ? '/@fs/' : '') + absolutePath),
        dynamicFileUrl: await import(fileUrl),
        static: staticModule,
      }
  10. info warn → info by review dynamic-import packages/vite/rollup.config.ts:371:41

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

          // escape import so that it's not bundled while config load
          const dynImport = (id: string) => import(id)
          // ignore warning from CJS entrypoint to avoid misleading logs
          process.env.VITE_CJS_IGNORE_WARNING = 'true'
    likely benign LLM, confidence 0.90 A helper that performs a runtime import(id) so the config loader is not bundled.
    Reasoning

    The dynamic import wraps a function parameter, but the surrounding comments show it is deliberately hidden from the bundler so the config loads at runtime. This is a standard build-tool pattern, not a dropper.

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

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

        const [acceptedPathWithoutQuery, query] = acceptedPath.split(`?`)
        const importPromise = import(
          /* @vite-ignore */
          base +
    likely benign LLM, confidence 0.85 HMR client dynamically imports an accepted module path, marked @vite-ignore.
    Reasoning

    The import is annotated with @vite-ignore and builds its specifier from a base URL and an accepted path for HMR module loading. This is expected behaviour in a Vite client.

  12. info warn → info by review dynamic-import packages/vite/src/module-runner/esmEvaluator.ts:44: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.85 Evaluator method that dynamically imports an external module by filepath.
    Reasoning

    This is a module runner that evaluates external ESM files by path. Dynamic import is its core purpose and the input comes from the module graph, not untrusted sources.

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

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

          const chunk = (output as RollupOutput).output[0]
          const mod = await import(
            path.join(
              import.meta.dirname,
    dismissed LLM, confidence 0.90 Test imports a built output file via a path constructed from import.meta.dirname.
    Reasoning

    This is a test that imports a built bundle from a path built with path.join and import.meta.dirname. It is a fixture load with no malicious indicators.

  14. file mixes tab and space indentation (4 tab-indented and 140 space-indented lines) (raw pass, confidence 0.40)

    import {
      type JsonOptions,
      extractJsonErrorPosition,
      jsonPlugin,
  15. info warn → info by review dynamic-import packages/vite/src/node/__tests__/resolve.spec.ts:292: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')
        )
    dismissed LLM, confidence 0.90 Test dynamically imports a fixture module built for file-url resolution.
    Reasoning

    The test imports a fixture file located with join(import.meta.dirname, ...). This is a normal test fixture load.

  16. info warn → info by review dynamic-import packages/vite/src/node/__tests__/resolve.spec.ts:307: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')
        )
    dismissed LLM, confidence 0.90 Test dynamically imports a virtual-fixture module by a local path.
    Reasoning

    Same pattern as the sibling finding: a test imports a fixture module by a local path. Nothing suspicious.

  17. info warn → info by review encoding-base64 packages/vite/src/node/__tests__/utils.spec.ts:222: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 A PEM-encoded test certificate fixture flagged by the base64 heuristic.
    Reasoning

    The base64 content is a PEM certificate fixture in a test file, with the BEGIN CERTIFICATE header. The raw-pass base64 heuristic fires on the normal encoding of a certificate.

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

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

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

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

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

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

    async function nativeImportConfigFile(resolvedPath: string) {
      const module = await import(
        pathToFileURL(resolvedPath).href + '?t=' + Date.now()
      )
    likely benign LLM, confidence 0.85 Native ESM config loader imports the resolved config file via file URL.
    Reasoning

    The function imports a config file by file URL with a cache-busting query, the standard way Vite loads native ESM config. The path comes from the user's project config resolution.

  23. info warn → info by review dynamic-import packages/vite/src/node/config.ts:2062: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.85 Imports a temporarily bundled config file and removes it afterwards.
    Reasoning

    This imports a temp file that the code has just bundled from the user's config, then deletes it in finally. This is the normal bundle-and-load config path, not an attack.

  24. info warn → info by review dynamic-import packages/vite/src/node/plugins/css.ts:2467:35

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

            // eslint-disable-next-line no-restricted-globals -- this function runs inside a cjs worker
            const sass: typeof Sass = require(sassPath)
            // eslint-disable-next-line no-restricted-globals
            const path: typeof import('node:path') = require('node:path')
    likely benign LLM, confidence 0.85 CJS worker requires the sass preprocessor from a resolved path.
    Reasoning

    The require uses a resolved sass path inside a CJS worker, which is a documented need for loading an optional preprocessor. The module ID comes from dependency resolution, not from attacker input.

  25. info warn → info by review dynamic-import packages/vite/src/node/plugins/css.ts:2583:35

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

            // eslint-disable-next-line no-restricted-globals -- this function runs inside a cjs worker
            const sass: typeof Sass = require(sassPath)
            // eslint-disable-next-line no-restricted-globals
            const path: typeof import('node:path') = require('node:path')
    likely benign LLM, confidence 0.85 CJS worker requires sass from a resolved path, a second occurrence.
    Reasoning

    Same pattern as the other sass require: loading an optional preprocessor from a resolved path inside the CJS worker. Benign.

  26. info warn → info by review dynamic-import packages/vite/src/node/plugins/css.ts:2684:40

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

          // https://github.com/nodejs/node/issues/31710
          const sass: typeof Sass = (await import(pathToFileURL(sassPath).href))
            .default
          compilerPromise ??= sass.initAsyncCompiler()
    likely benign LLM, confidence 0.85 Imports the sass compiler via file URL for ESM interop.
    Reasoning

    The code imports sass by file URL to work around a Node ESM issue, which is a documented compatibility pattern. The path is from resolution.

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

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

            // eslint-disable-next-line no-restricted-globals -- this function runs inside a cjs worker
            const nodeLess: typeof Less = require(lessPath)
            const viteResolverPlugin = createViteLessPlugin(
              nodeLess,
    likely benign LLM, confidence 0.85 CJS worker requires the less preprocessor from a resolved path.
    Reasoning

    The code requires the less preprocessor from a resolved path inside the CJS worker. This is standard optional-dependency loading.

  28. info warn → info by review dynamic-import packages/vite/src/node/plugins/css.ts:3173:43

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

            // eslint-disable-next-line no-restricted-globals -- this function runs inside a cjs worker
            const nodeStylus: typeof Stylus = require(stylusPath)
    
            const ref = nodeStylus(content, {
    likely benign LLM, confidence 0.85 CJS worker requires the stylus preprocessor from a resolved path.
    Reasoning

    The code requires the stylus preprocessor from a resolved path inside the CJS worker. This is expected preprocessor loading.

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 v6.4.5
disclude scan --severity info --diff v6.4.4 packages/vite