视图引擎的内容安全策略
本页回答:页面开着严格的内容安全策略(CSP)时,视图引擎要放行什么?
引擎可以在严格的内容安全策略下运行:script-src 'self'、style-src 'self',既不开 'unsafe-inline',也不开 'unsafe-eval'。引擎不执行字符串形式的代码,不写内联脚本;要放行的只有三件事,各有一个原因。
要放行的三件事
- 样式表是文件。 从允许的来源加载
styles.css(用预设时还有themes.css或themes/<名>.css),不要内联。引擎画出来的标记里没有style属性:内联样式都经 DOM 的 style 对象写入,策略不拦;图表提示框的色块是 SVG 的fill。也不载入data:图片:搭看板时显示的格子画在页面里。 - 打包进来的库加的样式带上页面的 nonce。 有三个库干活时会往
<head>加一个<style>:拖放库在拖动排序时加(拖动时的光标、不选中文字),栅格的拖动库在移动或缩放仪表盘面板时加(不选中文字),Base UI 在下拉选择的列表打开时加(出现滚动箭头时藏起滚动条)。按 Vite 的html.cspNonce的约定把本次响应的 nonce 写成<meta property="csp-nonce" nonce="…">(写在content里也认),并在style-src里放行'nonce-…';引擎把它交给这三个库。没有这个 meta 时一切照样能用,只是这几条规则被拦掉,各报一次违规。 - 导出 PNG 要载入
blob:图片。 图的 SVG 从一个blob:地址作为图片载入、再画到画布上,所以img-src要包含blob:。不放行时 PNG 做不出来,工具栏会说明。导出 SVG 不需要任何放行,两种导出都不执行代码、不写内联脚本。
策略
text
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'nonce-<每次响应不同>'; img-src 'self' blob:html
<meta property="csp-nonce" nonce="<同一个 nonce>" />nonce 每次响应都要新生成,由服务端(或渲染 HTML 的那一层)写进响应头与页面里的 meta;一个固定不变的 nonce 等于没有。
守着这条策略的测试
有两处测试正是按这条策略跑的,出现一次违规就失败:
- Storybook 里的
StrictCsp.test.stories.tsx走过记录工作台(拖一列、从下拉选一个汇总、拉宽一列、打开一条记录的详情)、每种图型连同它的提示框、SVG/PNG/CSV 三种导出,以及一块仪表盘的读、从图上筛选、搭(移动与缩放面板、拖动标签页、加一个分析)与保存;它和其他故事一起在 CI 里跑。策略由strictCsp.ts在每个故事开头装到页上。 - 补偿控制台按同一条策略跑端到端(
e2e/csp.spec.ts)。
下一步
| 接下来 | 阅读 |
|---|---|
| 样式表有哪些、各什么时候引 | 视图引擎的主题 |
ViewHost、路由与嵌入 | 把引擎接进宿主 |
| 视图引擎是什么 | 视图引擎 |