Files
Genarrative/docs/technical/【安全模型】AIWeb工程Runner与预览隔离威胁模型-2026-06-13.md
T
kdletters 071faa482c 统一 Rust 与 TypeScript 格式化门禁
纳入 AGC Cargo workspace 的统一 rustfmt 检查与格式化入口

完成项目 TypeScript/Prettier 与 Rust 全量格式化

修复 Pingora expected executable 门禁的空白敏感误报

同步开发运维文档与 AGC skill pack 格式化忽略规则
2026-09-01 16:28:34 +08:00

7.4 KiB
Raw Blame History

AI Web 工程 Runner 与预览隔离威胁模型

更新时间:2026-06-13

范围

本文约束 /editor/agent 浏览器内 AI Web 工程编辑器的 MVP:固定 React / Vite / TypeScript 静态模板、虚拟文件系统、独立 runner 构建、独立 origin iframe 预览。

不覆盖 HMR、终端 shell、后端服务、任意依赖安装、任意端口代理和正式作品发布。这些能力进入后续阶段前必须单独补威胁模型。

信任边界

用户浏览器主站 origin
  | /editor/agent 编辑器壳
api-server 控制面
  | 最小任务能力
web-project-runner 执行面
  | immutable artifact
preview gateway / 独立 preview origin

关键原则:

  • 主站不执行 AI 工程代码。
  • api-server 不执行 AI 工程代码。
  • runner 无平台密钥、无宿主源码挂载、无 Docker socket。
  • 预览域和主站不同 origin。
  • 预览页拿不到平台 cookie、access token、SpacetimeDB、OSS 写权限或 LLM provider 密钥。

资产与威胁

资产 主要威胁 MVP 缓解
主站 access token / cookie 预览代码同源读取、XSS 窃取 独立 preview originiframe 不带主站 cookie;预览页不能访问主站 storage
用户 Web 工程源码 跨租户读取、snapshot 枚举 project / owner 校验;snapshotId 不可枚举;preview token 绑定 owner / project / snapshot
preview artifact 路径穿越、MIME 错误、旧 token 访问 preview gateway 校验 token;禁止 ..;按白名单 MIME 服务;短期 token 可撤销
runner 临时工作区 逃逸到宿主源码、读取密钥 独立临时目录或容器;非 root;无宿主源码挂载;任务结束销毁
依赖缓存 缓存污染、恶意 postinstall MVP 固定依赖;禁用 scripts;缓存 key 包含模板、Node 版本和 lock digest
api-server / SpacetimeDB runner 横向访问内部服务 runner 默认无内网访问;阻断 api-server 管理端口、SpacetimeDB 和生产数据库
OSS / artifact store 越权读写、签名 URL 泄露 runner 只拿短期只读资产签名或受控写 artifact 能力;日志脱敏
构建日志 泄露环境变量、宿主路径、签名 URL 日志限长、脱敏、错误摘要化;不回显平台密钥
用户浏览器 弹窗逃逸、下载、剪贴板、摄像头、Service Worker 常驻 iframe sandboxCSP;禁用 Service Worker;不授权敏感能力

Runner 限制

runner 必须 fail-closed。每个 job 至少限制:

  • CPU。
  • 内存。
  • 磁盘。
  • 进程数。
  • 打开文件数。
  • 任务时长。
  • 日志大小。
  • artifact 大小。
  • 单文件大小。

执行环境要求:

  • 非 root 用户。
  • 只读基础镜像。
  • 无 Docker socket。
  • 无宿主源码目录挂载。
  • 无平台 .env
  • 无平台 token。
  • 临时工作区任务结束销毁。

构建超时或资源超限时直接 kill,job 进入 failedexpired,保留可展示错误摘要,不推进 active preview。

网络限制

MVP 构建期默认无外网。若模板构建确实需要网络,只允许:

  • 平台受控 npm registry mirror。
  • 平台资产只读签名域。

必须阻断:

  • RFC1918 内网网段。
  • 云 metadata 地址。
  • api-server 管理端口。
  • SpacetimeDB。
  • 生产数据库。
  • Docker daemon。
  • 任意用户配置 registry。

需要覆盖 DNS rebinding 和 HTTP redirect 到内网的情况;不能只按初始 URL 字符串判断。

预览 token

preview token 必须满足:

  • 绑定 ownerUserId
  • 绑定 projectId
  • 绑定 snapshotId
  • 绑定 artifactId
  • 短期有效。
  • 可撤销。
  • 不可枚举。
  • 不能跨租户复用。

访问无权限 artifact 应返回 403 或不可区分的 404,不得泄露其它项目是否存在。

Preview Gateway

gateway 只读服务 immutable artifact。

必须校验:

  • token 有效且未撤销。
  • artifact 属于 token 绑定 snapshot。
  • 请求路径规范化后仍在 artifact 根目录。
  • index.html fallback 只在 SPA 路由范围内生效。
  • MIME 类型来自白名单映射,不信任上传文件名。

必须测试:

  • path traversal。
  • 错误 MIME。
  • HTML 注入。
  • 缓存串租户。
  • 旧 token 访问。
  • artifact 删除后访问。
  • token 过期后访问。

浏览器隔离

iframe sandbox MVP 建议最小化:

sandbox="allow-scripts"

如果后续需要表单或同源能力,必须单独评审。MVP 不允许:

  • allow-same-origin
  • allow-top-navigation
  • allow-downloads
  • allow-popups
  • allow-modals
  • 摄像头。
  • 麦克风。
  • 剪贴板。
  • 地理位置。

CSP 默认收紧:

default-src 'none';
script-src 'self';
style-src 'self' 'unsafe-inline';
img-src 'self' data: blob: https://assets.genarrative.world;
font-src 'self' data:;
connect-src 'none';
frame-ancestors https://www.genarrative.world;
worker-src 'none';

MVP 禁用 Service Worker 和持久缓存,避免恶意预览代码在用户浏览器里长期驻留。

Patch 校验

AI 只能提交结构化 patch

  • create file
  • update file
  • delete file
  • rename file
  • package manifest request

api-server 必须拒绝:

  • 绝对路径。
  • ..
  • 符号链接。
  • .env.npmrc.git.ssh 等隐藏敏感文件。
  • 超深目录。
  • 超大文件。
  • 超大总 snapshot。
  • 二进制膨胀。
  • 大 Data URL。
  • 可执行权限。

前端编辑器可以显示校验错误,但正式准入以 api-server 为准。

依赖供应链

MVP 固定模板依赖,不开放任意 npm。即便用户或 AI 修改 package.json,也必须拒绝或忽略:

  • preinstall
  • install
  • postinstall
  • prepare
  • git: 依赖。
  • file: 依赖。
  • http: / https: tarball 依赖。
  • 私有 registry。
  • lockfile 篡改。
  • native build。
  • 二进制下载型包。

后续开放白名单依赖时,必须加入依赖 resolver、registry mirror、封禁列表、许可证 / 安全扫描和缓存污染防护。

审计与熔断

必须记录:

  • ownerUserId
  • projectId
  • snapshotId
  • jobId
  • artifactId
  • templateKey
  • 依赖 lock digest
  • 构建耗时
  • 资源用量
  • 失败原因摘要
  • runner id
  • preview token 签发和撤销事件

必须提供运维开关:

  • kill job。
  • 禁用项目。
  • 禁用 owner。
  • 禁用模板。
  • 禁用依赖。
  • 清理 artifact。
  • 暂停 runner。
  • 全局关闭 /editor/agent preview build。

发布门禁

临时 preview artifact 不能直接升为线上作品。作品化发布必须:

  • 重新构建。
  • 重新校验 snapshot。
  • 重新签发发布 artifact。
  • 使用 immutable artifact。
  • 走平台作品身份、公开详情、统计和权限链路。