Skip to content

html.cspNonce option injects nonce values onto <script> tags that already contain a nonce #16414

@thebanjomatic

Description

@thebanjomatic

Describe the bug

If you have <script> tags that already contain a nonce in your index.html, vite will add its own nonce tag resulting in a <script> with repeated nonce attributes which then fails to load.

For example,

<html>
<head>
  <script nonce="MY_NONCE">
    console.log('Hello!')
  </script>
</head>
<body>
  <script type="module" src="/main.ts"></script>
</body>
</html>

vite.config.ts

import {defineConfig} from 'vite';
export default defineConfig({
  html: {
    cspNonce: 'VITE_NONCE'
  },
});

Generates:

<head>
  <script nonce="MY_NONCE" nonce="VITE_NONCE">
    console.log('Hello!')
  </script>
  <meta property="csp-nonce" nonce="VITE_NONCE">
  <script type="module" crossorigin src="/assets/index-Clf4UCUm.js" nonce="VITE_NONCE"></script>
  <link rel="stylesheet" crossorigin href="/assets/index-D99yczAM.css" nonce="VITE_NONCE">
</head>
<body>
</body>
</html>

Note: The fact that MY_NONCE and VITE_NONCE are different identifiers is actually irrelevant to the problem and in my real use-case they happen to both be the same value being replaced at runtime when the index.html response is served.

When trying to run, this fails CSP in the browser:
image

Expected behavior

I would expect vite to ignore any <script> or <link> tags that already contain a nonce attribute rather than inject a second one.
While you could argue that I could just remove the nonce from my script tags in index.html, the situation is actually a little more complicated then that as I have plugins which are injecting these tags that have their own mechanism for injecting cspNonce since this feature did not exist until Vite v5.2. Those plugins could be made aware of cspNonce (and probably will be), but in the meantime I still think that it's a bug for vite to inject nonce onto tags that have one explicitly defined already.

Reproduction

https://stackblitz.com/edit/vitejs-vite-fmzzip?file=index.html

Steps to reproduce

It's probably easiest to just build the reproducer and verify that the <script> tag has multiple nonce attributes to reproduce the problem.

System Info

System:
    OS: Windows 11 10.0.22631
    CPU: (20) x64 12th Gen Intel(R) Core(TM) i7-12800H
    Memory: 9.09 GB / 31.64 GB
  Binaries:
    Node: 20.12.2 - ~\AppData\Local\Volta\tools\image\node\20.12.2\node.EXE
    Yarn: 4.1.1 - ~\AppData\Local\Volta\tools\image\yarn\1.22.19\bin\yarn.CMD
    npm: 10.5.0 - ~\AppData\Local\Volta\tools\image\node\20.12.2\npm.CMD
    pnpm: 8.14.1 - ~\AppData\Local\Volta\tools\image\pnpm\8.14.1\bin\pnpm.CMD
    bun: 1.1.0 - ~\.bun\bin\bun.EXE
  Browsers:
    Edge: Chromium (123.0.2420.65)
    Internet Explorer: 11.0.22621.1
  npmPackages:
    @vitejs/plugin-vue: ^5.0.4 => 5.0.4
    vite: ^5.2.8 => 5.2.8

Used Package Manager

yarn

Logs

No response

Validations

Metadata

Metadata

Assignees

No one assigned

    Labels

    feat: htmlp3-minor-bugAn edge case that only affects very specific usage (priority)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions