工作区信任
2021年7月6日,作者 Chris Dias, @chrisdias
我能信任我自己吗?这是自 1.57 版本更新以来,许多 Visual Studio Code 用户面临的终极哲学问题。
虽然我们无法替您回答这个问题,但我们可以告诉您更多关于我们为何引入“工作区信任”这一概念的信息。
不过,首先来点背景介绍。
猫和键盘,以及害群之马
互联网上充满了快乐的事物,比如猫在键盘上打字的视频。
对于开发者而言,互联网也充满了各种工具、软件包和开源项目。这些都是由善良的人们创建的,他们希望帮助您解决那个已经困扰了您数小时的问题。像 VS Code 这样的开发工具集成了包管理器、代码检查工具、任务运行器、打包工具等,利用不断发展的社区中最新、最伟大的技术进步,提供了愉悦的开发体验。
然而,这个丰富生态系统所带来的高效率,往往是建立在我们为开发设备提供了广泛访问权限的基础之上。再加上快速的演进、病毒式的分享和使用,开发工具成为了一个诱人的攻击目标,尤其是考虑到攻击者可以利用我们的设备进一步传播攻击(例如,通过存储在开发者设备上的身份验证令牌,甚至通过开发者编写的软件)。
成为一名开发者虽然收获满满,但也是一项有风险的工作。要为一个项目做贡献,您天生就需要信任其作者,因为诸如运行 npm install
或 make
、构建 Java 或 C# 项目、自动化测试或调试等活动,都意味着项目中的代码正在您的计算机上执行。
我们推出工作区信任功能的目标是找到一个恰当的平衡点:既能防范那些想破坏一切的少数“害群之马”,又能继续确保我们能拥有所有那些让开发充满乐趣的美好事物。
嘿,这不就是个编辑器吗?
是的,VS Code 是一个编辑器。然而,和大多数现代编辑器一样,它能够代表您运行工作区中的代码,以提供更丰富的开发体验。
运行和调试代码是显而易见的例子。但有些代码执行可能不那么明显,比如在启动应用前运行的 preLaunchTask
,它可以运行一个构建任务,而这个任务里可能包含一个与构建无关、执行任意代码的额外任务。又比如,某个 npm 模块可能会窃取您的加密钱包私钥?您只是做了一个简单的编辑,一个恶意的 linter 就从 node_modules
文件夹加载了,而不是您全局安装的那个。甚至阅读代码也可能具有欺骗性,攻击者可以使用 Unicode 技巧将恶意代码隐藏在众目睽睽之下。天啊,您甚至无需打开任何源代码就可能被攻击。
这里的目的不是要吓得您远离所有优秀的工具(包括 VS Code),也不是要让您改行。而是为了提高您的意识:当您从互联网上下载由您不具备任何信任关系的个人或组织编写的代码时,存在着许多攻击的机会。
打地鼠游戏
在上述所有场景中,这些工具都按其设计的方式工作,并且在非恶意的代码库中,它们极其高效。设置一个 preLaunchTask
在调试前构建应用能极大地节省时间,因为您不必在每次更改后都手动从终端构建。Linter 高度可定制,以支持每个团队偏好的编码规范和风格(是的,包括制表符与空格之争)。提交前挂钩(Pre-commit hooks)可以检查您是否忘记了什么,或确保在提交前运行测试。
现在,您不太可能同时遭受所有这些攻击。事实上,到目前为止还没有通过 VS Code 发生的攻击事件,因为有一个强大的专家社区,当新的风险出现时,他们会让我们知晓。在“工作区信任”功能出现之前,我们的方法是在每个漏洞点通过一个局部的权限提示来解决问题。
例如,Jupyter 扩展会警告用户,当您在 Notebook 中打开可视化工具时,嵌入的 JavaScript 可能会运行。
ESLint 漏洞是一个棘手的问题,因为它在工作区加载时就会运行(这是我们的第一个模态对话框)。
事实证明,这是一场注定要失败的战斗。用户会被多个(且略有不同)的权限提示打断,而这些提示并不适用于整个工作区。我信任你、你、你,不信任你,还有你,但只在周二信任。对我们来说,这就像一场永无止境的打地鼠游戏,每当一个漏洞暴露出来,就用又一个提示框去堵上它。
因此,我们在构建 VS Code 时遵循的一个模式是:观察哪些体验在整个工具和扩展中以相似但又不一致的方式实现,然后看是否能将其整合到核心功能中。信任提示就遵循了这个模式,所以我们决定着手构建一个工具和扩展都可以利用的体验和 API,并希望提供一个更清晰的用户体验。
信任
现在您已经了解了代码可能在您不知情的情况下运行的多种方式,希望您能更好地理解为什么我们一开始就提出这个问题。
我们特意询问您是否信任此工作区的作者,因为 VS Code 无法判断代码是否恶意(嘿,我们只认识 1 和 0),也无法知道它来自哪里,或者您是否打算为该项目做贡献等。
而您,则很聪明,您知道代码的来源:您自己(好的)、您的公司(可能还行)、您的朋友小凯(看情况),或者互联网上的某个陌生人(绝对不行)。
这些信息有助于让工具变得更智能。如果您信任作者,太好了!工具和扩展就获得了绿灯,可以尽情发挥,提供神奇的体验,而且我们不会再打扰您。
如果您不信任,您就是在告诉我们:小心点 VS Code,不要执行任何代码。这就是我们所说的受限模式,在这种模式下,潜在有害的功能会被禁用,以便您可以更安全地浏览代码,并最终做出明智的决定。
但是那个对话框!
我们听到了您的心声,那个模态对话框确实很大,而且每次打开新文件夹都会出现,除非您采取行动去配置它。
我们一开始的设计并非如此。我们研究了 ESLint 模态对话框的风波,并自问是否能通过视觉线索和单个、尽可能延迟弹出的通知提示,来提供一种非阻塞的体验。我们希望做到不打扰用户,以受限模式启动(让您几乎察觉不到),然后在最后一刻才提示信任请求。
我们引入了一种“被动”信任通知,您可以通过它告诉我们是否信任该工作区。我们尝试了各种 UI 处理方式来表明工作区不受信任,包括在“设置”齿轮图标上增加标记,以及引入一个新的安全图标。
如果您使用 Insiders 构建版本,您将获得 VS Code 新体验的最新迭代,就像我们正在讨论的“工作区信任”一样。Insiders 版本每日发布,我们用它来构建 VS Code。
其理念是让用户(您!)可以根据自己的节奏,决定何时授予或拒绝工作区的信任。只有当工具或扩展确实需要访问权限时,我们才会弹出一个通知,询问您是否信任该工作区。
现在,我相信你们中的许多人都会同意,VS Code 有点我们所说的“通知疲劳症”(我保证我们正在解决这个问题 😊)。在我们的测试中,我们发现人们根本不理会这个通知。用户没有看到齿轮图标上的通知,甚至没有看到新的安全图标。使用数据显示,通过被动通知授予信任的比率非常低。在用户研究中,我们观察到人们把所有时间都花在以为自己弄坏了什么东西上,然后又花时间排查故障,试图回到他们预期的状态。
我们本想做到不打扰用户并尽可能延迟提示,但现实是,在受限模式下,产品感觉像是坏了,而人们认为是自己的错。这对我们双方来说都不是一个好的处境。
让您掌控一切
信任一个文件夹的决定对 VS Code 的功能有着根本性的影响,因此经过所有研究后,我们认为正确的做法是在您尝试打开文件夹时立即询问信任问题。因为模态对话框具有干扰性,我们试图通过让对话框功能强大来平衡这一点,这样您只需回答几个问题,最终在日常工作中就能大大减少看到提示的频率。
通过我们自己的内部试用(dogfooding)以及与其他开发者的访谈,我们发现人们通常有一个主文件夹,用来存放他们所有的源代码,并认为它是可信的。因此,我们添加了直接从对话框中信任父文件夹的功能。您只需一次点击就可以信任它及其所有子文件夹,然后您就不会再看到信任提示了。
工作区信任编辑器
工作区信任编辑器让您对信任的内容有更多的控制权,并将在 1.58 版本中更新,使其更容易配置以满足您的需求。
因为您可以自定义其行为,所以有很多方法可以进入信任编辑器 😊。点击状态栏中的受限模式消息、受限模式横幅中的管理链接、齿轮菜单,或者打开命令面板(F1)并使用 Workspaces: Manage Workspace Trust(工作区:管理工作区信任)命令。
在工作区信任编辑器中,您可以信任当前文件夹、父文件夹(及其所有子文件夹),以及计算机上的任何文件夹。
您还可以快速跳转到所有工作区信任设置,以微调体验。
我们如何使用工作区信任
没人喜欢用牙线,但我们还是会用,因为我们知道这是正确的事。没人愿意考虑安全问题,但我们也知道这是正确的事。通过自定义体验,您可以在保持开发体验愉悦的同时,保护自己免受开发中固有的威胁(有趣的牙线?!)。
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 和 issue 中联系我们,我们感谢您坦诚的反馈。基于您的意见,我们在 1.58 版本中进行了许多修复和改进,并期待继续这场对话。
展望未来,我们希望帮助扩展作者避免任意代码执行,并在受限模式下运行时提供更多功能。我们的路线图中提到了我们正在与 Visual Studio Marketplace 团队合作,为扩展生态系统带来额外的安全性(我们称之为“受信任的扩展”),包括验证发布者、签名和特定于平台的扩展。简而言之,您可以将“工作区信任”视为帮助好的扩展做出好的决定。而“受信任的扩展”将帮助您防范坏的扩展。
以开放的方式构建 VS Code 的好处之一是社区可以帮助我们创造最佳的体验。所以,请告诉我们如何改进这个流程,在尽可能不打扰您的情况下帮助您保持安全。请(礼貌地!)在现有的 issue 中评论,提交一个新的,或者在 Twitter 上 @code 我们,我们正在倾听!
谢谢,
Chris 和 VS Code 团队
(安全地)编码愉快!