vitepress
vitepress copied to clipboard
Content Security Policy: unsafe-eval has to be set due to `new Function` call when using customized search
Describe the bug
We have set the Content Security Policy not to allow unsafe-eval. This worked until we added a custom tokenize function for the search. Now the page fails to load the scripts with this error, which results in broken navigation:
Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' {... generated sha256 of all script blocks on the page ...}".
at new Function (<anonymous>)
at deserializeFunctions (index.html:29:12475)
at index.html:29:12397
at Array.reduce (<anonymous>)
at deserializeFunctions (index.html:29:12377)
at index.html:29:12397
at Array.reduce (<anonymous>)
at deserializeFunctions (index.html:29:12377)
at index.html:29:12397
at Array.reduce (<anonymous>)
The stacktrace points to the new Function call in deserializeFunctions (https://github.com/vuejs/vitepress/blob/main/src/node/utils/fnSerialize.ts#L42).
Reproduction
To reproduce the issue, you have to create a vitepress config file that defines at least one function. In our case, we have defined a custom tokenize function for the search:
export default defineConfig({
// ...
themeConfig: {
search: {
provider: "local",
options: {
miniSearch: {
options: {
// Overriding the default regex (/[\n\r\p{Z}\p{P}]/u), to include e.g. "C#" as a token
tokenize: (text, fieldName) => text.split(/[\n\r\p{Z}\p{Terminal_Punctuation}]/u),
}
}
}
}
// ...
}
});
Also you have to set the Content Security Policy not to allow unsafe-eval, e.g. if you use a similar configuration to us, you have to set the script-src to include self, and an sha256 for each script block.
Expected behavior
Vitepress docs work with the customized search, even if the CSP does not allow unsafe-eval.
System Info
System:
OS: macOS 14.2.1
CPU: (12) arm64 Apple M2 Max
Memory: 1.62 GB / 64.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 18.19.1 - /opt/homebrew/opt/node@18/bin/node
npm: 10.2.4 - /opt/homebrew/opt/node@18/bin/npm
pnpm: 8.14.1 - /opt/homebrew/bin/pnpm
Browsers:
Chrome: 123.0.6312.59
Safari: 17.2.1
npmPackages:
vitepress: 1.0.0-rc.44 => 1.0.0-rc.44
Additional context
No response
Validations
- [X] Check if you're on the latest VitePress version.
- [X] Follow our Code of Conduct
- [X] Read the docs.
- [X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
How would it work then?
Thanks for looking into this! As far as I understood from other similar issues, they usually add a precompile step, resulting in directly adding the relevant functions, instead of serializing it and then deserializing it from a string. Would this be possible?
Ah good idea. We can do that.