跳到主要内容

内容安全策略

如果网站发送 Content-Security-Policy 请求头,浏览器会阻止所有策略未明确允许的内容,包括 Kaleidr 的脚本、iframe 和请求。本页说明使用各产品时需要允许哪些资源。如果网站没有发送该请求头,则无需阅读本页。

所需授权取决于产品在哪里运行:

产品运行位置策略必须允许的内容
ViewerKaleidr 托管的 iframe 中加载器脚本和 iframe。
TileKaleidr 托管的 iframe 中加载器脚本、会话请求及 iframe。
Chat你自己的网页中加载器脚本、API 请求、注入样式、内嵌字体及图片。
Editor你自己的网页中,带独立地图以上所有内容,加上底图主机、地图 worker 和地图图片。

对于 Viewer 和 Tile 两种 iframe 产品,iframe 内的地图及其加载的所有内容受 Kaleidr 自己的安全策略约束,而不是你的网页策略。因此需要允许的内容较少。

使用的主机​

主机提供的资源使用产品
https://cdn.kaleidr.comkaleidr.js 及其加载的产品包(chat.js、viewer.js、editor.js、tile.js)。使用 SDK 时的所有产品。
https://api.kaleidr.com会话交换及 Chat 回答时发送的请求。Chat、Editor、Tile。
https://map-embed.kaleidr.comViewer 和 Tile iframe 内显示的网页。Viewer、Tile。
https://tile.kaleidr.comEditor 页面内地图的底图,包括样式、瓦片、精灵图和字体。Editor。

Kaleidr 的任何产品都不要求允许 Mapbox、MapTiler 或 OpenStreetMap 的主机。此前版本曾列出这些地址,现在可以移除。如果你在网页中运行自己的地图,则仍需允许该地图所用的主机。

Viewer​

使用 SDK 元素或 Kaleidr.mount 时:

script-src https://cdn.kaleidr.com;
frame-src https://map-embed.kaleidr.com;

使用 Studio 提供的普通 iframe 代码时,不需要脚本:

frame-src https://map-embed.kaleidr.com;

Viewer 不需要 connect-src 配置,因为没有密钥的 Viewer 不会从你的网页发出请求。

Tile​

script-src https://cdn.kaleidr.com;
connect-src https://api.kaleidr.com;
frame-src https://map-embed.kaleidr.com;

connect-src 用于允许 SDK 在创建 iframe 之前,使用可公开密钥进行会话交换。

Chat​

script-src https://cdn.kaleidr.com;
connect-src https://api.kaleidr.com;
style-src 'unsafe-inline';
font-src data:;
img-src data: https:;
指令原因
script-src https://cdn.kaleidr.com加载器及 chat.js。
connect-src https://api.kaleidr.com会话交换,以及每次提问和回答。
style-src 'unsafe-inline'Chat 会在文档 head 中添加一个没有 nonce 的 <style> 元素。
font-src data:Chat 字体以 data: URL 形式内嵌在产品包中。
img-src data:Chat 图标以内嵌的 data: URL 提供。
img-src https:地点卡片显示照片,照片主机会因地点而异,无法在此全部列出。如果收紧 img-src,未允许的主机上的照片将无法加载。
img-src https:(网站图标)回答中的链接和地点卡片中的网站会显示网站图标。图标来自 Google 的 favicon 服务 https://www.google.com,并重定向到 https://t0.gstatic.com 至 https://t3.gstatic.com。如果收紧 img-src,就需要允许 https://www.google.com 和 https://*.gstatic.com,否则图标缺失,但链接仍然可用。

Chat 产品包不包含地图类库,也不需要 'wasm-unsafe-eval'。它会绘制在网页已有的地图上,因此你仍需允许自身地图库要求的资源:脚本主机、connect-src 和 img-src 中的瓦片与样式主机,以及 Mapbox GL JS、MapLibre GL JS 所需的 worker-src blob:。

如果 Chat 控制的是 Kaleidr 的 Viewer 或 Tile 元素,而不是你自己的地图,还需添加该产品的指令,包括 frame-src https://map-embed.kaleidr.com。

Editor​

script-src 'self' https://cdn.kaleidr.com;
style-src 'self' 'unsafe-inline';
connect-src 'self' https://api.kaleidr.com https://tile.kaleidr.com;
img-src 'self' data: blob: https://tile.kaleidr.com;
worker-src blob:;
font-src 'self' data:;
指令原因
script-src https://cdn.kaleidr.com加载器及 editor.js。
style-src 'unsafe-inline'Editor 通过 JavaScript 向文档添加样式表,不使用 nonce。
connect-src https://api.kaleidr.com会话交换。
connect-src https://tile.kaleidr.comEditor 从网页获取的底图样式、瓦片、精灵图和标注字体。
img-src data: blob: https://tile.kaleidr.com地图图像及图标;地图通过 blob: 和 data: URL 创建图像。
worker-src blob:地图通过 blob: URL 运行其 worker。
font-src data:Editor 界面字体以 data: URL 形式内嵌。

'wasm-unsafe-eval' 不包含在默认列表中。只有控制台明确报告策略阻止了 editor.js 的 WebAssembly 编译(用于解码 3D 模型)时,才把它添加到 script-src。

如果通过 styleId 传入完整样式 URL,还必须在 connect-src 和 img-src 中允许该样式自己的主机。

一个网页使用多个产品​

将各产品的列表合并。例如,同时使用 Tile 地图和控制它的 Chat 面板时,需要:

script-src https://cdn.kaleidr.com;
connect-src https://api.kaleidr.com;
frame-src https://map-embed.kaleidr.com;
style-src 'unsafe-inline';
font-src data:;
img-src data: https:;

完整策略示例​

以上代码块仅展示 Kaleidr 新增的许可要求。实际策略还要允许你自己的资源。以下是一个完整请求头示例:网站从自己的来源提供其他所有资源,同时嵌入 Viewer 和 Tile:

Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.kaleidr.com; connect-src 'self' https://api.kaleidr.com; frame-src https://map-embed.kaleidr.com; style-src 'self' 'unsafe-inline'

示例中使用 style-src 'unsafe-inline' 的原因并非 Kaleidr 代码本身,而是文档示例使用内联属性 style="display:block; height:480px" 设置元素尺寸。不含 'unsafe-inline' 的策略会忽略内联样式属性。如果你希望继续阻止内联样式,可在自己的 CSS 样式表中设置尺寸:

kaleidr-map { display: block; height: 480px; }

SDK 为 iframe 设置的尺寸不会受到影响,因为它是通过脚本设置的,而样式策略不会阻止这一操作。元素默认的 display:block 也不受影响,因为它不是通过 <style> 标签或 style 属性实现的,因此不需要 'unsafe-inline'。

Nonce、哈希及 strict-dynamic​

  • 脚本。 加载器会将各产品包添加为 <script src> 元素。基于主机的 script-src 可以放行。如果策略使用 nonce 和 'strict-dynamic',请把 nonce 放在加载器脚本标签上。加载器随后添加的脚本会通过 'strict-dynamic' 获得信任,无需单独列出主机。
  • 样式。 SDK 无法为 Chat 和 Editor 注入的样式设置 nonce,其内容会随着版本发布而变化,因此也无法固定哈希。这两个产品需要在 style-src 中使用 'unsafe-inline'。Viewer 和 Tile 不会向你的网页注入样式。
  • 完整性。 不要为加载器脚本标签添加 integrity 属性,因为文件会在原地址更新。参见 CDN 版本管理。

如何识别被阻止的资源​

浏览器会在控制台报告每次阻止操作及触发的策略指令。请对照下表排查。

现象控制台指出的指令需要添加的许可
无法挂载任何内容。Kaleidr is not defined。script-src在 script-src 中允许 https://cdn.kaleidr.com。
元素为空。控制台:[kaleidr:<product>] [kaleidr] failed to load …/embed/v1/<product>.jsscript-src允许相同主机。加载器已被放行(例如通过哈希),但它加载的产品包没有被允许。
Viewer 或 Tile 显示空白区域。frame-src(或 child-src、default-src)在 frame-src 中允许 https://map-embed.kaleidr.com。
Tile、Chat 或 Editor 无法启动,sessions 请求被阻止。connect-src在 connect-src 中允许 https://api.kaleidr.com。
Chat 面板没有样式。style-src在 style-src 中允许 'unsafe-inline'。
Chat 图标或字体缺失。img-src、font-src两处都允许 data:。
Chat 中地点照片或链接旁图标缺失。img-src在 img-src 中允许 https:,或控制台指出的主机。
Editor 面板显示正常,但地图空白。connect-src、worker-src 或 img-src在 connect-src 和 img-src 中允许 https://tile.kaleidr.com,在 worker-src 和 img-src 中允许 blob:。
Editor 没有样式。style-src在 style-src 中允许 'unsafe-inline'。
元素忽略 style 属性中的高度。style-src无需新增许可,改用 CSS 样式表设置尺寸。

并非所有故障都由策略导致。如果 sessions 请求已发出,但返回 401、403 或 429,说明策略放行了请求,是 API 拒绝了它。参见错误参考和 CORS 与允许的来源。

先以仅报告模式上线​

要在严格策略下引入 Kaleidr,又不影响生产环境网页,可按以下流程进行:

  1. 保留现有策略,同时通过 Content-Security-Policy-Report-Only 发布待测试的策略,并配置自己的报告端点。
  2. 测试嵌入组件:打开页面、移动地图,并在 Chat 中提问,确保返回带照片的地点。
  3. 按报告指出的指令允许相应来源。地点照片通常会引入新的图片主机。
  4. 报告中不再出现违反策略的情况后,改用 Content-Security-Policy。

不需要添加的内容​

  • 任何 Kaleidr 产品都不需要 Mapbox、MapTiler 或 OpenStreetMap 主机。
  • script-src 中的 'unsafe-inline'。加载器通过 <script src> 元素加载产品包,从不添加内联脚本。
  • frame-ancestors。该指令控制哪些网站可将你的网页放进 iframe,而不是你的网页可加载哪些 iframe。
  • Viewer 或 Tile iframe 内部资源对应的许可项。

相关页面​