🚀 在 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 文件夹加载恶意检查器,而不是全局安装的那个。即使是阅读代码也可能具有欺骗性,攻击者可以使用 Unicode 技巧将恶意代码隐藏在眼皮底下。见鬼,您甚至不必打开任何源代码就被攻陷

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

打地鼠

在上述所有场景中,工具都在按照设计的方式工作,并且在非恶意代码库中,它们非常高效。设置 preLaunchTask 以在调试之前构建应用程序是一个很棒的省时功能,因为您不必在每次更改后都从终端手动构建它。检查器是高度可定制的,可以支持每个团队首选的编码指南和风格(是的,制表符与空格)。预提交钩子让您可以检查是否遗忘了一些东西,或者确保在提交之前运行测试。

现在,您不太可能同时遭受所有这些攻击。事实上,(到目前为止)还没有通过 VS Code 进行的漏洞利用,因为有一个由专家组成的伟大社区,他们让我们意识到何时会出现新的机会。在我们推出工作区信任之前,我们的方法是在每个漏洞点使用本地化的权限提示来解决每个场景。

例如,Jupyter 扩展警告用户,当您在笔记本中打开可视化工具时,嵌入式 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 上,我将我从 Microsoft 组织在 GitHub 上拉取的所有源代码都放在我的 ~/src 文件夹中。我将 ~/src 指定为受信任的文件夹,并且其下的所有内容都天生受到信任。当我打开 ~/src/vscode~src/vscode-docker 等时,它们会在完全信任的情况下打开,因为我信任我的组织编写和使用的代码。

我有一个单独的文件夹,名为 ~/scratch(“scratchpad”的缩写,您显然可以随意命名),我在其中放置所有其他内容,并假设默认情况下它不受信任。然后,我根据文件夹逐个做出信任决定。

为了简化我的工作流程,我将 "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 和问题中与我们联系,我们感谢您的坦诚反馈。根据您的意见,我们在 1.58 版本中进行了一些修复和改进,并期待继续对话。

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

在开放环境中构建 VS Code 的好处之一是,社区可以帮助我们创建尽可能最佳的体验。因此,请告诉我们如何改进流程,帮助您在保持安全的同时尽可能不引人注目。对现有问题发表评论(礼貌地!),提交新问题,或在 Twitter 上 @code 上给我们发推文,我们都在倾听!

谢谢,

Chris 和 VS Code 团队

快乐编码(安全地)!