Skip to content

工作区信任插件指南

什么是工作区信任?

工作区信任是一项功能,源于用户在 VS Code 中打开工作区时因意外执行代码而产生的安全风险。例如,考虑一个语言插件,为了提供功能,可能会执行当前加载工作区中的代码。在这种情况下,用户应信任工作区的内容不是恶意的。工作区信任将此决策集中到 VS Code 中,并支持受限模式以防止自动执行代码,这样插件作者就不必自行处理这套基础设施。VS Code 提供静态声明和 API 支持,让插件能够快速接入,而无需在各插件之间编写重复代码。

接入

静态声明

在你的插件 package.json 中,VS Code 支持以下新的 capabilities 属性 untrustedWorkspaces

typescript
capabilities:
  untrustedWorkspaces:
    { supported: true } |
    { supported: false, description: string } |
    { supported: 'limited', description: string, restrictedConfigurations?: string[] }

对于 supported 属性,接受以下值:

  • true - 插件在受限模式下完全受支持,因为它不需要工作区信任即可执行任何功能。它会像以前一样被启用。
  • false - 插件在受限模式下不受支持,因为没有工作区信任它就无法运行。它将保持禁用,直到授予工作区信任为止。
  • 'limited' - 插件的部分功能在受限模式下受支持。对信任敏感的功能应保持禁用,直到授予工作区信任为止。插件可以使用 VS Code API 隐藏或禁用这些功能。可以使用 restrictedConfigurations 属性按信任自动对工作区设置进行门控。

对于 description 属性,必须提供需要信任的原因说明,帮助用户了解哪些功能会被禁用,或者在授予或拒绝工作区信任之前应检查什么。如果 supported 设置为 true,则忽略此属性。

description 属性的值应添加到 package.nls.json 中,然后在 package.json 文件中引用,以支持本地化。

restrictedConfigurations 属性接受一个配置设置 ID 数组。对于列出的设置,在不受信任工作区的受限模式下,插件将不会被赋予工作区定义的值。

如何支持受限模式?

为了帮助插件作者了解工作区信任的范围,以及哪些类型的功能在受限模式下是安全的,这里列出了一些需要考虑的问题。

我的插件有主入口点吗?

如果插件没有 main 入口点(例如主题和语言语法),则该插件不需要工作区信任。对于这类插件,插件作者无需采取任何行动,因为无论工作区是否受信任,它们都会继续运行。

我的插件是否依赖打开的工作区中的文件来提供功能?

这可能意味着诸如可以由工作区设置的设置,或工作区中的实际代码之类的东西。如果插件从不使用工作区的任何内容,那么它可能不需要信任。否则,请查看其他问题。

我的插件是否将工作区的所有内容视为代码?

最常见的例子是使用项目的工作区依赖项,例如存储在本地工作区中的 Node.js 模块。恶意工作区可能会签入一个被篡改的模块版本。因此,这对用户和插件来说都是一种安全风险。此外,插件可能依赖控制插件或其他模块行为的 JavaScript 或其他配置文件。还有很多其他例子,例如执行已打开的代码文件以确定其输出用于错误报告。

我的插件会通过设置项来决定代码执行,代码执行过程会被工作区影响?

你的插件可能会将设置值用作插件所执行 CLI 的标志。如果这些设置被恶意工作区覆盖,它们可能会对你插件进行参数攻击。另一方面,如果设置值仅用于检测特定场景,那么它可能没有安全风险,也不需要工作区信任。例如,插件可能会检查首选 shell 设置的值是 bash 还是 pwsh,以决定显示什么文档。下面的配置(设置)一节提供了关于设置的指导,帮助你为插件找到最佳配置。

这不是可能需要工作区信任的案例的详尽列表。随着我们审查更多插件,我们会更新此列表。在考虑工作区信任时,请使用此列表来思考你的插件可能正在做的类似行为。

如果我不对我的插件做任何更改会怎样?

如上所述,没有在 package.json 中贡献任何内容的插件将被视为不支持工作区信任。当工作区处于受限模式时,它将被禁用,用户会收到通知,说明某些插件因工作区信任而无法工作。这对用户来说是最注重安全的做法。尽管这是默认行为,但最佳实践是设置适当的值,表明作为插件作者,你已经努力保护用户和你的插件免受恶意工作区内容的侵害。

工作区信任 API

如上所述,使用 API 的第一步是将静态声明添加到你的 package.json 中。最简单的接入方法是对 supported 属性使用 false 值。再次说明,即使你什么都不做,这也是默认行为,但这向用户发出了一个良好的信号:你做出了慎重的选择。在这种情况下,你的插件不需要再做其他任何事情。它会在被授予信任之前保持不激活,然后你的插件就会知道它是在用户同意的情况下执行的。不过,如果你的插件只需要对部分功能进行信任,这可能不是最佳选择。

对于希望按工作区信任对其功能进行门控的插件,它们应对 supported 属性使用 'limited' 值,VS Code 提供了以下 API:

typescript
export namespace workspace {
  /**
    * When true, the user has explicitly trusted the contents of the workspace.
    */
  export const isTrusted: boolean;

  /**
    * Event that fires when the current workspace has been trusted.
    */
  export const onDidGrantWorkspaceTrust: Event<void>;
}

使用 isTrusted 属性判断当前工作区是否受信任,使用 onDidGrantWorkspaceTrust 事件监听工作区何时被授予信任。你可以使用此 API 阻止特定的代码路径,并在工作区受信任后执行任何必要的注册。

VS Code 还暴露了一个上下文键 isWorkspaceTrusted,用于 when 子句,如下所述。

配置点

命令、视图或其他 UI

当用户尚未信任工作区时,他们将以受限模式运行,功能仅限于浏览代码。你在受限模式下禁用的任何功能都应从用户界面中隐藏。这可以通过 when 子句上下文 和上下文键 isWorkspaceTrusted 来实现。即使命令没有出现在 UI 中,也仍然可以被调用,因此你应该在插件代码中基于上述 API 阻止执行,或不注册命令。

配置(设置)

首先,你应该审查你的设置,以确定它们是否需要考虑信任。如上所述,工作区可能会为你插件所使用的设置定义一个对用户不利的值。如果你发现容易受攻击的设置,你应该对 supported 属性使用 'limited',并将设置 ID 列在 restrictedConfigurations 数组中。

当你将设置 ID 添加到 restrictedConfigurations 数组时,在受限模式下,VS Code 将只返回该设置的用户定义值。你的插件就不需要对设置做任何额外的代码更改。当授予信任时,除了工作区信任事件外,还会触发配置更改事件。

调试插件

VS Code 会阻止在受限模式下进行调试。因此,调试插件通常不需要要求信任,应该为 supported 属性选择 true。不过,如果你的插件提供了不属于内置调试流程的额外功能、命令或设置,你应该使用 'limited' 并遵循上面的指导。

任务提供者

与调试类似,VS Code 会阻止在受限模式下运行任务。如果你的插件提供了不属于内置任务流程的额外功能、命令或设置,你应该使用 'limited' 并遵循上面的指导。否则,你可以指定 supported: true

测试工作区信任

有关启用和配置工作区信任的详细信息,请参阅工作区信任用户指南