安全地使用管道变量和参数

Azure DevOps Services |Azure DevOps Server |Azure DevOps Server 2022 |Azure DevOps Server 2020

在 Azure Pipelines 中,您可以通过使用变量和参数来收集用户输入,从而自定义管道执行。 但是,如果无法正确处理,接受用户输入也会带来安全风险。 本文介绍如何在管道中安全地使用变量和参数。

本文是一系列教程的一部分,可帮助实现 Azure Pipelines 的安全措施。 请参阅 安全 Azure Pipelines 以获取详细信息。

先决条件

类别 要求
Azure DevOps - 在使 Azure DevOps 安全和保护 Azure Pipelines 中实施建议。
- 对 YAML 和 Azure Pipelines 的基本知识。 有关详细信息,请参阅 创建第一个管道
权限 - 修改管道权限: 项目管理员组的成员
- 要修改组织权限:成为项目集合管理员组的成员。

变量

变量是提前收集用户输入的便捷方式,有助于在管道步骤之间传输数据。 但是,默认情况下,YAML 任务或脚本中定义的变量是读写的。 上游步骤中设置的值可能会意外地修改下游值。

例如,以下脚本代码片段调用名为 MyConfig 的变量。

msbuild.exe myproj.proj -property:Configuration=$(MyConfig)

如果前面的步骤将 MyConfig 变量值 Debug & deltree /y c:设置为,则运行此脚本会删除生成代理的内容,并可能导致意外后果。 此示例突出显示了此类设置的潜在危险。

系统变量(如 Build.SourcesDirectory 任务输出变量)始终为只读。 还可以通过在脚本或 YAML 任务的日志命令中传递 isReadonly=true 标志,将此任务中创建的变量指定为只读变量。

在 YAML 变量定义中,可以使用特定 readonly 键指定只读变量:

variables:
- name: myReadOnlyVar
  value: myValue
  readonly: true

对机密变量特别小心。 用于设置机密变量的建议方法包括:使用 UI、创建变量组或使用源自 Azure Key Vault 的变量组。 有关详细信息,请参阅 “设置机密变量”。

队列时间变量

在 Azure Pipelines UI 中定义变量时,您可以选择是否允许用户在管道执行期间覆盖该值。 允许用户在队列时设置其值的变量称为队列时变量,只能在 Azure Pipelines 变量 UI 中定义。

在经典管道编辑器中,通过选中 可在队列时间设置 的复选框来定义队列时间变量。 在 YAML 管道中,选择 “允许用户在运行此管道时替代此值”来指定此值。

注释

在发布管道中,在 发布时选择 Settable。 有关详细信息,请参阅 如何在发布时编辑变量?

定义队列时间变量的屏幕截图。

当用户手动运行管道时,他们可以选择队列时间变量并更改值。

更新队列时间变量值的屏幕截图。

用户必须对管道具有 “编辑队列生成”配置 权限才能定义在队列时设置的变量。

限制可在排队时设置的变量

运行管道的 Azure Pipelines UI 和 REST API 为用户提供在队列时添加新变量的方法。 此功能允许用户创建管道作者未定义的变量、重写系统变量并在队列时设置现有变量的值。

在运行管道之前添加队列时间变量的屏幕截图。

若要避免这些能力引起的问题,可以限制可在队列时设置的变量。 可以启用 限制可以在队列时设置的变量 的设置,使用户只能在队列时设置显式标记为 在队列时间可设置 的变量,或允许用户在队列时 覆盖此值

此设置可在组织和项目级别应用。

选项限制可在组织级别的队列时间设置的变量的屏幕截图。

项目集合管理员可以组织设置>管道>设置中的组织级别应用此设置。 当设置为 开启时,只有那些被明确标记为能在队列时设置的变量,才能在组织内所有项目中的所有流水线中于队列时进行设置。

启用的选项限制可在组织级别的队列时间设置的变量的屏幕截图。

项目管理员可以项目设置>管道>设置中的项目级别应用此设置。 当设置为 On 时,只有那些在队列时间显式标记为 可设置 的变量才能在此项目中的所有管道的队列时间进行设置。 如果未在组织级别启用此设置,则可以为单个项目启用或禁用该设置。

如果启用了组织级别设置,则它适用于组织中的所有项目,并且无法在项目级别关闭。

显示无法在项目级别限制队列时间可设置变量选项的屏幕截图。

以下示例显示了经典管道的变量,其中一些变量在 队列时标记为 Settable。 可以在队列时间设置 BuildPlatform 变量,但不能设置 BuildConfiguration

在经典管道中定义变量的屏幕截图。

运行此管道时,只有标记为队列时间可设置的变量会显示在变量屏幕上供选择。

“变量”面板的屏幕截图,设置已开启。

如果在项目或组织级别启用了 可在队列时间设置的“限制”变量 ,则不会显示 “添加变量 ”按钮。

设置开启时,无法在运行时添加变量的屏幕截图。

使用 生成 - 队列运行 - 运行管道 API 对管道运行进行排队,并尝试在队列时设置未标记为 Settable 的变量的值失败,并出现如下错误:

{
  "$id": "1",
  "innerException": null,
  "message": "You can't set the following variables (BuildConfiguration). If you want to be able to set these variables, then edit the pipeline and select Settable at queue time on the variables tab of the pipeline editor.",
  "typeName": "Microsoft.Azure.Pipelines.WebApi.PipelineValidationException, Microsoft.Azure.Pipelines.WebApi",
  "typeKey": "PipelineValidationException",
  "errorCode": 0,
  "eventId": 3000
}

参数

与变量不同,正在运行的管道无法修改管道参数。 参数具有数据类型numberstring,并且可以限制为特定的值的子集。 当管道的用户可配置方面只接受预定义列表中的值时,此限制非常有用,确保管道不接受任意数据。

启用 shell 任务参数验证

管道可以引用管道中执行的任务。 某些任务包括一个 arguments 参数,允许用户为任务指定更多选项。

应用 Enable shell 任务参数验证 设置可 argument 验证内置 shell 任务的参数,以检查是否可以将命令注入脚本的输入。 检查可确保 shell 在执行下面的管道任务时,能正确处理分号、引号和括号等字符。

  • PowerShell
  • BatchScript
  • Bash
  • AzureFileCopy
  • WindowsMachineFileCopy

可以在组织设置>设置下的组织级别或>设置下的项目级别应用>。 如果启用了组织级别设置,则它适用于组织中的所有项目,并且无法在项目级别关闭。

启用此设置后,与参数相关的 arguments 任何验证问题将触发以下错误消息:

Detected characters in arguments that may not be executed correctly by the shell. Please escape special characters using backtick (`).

若要解决此问题,请通过转义错误消息中所示的特殊字符来调整参数。