vitejs / vite

Next generation frontend tooling. It's fast!
http://vitejs.dev
MIT License
67.21k stars 6.04k forks source link

Improper escaping of HTML attribute when `transformIndexHtml` is used #18040

Closed jtbandes closed 5 days ago

jtbandes commented 1 week ago

Describe the bug

Vite plugins which implement the transformIndexHtml() function can choose to return an array, representing HTML tags to be added to the document. The attrs of these tags are improperly escaped and can lead to arbitrary HTML/scripts being injected into the index.html file.

The serializeAttrs function used by the built-in html plugin incorrectly escapes HTML attributes using JSON.stringify: https://github.com/vitejs/vite/blob/1a76300cd16827f0640924fdc21747ce140c35fb/packages/vite/src/node/plugins/html.ts#L1513

This code dates back to 4 years ago: https://github.com/vitejs/vite/commit/9ce2ab4febfb110b03760a2494546d683097189c#diff-89bae1df62862bb7f4a03d82a1e9cbf4ac6d0c042f21fbbacb0a2238bd050042R140

Reproduction

https://stackblitz.com/edit/vitejs-vite-swzvsz?file=vite.config.ts

Steps to reproduce

Using the following vite.config.ts:

import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [
    {
      name: 'example',
      transformIndexHtml(_html, _ctx) {
        return [
          {
            tag: 'link',
            attrs: {
              rel: 'icon',
              href: `"><script>alert('hi from transformIndexHtml')</script>`,
            },
          },
        ];
      },
    },
  ],
});

The resulting index.html file now includes this:

<link rel="icon" href="\"><script>alert('hi from transformIndexHtml')</script>">

(The leading " was incorrectly escaped with \. One correct way to escape this in a HTML attribute would be &quot;.)

System Info

vite 5.4.3

Used Package Manager

npm

Logs

No response

Validations

stackblitz[bot] commented 1 week ago

Fix this issue in StackBlitz Codeflow Start a new pull request in StackBlitz Codeflow.