在 VS Code 中尝试

工作区信任

2021 年 7 月 6 日,作者:Chris Dias,@chrisdias

我能相信自己吗?这是自 1.57 版本更新以来,许多 Visual Studio Code 用户面临的根本性问题。

Social image of two versions of Spider-Man pointing at each other

虽然我们无法替您回答这个问题,但我们可以告诉您更多关于我们为何引入工作区信任概念的原因。

但首先,一点背景知识。

猫和键盘,以及坏苹果

互联网充满了欢乐的东西,比如猫在键盘上打字的视频。

对于开发人员来说,互联网也充满了优秀的工具、包和由善良的人构建的开源项目,他们想帮助您解决您已经花了几小时处理的问题。VS Code 等开发工具集成了包管理器、代码检查器、任务运行器、打包器等,以提供愉快的体验,利用不断发展的社区中最新、最优秀的成果。

然而,这种丰富的生态系统带来的生产力往往是我们对开发机器提供的广泛访问的结果。再加上快速的演变以及病毒式的共享和消费,开发工具成为攻击者的诱人目标,特别是考虑到攻击者可以利用我们的机器进一步传播攻击(例如,通过存储在开发机器上的身份验证令牌,甚至通过开发人员编写的软件)。

成为一名开发人员是很有价值的,但也是一项有风险的工作。要为一个项目做贡献,您本质上需要信任其作者,因为运行 npm installmake,构建 Java 或 C# 项目,自动化测试或调试等活动,都意味着项目中的代码将在您的计算机上执行。

我们引入 工作区信任 特性的目标是找到正确的平衡,既能防止少数想要破坏一切的“坏苹果”,又能确保我们能享受到让开发如此有趣的各种美好事物。

嘿,这不只是一个编辑器,对吧?

Twitter comment complaining about Workspace Trust

是的,VS Code 是一个编辑器。然而,像大多数现代编辑器一样,它能够代表您运行工作区中的代码,以提供更丰富的开发体验。

运行和调试代码是显而易见的例子。不太明显的代码执行可能是 preLaunchTask,它在启动应用之前运行,并且可以运行一个构建,该构建有一个额外的任务执行与构建无关的任意代码。那么窃取您加密钱包私钥的 npm 模块呢?进行简单的编辑,就会从 node_modules 文件夹加载恶意 linter,而不是全局安装的那个。即使是阅读代码也可能具有欺骗性,攻击者可以使用 Unicode 技巧来明目张胆地隐藏恶意代码。见鬼,您甚至不需要打开任何源代码 就会被入侵

这里的意图不是要吓跑您远离所有优秀的工具(包括 VS Code)或让您改行。而是要提高认识,即当您从与您没有任何信任关系的人或组织下载代码时,存在许多攻击机会。

打地鼠

在上述所有场景中,工具都在按照设计工作,并且在非恶意代码库中,它们非常高效。设置 preLaunchTask 在调试前构建应用是一个很好的省时方法,因为您不必在每次更改后都手动从终端构建它。Linters 高度可定制,以支持每个团队首选的编码规范和风格(是的,制表符 vs. 空格)。Pre-commit 钩子让您可以检查是否遗漏了什么,或者确保在提交前运行测试。

现在,您不太可能同时受到所有这些攻击。事实上,通过 VS Code 还没有发生过(也还没有)漏洞利用,因为有一个优秀的专家社区,他们在新机会出现时会及时告知我们。在工作区信任出现之前,我们的做法是在每个漏洞点通过本地化的权限提示来解决。

例如,Jupyter 扩展会警告用户,当您打开 Notebook 中的可视化工具时,可以运行嵌入式 JavaScript。

Jupyter Notebook security warning

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

ESLint extension security warning

事实证明,这是一场注定失败的战斗。用户被多个(且略有不同)的权限提示打断,这些提示不适用于整个工作区。我信任你,信任你,信任你,信任你,不信任你,还有你,但只在周二。对我们来说,这是一场持续的打地鼠游戏,通过另一个提示来弥补暴露的每个漏洞。

因此,我们在构建 VS Code 时遵循的模式之一是查看在工具和扩展中实现相似但不一致的体验,看看我们是否可以将其引入核心。信任提示遵循了这一模式,因此我们决定构建一个工具和扩展都可以利用的体验和 API,并希望能提供一个更清晰的用户体验。

信任

现在您了解了代码在您不知情的情况下可以运行的几种方式,希望您能更好地理解我们为什么要提前提出这个问题。

Do you trust the authors notification

我们特别询问您是否信任此工作区的作者,因为 VS Code 无法判断代码是恶意的还是无害的(嘿,我们只认识 1 和 0),它来自哪里,您是否打算为项目贡献等。

另一方面,您很聪明,您知道代码来自哪里:您(好的),您的公司(可能好的),您的朋友 Kai(取决于情况),或者互联网上某个陌生人(绝对不行)。

这些知识有助于使工具更智能。如果您信任作者,太棒了!工具和扩展获得了绿灯,可以发挥它们的作用并提供神奇的体验,我们不会再打扰您。

如果您不信任,您就是在告诉我们:VS Code,请小心,不要执行任何代码。这被称为受限模式,在此模式下,潜在的有害功能被禁用,以便您可以更安全地浏览代码并最终做出明智的决定。

但那个对话框!

我们听到您的反馈了,这个模态对话框确实很大,而且每打开一个新文件夹都会弹出,除非您采取行动进行配置。

我们并非一开始就采用了这种设计。我们回顾了ESLint 模态对话框事件,并自问是否可以通过使用视觉线索和单个延迟通知来提供一种非阻塞的体验,并尽可能延长延迟时间。我们希望做到不显眼,以受限模式启动(在您没有真正注意到的情况下),并在最后一刻提示信任。

我们引入了“被动”信任通知,您可以通过它告诉我们您是否信任该工作区。我们尝试了各种 UI 处理方式来表明工作区不受信任,包括增强设置齿轮图标和引入新的安全图标。

Several early versions of a security icons and badges

如果您使用 Insiders 构建版本,您将获得 VS Code 中新体验的最新迭代,就像我们现在讨论的工作区信任一样。Insiders 版本每天发布,我们使用它来构建 VS Code。

这个想法是用户(您!)可以按自己的意愿决定何时授予或拒绝工作区的信任。只有当工具或扩展真正需要访问时,我们才会弹出通知询问您是否信任该工作区。

Workspace Trust required prompt

现在,我相信很多人都会同意,VS Code 有点患有所谓的“通知疲劳”(我保证我们正在努力解决😊)。在我们的测试中,我们看到人们根本忽略了通知。用户没有注意到齿轮图标上的通知,甚至没有注意到新的安全图标。使用数据显示,通过被动通知授予信任的比率非常低。在用户研究中,我们观察到人们花费所有时间思考他们弄坏了什么东西,然后花费时间排除故障,试图回到他们预期的状态。

我们原本打算做到不显眼并尽可能延迟,但现实是,处于受限模式时,产品感觉像是坏掉了,人们以为是自己的问题。这对我们双方来说都不是一个好情况。

将控制权交给你

信任一个文件夹的决定对 VS Code 的功能有着根本性的影响,因此经过所有的研究,我们决定正确的做法是当您尝试打开一个文件夹时立即询问信任问题。由于模态对话框具有干扰性,我们试图通过增强对话框的功能来平衡这一点,以便您可以回答几个问题,最终在日常工作中看到提示的频率大大降低。

通过我们自己的内部测试以及对其他开发人员的采访,我们发现人们通常有一个主要文件夹,他们在其中放置所有他们信任的源代码。因此,我们添加了直接从对话框中信任文件夹的功能。您可以一键信任它及其所有子文件夹,然后您就不会再次看到信任提示了。

Trust parent folder checkbox

工作区信任编辑器

工作区信任编辑器让您可以进一步控制您信任的内容,并且将在 1.58 版本中进行更新,以便更容易地根据您的需求配置该特性。

由于您可以自定义行为,所以有多种方式可以打开信任编辑器😊。点击受限模式状态栏消息,受限模式横幅中的管理链接,齿轮菜单,或打开命令面板(F1)并使用工作区:管理工作区信任命令。

在工作区信任编辑器中,您可以信任当前文件夹、父文件夹(及其所有子文件夹),以及机器上的任何文件夹。

Workspace Trust editor with annotations

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

Workspace Trust settings via @tag:workspaceTrust

我们如何使用工作区信任

没有人喜欢刷牙,但我们还是会做,因为我们知道这是对的。没有人想考虑安全问题,但我们也知道这是对的。通过自定义体验,您可以保持愉快的开发体验,同时保护自己免受开发中固有的威胁(刷牙有趣吗?!)。

VS Code 团队的大多数人都是从一个顶级文件夹开始工作,他们在这里处理他们信任的源代码。例如,在我的 Mac 上,我将从 GitHub 上的 Microsoft 组织拉取的所有源代码放在我的 ~/src 文件夹中。我将 ~/src 指定为信任的文件夹,其下的所有内容都被视为信任。当我打开 ~/src/vscode~src/vscode-docker 等时,它们都会以完全信任的方式打开,因为我信任我的组织编写和使用的代码。

我有一个独立的文件夹叫做 ~/scratch(“草稿本”的缩写,您显然可以随意命名),我把所有其他东西都放在这里,并默认认为它是不受信任的。然后,我逐个文件夹地决定信任。

为了简化我的工作流程,我将 "security.workspace.trust.startupPrompt" 设置为 "never"

Workspace Trust Startup Prompt setting as never

有了这个设置,我不会收到模态对话框的提示,工作区会直接以受限模式打开。我已经决定 ~src/scratch 文件夹是不受信任的,所以每次我打开一个子文件夹时都没有必要再提示我。如果我决定信任我正在阅读或编写的代码,我可以通过两次快速点击(VS Code 顶部的受限模式通知,然后点击信任按钮)在该文件夹上启用信任。

在我的 Windows 机器上,情况稍微有趣一些。我通常在运行于 Windows Subsystem for Linux (WSL) 的 Ubuntu 镜像中工作,使用的是 WSL 扩展。我信任 Linux 上的 ~/src 文件夹,我也信任 Windows 端的 d:\src 文件夹。

Trust Folders & Workspaces list with WSL trusted folders

团队中有几个人更进一步,也将顶部的受限模式横幅关闭("security.workspace.trust.banner": "never"),只留下状态栏通知。对我来说这有点过了,顶部的横幅让我在从互联网上拉取内容时保持警惕,提醒我保持警醒。

开源太棒了

我们知道 VS Code 是您用来完成“真正”工作的工具,我们引入的任何障碍或阻碍只会减慢您构建和发布下一个独角兽的速度。你们中的许多人在 Twitter、Reddit 和 issues 中抽出时间与我们联系,我们感谢你们坦诚的反馈。我们根据您的输入在 1.58 版本中进行了许多修复和改进,并期待继续对话。

展望未来,我们希望帮助扩展作者避免任意代码执行,并在受限模式下提供更多功能。我们的路线图指出了我们正在与 Visual Studio Marketplace 团队一起努力为扩展生态系统带来额外安全性的工作(我们称之为“信任的扩展”),包括验证发布者、签名和特定于平台的扩展。简而言之,您可以认为工作区信任有助于好的扩展做出好的决策。信任的扩展将帮助您免受坏扩展的侵害。

在开放环境中构建 VS Code 的好处之一是社区可以帮助我们创造最佳体验。因此,请告诉我们如何改进流程,在保持您安全的同时,尽量做到不显眼。请(礼貌地!)在现有 issue 上评论,提交新 issue,或通过 @code 给我们发推特,我们正在倾听!

谢谢,

Chris 和 VS Code 团队

快乐编程(安全地)!