Simon Willison 这个小实验,钩子很小,问题很大:不可信的小应用到底该不该联网?
全禁,很多应用直接残废。全开,平台等于把出网权限交给一段自己未必看过的代码。他做的事,是让沙箱在两者之间多出一个动作:问一句。
实验里,应用被放进受 CSP 保护的 sandboxed iframe。默认策略是 default-src 'none',也就是先全部关掉。沙箱里的代码尝试 fetch() https://api.inaturalist.org 时,被 CSP 拦下。自定义 fetch() 把这个失败信息传给父页面,父页面弹窗询问:要不要把这个 origin 加入 connect-src 白名单?用户同意后,刷新页面,规则生效。
这里没有“逃逸”。没有“绕过 CSP”。只有宿主系统按规则开门。
它具体跑通了什么
这套流程的价值,不在代码多复杂,而在边界清楚。
CSP 负责拦。sandboxed iframe 负责隔离。自定义 fetch() 负责把一次失败变成可解释事件。父页面负责授权。connect-src 白名单负责控制能连哪里。
| 环节 | 实验里的做法 | 真正的含义 |
|---|---|---|
| 默认策略 | default-src 'none' | 先拒绝,不预设信任 |
| 运行环境 | sandboxed iframe | 把第三方 HTML / 小应用关进容器 |
| 联网请求 | 沙箱内 fetch() API | 只讨论特定出网行为,不是所有能力 |
| 拦截对象 | https://api.inaturalist.org | 按 origin 授权,而不是一口气放开网络 |
| 授权动作 | 父页面弹窗询问是否加入 connect-src | 权限决定交给宿主层 |
| 生效方式 | 加白名单后刷新 | 不是即时魔法,仍受页面生命周期限制 |
这个点很适合几类人看:插件平台开发者、低代码工具开发者、AI 代码沙箱维护者、UGC HTML 托管平台。
这些产品每天面对同一个麻烦:用户想运行别人写的小应用,小应用又经常要调外部 API。平台如果只给“允许全部网络 / 禁止全部网络”两个选项,最后一定会被产品需求逼到墙角。
这个实验给的是第三种姿势:默认关门,按 origin 开门,开门前说明门外是谁。
这对平台开发者有什么用
我更在意的是,它把 CSP 从一条冷规则,拉近到一个权限交互。
这有点像早期操作系统的权限弹窗。应用要访问相机、通讯录、定位,系统先问用户。类比不完全一样:CSP 是页面声明的安全策略,不是浏览器原生权限框架;Simon 这个也是实验,不是标准能力。
但治理思路接近:危险动作不要藏在日志里,要浮到宿主界面上。
对做 AI 代码沙箱的人,这尤其现实。AI 生成的小应用会越来越多,平台不可能逐行审查每个 fetch()。更靠谱的做法,是把出网目标拆出来,让用户或宿主判断:这个小应用为什么要连这个 origin?它是不是当前任务需要的?
对插件平台和低代码平台,动作也很具体:
- 原本打算默认放开网络的团队,至少该考虑按 origin 授权。
- 原本一刀切禁用外部 API 的团队,可以评估这种“申请—批准—刷新”的流程。
- 如果平台面向企业用户,白名单最好能由管理员预设,而不是让每个终端用户临场点 OK。
“明者防祸于未萌。”放到这里,就是不要等小应用已经拿到任意出网能力,再假装靠审计补救。先把联网目标亮出来,很多风险才有被讨论的入口。
不过,别把提示框当安全银弹。
用户点 OK,不等于用户理解风险。授权疲劳会吞掉很多好设计。一个 origin 看起来正常,不代表 API 行为永远可控;一个 API 今天合理,不代表明天不会被滥用。
更硬的限制也在这里:这个实验主要处理 fetch() / connect-src 这一类联网请求。它不解决所有 iframe 安全问题,也不能替代内容隔离、权限边界、日志审计和滥用处置。
还有几个采用前必须想清楚的问题:白名单放在哪里?按用户、按项目,还是按组织?谁能撤销?弹窗文案怎么写,才能让用户知道这次授权影响什么?如果恶意代码反复触发授权请求,平台怎么限流?
这些不是细枝末节。权限系统死掉,通常不是死在拦不住,而是死在问得太多、问得太含糊。
接下来该看哪几件事
这个实验目前最值得观察的,不是它会不会马上变成生产框架,而是这种模式能不能被产品化。
我会看四个变量。
| 观察点 | 为什么重要 |
|---|---|
| CSP 错误捕获边界 | 包装 fetch() 能覆盖多少场景,哪些请求不会走这条链路 |
| 白名单持久化 | 授权如果不能管理、撤销、分层,就会变成一次性弹窗 |
| 企业控制台 | 真正的生产平台往往需要管理员策略,而不是只靠用户点击 |
| 滥用防护 | 恶意小应用可以制造授权疲劳,平台必须限制提示频率和展示上下文 |
这里的分水岭很清楚。
如果它只是弹窗加白名单,那只是一个顺手的小工具。如果它能和项目权限、组织策略、审计日志、撤销机制连起来,就会变成 Web 小应用容器的一块基础设施。
安全沙箱最怕两种懒惰。
一种是安全团队只会说“不”。产品最后会绕开它。
另一种是产品团队只会说“先放开”。事故最后会找回来。
这次实验少见地把中间地带做得很具体:默认拒绝,按源授权,刷新生效,用户和宿主都看得见。它不宏大,但方向对。
真正难的不是让沙箱更凶,而是让它问得准、记得住、撤得回。
