工作区信任
2021 年 7 月 6 日,作者 Chris Dias,@chrisdias
我能相信自己吗?自 1.57 更新以来,这是许多 Visual Studio Code 用户面临的生存问题。

虽然我们无法为您回答这个问题,但我们可以告诉您更多关于为什么我们引入了工作区信任概念的原因。
但首先,了解一些背景知识。
猫和键盘,以及害群之马
互联网上充满了快乐的事物,比如猫在键盘上打字的视频。
对于开发者来说,它也充满了由好人构建的工具、包和开源项目,他们希望帮助您解决您已经困扰了几个小时的问题。像 VS Code 这样的开发工具集成了包管理器、代码 Linter、任务运行器、打包器等,以提供愉快的体验,利用不断发展的社区中最新和最伟大的进步。
然而,这个丰富生态系统所带来的生产力,往往是我们为开发机器提供的广泛访问权限所致。再加上快速演进和病毒式传播与消费,开发工具成为引人注目的攻击目标,尤其是考虑到攻击者可以利用我们的机器进一步传播攻击(例如,通过存储在开发机器上的身份验证令牌,甚至通过开发者编写的软件)。
成为一名开发者是很有价值的,但它也是一项有风险的业务。要为一个项目做贡献,你本质上需要信任它的作者,因为运行 `npm install` 或 `make`、构建 Java 或 C# 项目、自动化测试或调试等活动,都意味着项目中的代码正在你的电脑上执行。
我们推出 工作区信任 功能的目标是找到合适的平衡点,既能抵御少数“害群之马”破坏所有人的乐趣,又能确保我们能继续拥有让开发变得如此有趣的一切美好事物。
嘿,它只是一个编辑器,对吧?

是的,VS Code 是一个编辑器。然而,像大多数现代编辑器一样,它能够代表您运行工作区中的代码,以提供更丰富的开发体验。
运行和调试代码是一个显而易见的例子。不那么明显的代码执行可能是 `preLaunchTask`,它在启动应用程序之前运行,并且可以运行一个构建,该构建有一个额外任务,执行与构建无关的任意代码。那个窃取您加密钱包私钥的 npm 模块呢?进行一个简单的编辑,一个恶意的 Linter 就会从 `node_modules` 文件夹中加载,而不是全局安装的那个。甚至阅读代码也可能具有欺骗性,攻击者可以使用 Unicode 技巧 隐藏恶意代码于明处。见鬼,你甚至不必打开任何源代码 就会被攻破。
这里的目的不是为了吓跑您,让您远离所有优秀的工具(包括 VS Code),也不是为了让您改行。而是为了提高您的意识,当您从互联网上下载由您没有任何信任关系的个人或组织编写的代码时,存在许多攻击机会。
打地鼠
在上述所有场景中,工具都按设计工作,在非恶意代码库中,它们都具有极高的生产力。设置 `preLaunchTask` 在调试前构建应用程序可以节省大量时间,因为您不必在每次更改后都从终端手动构建它。Linter 具有高度可定制性,以支持每个团队首选的编码指南和风格(是的,制表符与空格)。预提交钩子可以让您检查是否遗漏了什么,或者确保在提交前运行测试。
现在,你不太可能同时受到所有这些攻击。事实上,目前还没有通过 VS Code 的漏洞利用(尚未),因为有一个庞大的专家社区,他们会在新机会出现时提醒我们。在工作区信任之前,我们的方法是在漏洞点通过局部权限提示来解决每个场景。
例如,Jupyter 扩展会警告用户,当您在 Notebook 中打开可视化器时,嵌入的 JavaScript 可能会运行。

ESLint 漏洞是一个 大麻烦,因为它在工作区加载时运行(这是我们的第一个模态对话框)。

事实证明,这是一场注定要失败的战斗。用户会被多个(且略有不同)的权限提示打断,这些提示并不适用于整个工作区。我信任你、你、你、你,不信任你,还有你,但只在周二。对我们来说,这是一场持续的 打地鼠 游戏,每当一个漏洞暴露时,就用另一个提示来堵塞。
因此,我们构建 VS Code 时遵循的模式之一是,查看工具和扩展中哪些体验的实现方式类似但不一致,然后看我们是否能将其纳入核心。信任提示遵循了这种模式,所以我们决定着手构建一个工具和扩展都可以利用的体验和 API,并提供(希望)更清晰的用户体验。
信任
既然您已经了解了代码在您不知情的情况下运行的各种方式,希望您能更好地理解我们为什么要提前提出这个问题。

我们特意询问您是否信任此工作区的作者,因为 VS Code 无法判断代码是否恶意(嘿,我们只知道 1 和 0),它来自哪里,您是否打算为项目做贡献等等。
另一方面,您很聪明,您知道代码来自哪里:您(好的),您的公司(可能好的),您的朋友 Kai(取决于情况),或者互联网上的某个陌生人(绝对不行)。
这些知识有助于使工具更智能。如果您信任作者,那就太好了!工具和扩展程序获得绿灯,可以做它们的事情并提供神奇的体验,我们不会再打扰您。
如果您不信任,您就是在告诉我们:**小心点,VS Code,不要执行任何代码**。这就是我们所说的**受限模式**,在这种模式下,潜在的有害功能被禁用,这样您就可以更安全地浏览代码,并最终做出明智的决定。
但是那个对话框!
我们听到了,模态对话框相当大,除非您采取操作进行配置,否则每次打开新文件夹时都会弹出。
我们最初并没有采用这种设计。我们研究了 ESLint 模态对话框的漫长历程,并自问我们能否通过视觉线索和尽可能延迟的单个通知提示,提供一种非阻塞的体验。我们希望做到不打扰用户,以受限模式启动(让您几乎察觉不到),并在最后一刻提示信任。
我们引入了一个“被动”信任通知,您可以通过它告诉我们您是否信任工作区。我们循环尝试了各种 UI 处理方式来表示工作区不受信任,包括增强设置齿轮图标和引入新的安全图标。
![]()
如果您使用 Insider 版本,您将获得 VS Code 中新体验的最新迭代,就像我们正在讨论的工作区信任一样。Insider 版本每天发布,我们用它来构建 VS Code。
其理念是用户(您!)可以“**按自己的意愿**”决定何时授予或拒绝工作区的信任。当工具或扩展真正需要访问时,我们才会弹出通知询问您是否信任该工作区。

现在,我敢肯定你们很多人都会同意,VS Code 确实有点“通知疲劳”(我保证我们正在努力解决这个问题😊)。在我们的测试中,我们发现人们只是忽略了通知。用户没有看到齿轮上的通知,甚至也没有看到新的安全图标。使用数据显示,通过被动通知授予信任的比率非常低。在用户研究中,我们观察到人们把所有时间都花在思考自己是不是弄坏了什么,然后花时间进行故障排除,试图恢复到他们预期的状态。
我们本意是不打扰用户并尽可能延迟,但现实是,在受限模式下,产品感觉像是坏了,人们认为这是他们的错。这对我们双方来说都不是一个好局面。
让您掌控一切
信任一个文件夹的决定对 VS Code 的功能具有根本性的影响,因此经过所有研究,我们决定在您尝试打开一个文件夹时立即提出信任问题是正确的做法。因为模态对话框会打断用户,我们试图通过使对话框功能强大来平衡这一点,以便您可以回答几个问题,最终在日常工作中更少地看到该提示。
通过我们自己的内部测试以及与其他开发者的访谈,我们发现人们通常有一个主要的文件夹,他们将所有源代码放在其中并认为它是可信的。因此,我们添加了直接从对话框中信任**父**文件夹的功能。您可以一键信任它及其所有子文件夹,然后您将不会再次看到信任提示。

工作区信任编辑器
工作区信任编辑器让您可以更好地控制信任内容,并且将在 1.58 版本中进行更新,使其更容易根据您的需求配置该功能。
因为您可以自定义行为,所以有多种方法可以进入信任编辑器 😊。点击**受限模式**状态栏消息,受限模式横幅中的**管理**链接,齿轮菜单,或者打开命令面板 (F1) 并使用**工作区:管理工作区信任**命令。
在工作区信任编辑器中,您可以信任当前文件夹、父文件夹(以及所有子文件夹),以及机器上的任何文件夹。

您还可以快速跳转到所有工作区信任设置,以微调体验。

我们如何使用工作区信任
没有人喜欢刷牙,但我们还是会做,因为我们知道这是正确的事情。没有人想考虑安全问题,但我们也知道这是正确的事情。通过定制体验,您可以保持愉快的开发体验,同时保护自己免受开发固有的威胁(有趣的刷牙?!)。
VS Code 团队的大多数成员都从一个顶级文件夹开始,在那里处理他们信任的源代码。例如,在我的 Mac 上,我将从 GitHub 上的 Microsoft 组织拉取的所有源代码都放在我的 `~/src` 文件夹中。我将 `~/src` 指定为受信任的文件夹,其下的所有内容都默认是受信任的。当我打开 `~/src/vscode` 或 `~src/vscode-docker` 等时,它们会以完全信任的方式打开,因为我信任我的组织编写和使用的代码。
我有一个单独的文件夹,叫做 `~/scratch`(“草稿”的缩写,您显然可以随意命名),我把所有其他东西都放在里面,并默认假设它们不受信任。然后,我逐个文件夹地做出信任决定。
为了简化我的工作流程,我将 `"security.workspace.trust.startupPrompt"` 设置为 `"never"`。

通过此设置,我不会收到模态对话框的提示,工作区会直接以受限模式打开。我已经决定 `~src/scratch` 文件夹不受信任,因此每次我打开子文件夹时都没有必要提示我。如果我决定信任我正在阅读或编写的代码,我可以通过两次快速点击在文件夹上启用它(VS Code 顶部受限模式通知,然后是信任按钮)。
在我的 Windows 机器上,情况有点意思。我通常在运行于 Windows Subsystem for Linux (WSL) 上的 Ubuntu 镜像中工作,使用 WSL 扩展。我信任 Linux 上的 `~/src` 文件夹,也信任 Windows 上的 `d:\src` 文件夹。

团队中有些人更进一步,甚至关闭了顶部的受限模式横幅(`"security.workspace.trust.banner": "never"`),只留下状态栏通知。对我来说,这太过头了,顶部的横幅让我保持警惕,并提醒我在从互联网获取内容时要小心。
开源棒极了
我们知道 VS Code 是您完成“真正”工作的工具,我们引入的任何障碍或阻碍只会减慢您构建和发布下一个独角兽的速度。许多人花时间在 Twitter、Reddit 和 issues 中联系我们,我们感谢您坦诚的反馈。我们根据您的意见在 1.58 版本中进行了许多 修复和改进,并期待继续对话。
展望未来,我们希望帮助 扩展作者 避免任意代码执行,并在受限模式下提供更多功能。我们的 路线图 指出了我们与 Visual Studio Marketplace 团队正在进行的工作,旨在为扩展生态系统带来额外的安全性(我们称之为“受信任扩展”),包括经过验证的发布者、签名和特定于平台的扩展。简而言之,您可以将工作区信任视为帮助优秀的扩展做出良好决策。受信任扩展将帮助您免受不良扩展的侵害。
开放构建 VS Code 的好处之一是,社区可以帮助我们创造最好的体验。因此,请告诉我们如何改进流程,在尽可能不打扰您的情况下,帮助您保持安全。请(礼貌地!)在 现有问题 上评论,提交新问题,或在 Twitter 上@我们 @code,我们正在倾听!
谢谢,
Chris 和 VS Code 团队
快乐编码(安全地)!