Secret 检测

开发应用程序时经常出现的一个问题是,人们可能会不小心将 secret 提交到他们的远端 Git 存储库,包括密钥、密码、API 令牌和其它敏感信息。任何有权访问仓库的人都可以将这些 secret 用于恶意目的。 以这种方式暴露的 secret 必须被视为已泄露并被替换,这可能代价高昂。 防止 secret 被提交到 Git 仓库很重要。

Secret 检测使用 Gitleaks 工具扫描仓库中的 secret。所有已识别的 secret 都报告在:

  • 合并请求页面部件
  • 流水线的 安全 选项卡
  • 安全仪表盘
  • 拥有项目或群组的正确角色。

Secret Detection in merge request widget

cautionSecret 检测不支持扫描二进制文件。

检测到的 secret

Secret 检测使用包含 90 多种 secret 检测 pattern 的默认规则集。您还可以使用自定义规则集自定义 secret 检测 pattern。

要求

要运行 secret 检测作业,默认情况下,您需要带有 dockerkubernetes executor 的 GitLab Runner。 如果您在 SaaS 上使用共享 runner,则默认启用此功能。

cautionSecret 检测作业需要 Linux/amd64 容器类型。不支持 Windows 容器。
caution如果您使用自己的 runner,请确保安装的 Docker 版本不是 19.03.0

所有级别产品都可以使用 secret 检测

为了让尽可能多的客户可以使用 secret 检测,所有级别均适用。 但是,并非所有功能都适用于每个级别。有关详细信息,请参阅下面的细分表格。

每个级别的功能摘要

不同的产品级别提供不同的功能,如下表所示:

能力 免费版和专业版 旗舰版
配置 secret 检测扫描程序
Customize Secret Detection Settings
下载 JSON 报告
在合并请求部件中查看新发现
在流水线的 安全 选项卡中查看已识别的 secret
管理漏洞
访问安全仪表盘
自定义 Secret Detection 规则集

配置

  • 于 14.0 版本,Secret 检测作业 secret_detection_default_branchsecret_detection 合并为一个作业,secret_detection

Secret 检测由特定分析器secret-detection 作业期间执行。无论您的应用程序的编程语言如何,它都会运行。

Secret 检测分析器包括 Gitleaks 检查。

请注意,如果密码以美元符号 ($) 开头,secret 检测分析器会忽略 URL 中的密码漏洞,因为这可能表明密码是环境变量。 例如,未检测到 https://username:$password@example.com/path/to/repo,而检测到 https://username:password@example.com/path/to/repo

note如果您使用由 Auto DevOps 提供的 Auto Secret Detection,则无需手动配置本节所示的 Secret Detection。

要为 13.1 及更高版本启用 secret 检测,您必须包含作为安装实例的一部分提供的 Secret-Detection.gitlab-ci.yml 模板。

确保您的 .gitlab-ci.yml 文件有一个名为 teststage,并将以下内容添加到您的 .gitlab-ci.yml 文件中:

include:
  - template: Security/Secret-Detection.gitlab-ci.yml

包含的模板在您的 CI/CD 流水线中创建 secret 检测作业,并扫描您项目的源代码中的 secret。

结果保存为 secret 检测报告产物,您可以稍后下载和分析。由于实施限制,我们始终采用可用的最新 secret 检测产物。

支持的发行版

默认扫描器镜像是在基本 Alpine 镜像的基础上构建的,确保大小和可维护性。

FIPS-enabled 镜像

引入于 14.10 版本

提供启用 FIPS 的镜像的 Red Hat UBI 版本。 要使用启用 FIPS 的镜像,您可以:

  • SAST_IMAGE_SUFFIX 设置为-fips
  • -fips 扩展添加到默认镜像名称。

例如:

variables:
  SECRET_DETECTION_IMAGE_SUFFIX: '-fips'

include:
  - template: Security/Secret-Detection.gitlab-ci.yml

通过自动合并请求启用 secret 检测

  • 引入于 13.11 版本,部署在功能标志后,默认启用。
  • 功能标志移除于 14.1 版本。
note此方法在没有现有 .gitlab-ci.yml 文件或最小配置文件的情况下效果最佳。如果您有一个复杂的 GitLab 配置文件,它可能无法解析成功,并且可能会出现错误。

要在项目中启用 Secret Detection,您可以创建一个合并请求:

  1. 在顶部栏上,选择 菜单 > 项目 并找到您的项目。
  2. 在左侧边栏上,选择安全与合规 > 配置
  3. 密码检测 行中,选择 使用合并请求进行配置
  4. 查看并合并合并请求,启用 Secret Detection。

流水线现在包括 Secret Detection 作业。

自定义设置

可以使用 variables 更改 secret 检测扫描设置,通过 .gitlab-ci.yml 中的 CI/CD 变量参数。

caution在将这些更改合并到默认分支之前,应在合并请求中测试极狐GitLab 安全扫描工具的所有自定义。不这样做会产生意想不到的结果,包括大量误报。

要覆盖作业定义(例如,更改 variablesdependencies 等属性),请声明与要覆盖的 secret 检测作业同名的作业,将此新作业放在模板 include 之后,并在其下指定任何其它 key。

caution从 13.0 版本开始,不再支持使用 onlyexcept。覆盖模板时,您必须改用 rules

GIT_DEPTH 变量

GIT_DEPTH CI/CD 变量影响 secret 检测。 Secret 检测分析器依赖于在提交之间生成补丁来扫描 secret 内容。如果覆盖默认值,请确保该值大于 1。如果 MR 中的提交次数大于 GIT_DEPTH 值,Secret Detection 将无法检测

自定义设置示例

在下面的例子中包含了 secret 检测模板,同时设置 SECRET_DETECTION_HISTORIC_SCAN CI/CD 变量为 true,覆盖了 secret_detection 作业:

include:
  - template: Security/Secret-Detection.gitlab-ci.yml

secret_detection:
  variables:
    SECRET_DETECTION_HISTORIC_SCAN: "true"

因为模板是在流水线配置之前取值,所以最后提及的变量优先。

可用的 CI/CD 变量

可以通过定义可用的 CI/CD 变量来自定义 secret 检测:

CI/CD 变量 默认值 描述
SECRET_DETECTION_EXCLUDED_PATHS ”” 根据路径从输出中排除漏洞。这是一个逗号分隔的模式列表,pattern 可以是 glob,也可以是文件或文件夹路径(例如,doc,spec),父目录也匹配 pattern。引入于 13.3 版本。
SECRET_DETECTION_HISTORIC_SCAN false 启用 Gitleaks 历史扫描的标志。
SECRET_DETECTION_IMAGE_SUFFIX ”” 后缀添加到镜像名称。如果设置为 -fips,则使用 FIPS-enabled 镜像进行扫描。有关详细信息,请参阅启用 FIPS 的镜像。引入于 14.10 版本。
SECRET_DETECTION_LOG_OPTIONS ”” git log 选项用于定义提交范围。引入于 15.1 版本。

在以前的版本中,以下变量也可用:

CI/CD 变量 默认值 描述
SECRET_DETECTION_COMMIT_FROM - Gitleaks 扫描从哪个提交开始。移除于 13.5 版本。由 SECRET_DETECTION_COMMITS 代替。
SECRET_DETECTION_COMMIT_TO - Gitleaks 扫描到哪个提交结束。移除于 13.5 版本。由 SECRET_DETECTION_COMMITS 代替。
SECRET_DETECTION_COMMITS - Gitleaks 应该扫描的提交列表。引入于 13.5 版本。移除于 15.0 版本。

自定义规则集

  • 引入于 13.5 版本
  • 于 14.6 版本中添加了对直通链的支持,扩展为包括额外的传递类型的 filegiturl
  • 于 14.8 版本中添加了对覆盖规则的支持。

您可以自定义极狐GitLab 提供的默认 secret 检测规则。 规则集自定义支持以下可同时使用的功能:

自定义允许使用您定义的规则替换默认的 secret 检测规则。

创建自定义规则集:

  1. 在项目的根目录下创建一个 .gitlab 目录,如果该目录尚不存在。
  2. .gitlab 目录下创建一个名为 secret-detection-ruleset.toml 的自定义规则集文件。

禁用预定义的分析器规则

禁用分析器规则:

  1. ruleset 部分的上下文中,将 disabled 标志设置为 true

  2. 在一个或多个 ruleset.identifier 中,列出您要禁用的规则。每个 ruleset.identifier 部分都有:

    • 一个 type 字段,用于命名预定义的规则标识符。
    • 一个 value 字段,用于命名要禁用的规则。
示例:禁用 secret 检测分析器的预定义规则

在以下示例中,通过匹配标识符的 typevalue 将禁用的规则分配给 secrets

[secrets]
  [[secrets.ruleset]]
    disable = true
    [secrets.ruleset.identifier]
      type = "gitleaks_rule_id"
      value = "RSA private key"

覆盖预定义的分析器规则

要覆盖规则:

  1. 在一个或多个 ruleset.identifier 中,列出您要覆盖的规则。每个 ruleset.identifier 部分都有:

    • 一个 type 字段,命名 secret 检测分析器使用的预定义规则标识符。
    • 一个 value 字段,命名要覆盖的规则。
  2. ruleset 部分的 ruleset.override 上下文中,提供要覆盖的键。可以覆盖任何键组合。有效的键是:

    • description
    • message
    • name
    • severity (有效选项:Critical, High, Medium, Low, Unknown, Info)
示例:覆盖 secret 检测分析器的预定义规则

在以下示例中,规则由标识符的 typevalue 匹配,然后被覆盖:

[secrets]
  [[secrets.ruleset]]
    [secrets.ruleset.identifier]
      type = "gitleaks_rule_id"
      value = "RSA private key"
    [secrets.ruleset.override]
      description = "OVERRIDDEN description"
      message = "OVERRIDDEN message"
      name = "OVERRIDDEN name"
      severity = "Info"

合成自定义配置

要创建自定义配置,您可以使用传递链。

  1. secret-detection-ruleset.toml 文件中,执行以下操作之一:

    • 定义自定义规则集:

      [secrets]
        description = 'secrets custom rules configuration'
      
        [[secrets.passthrough]]
          type  = "raw"
          target = "gitleaks.toml"
          value = """\
      title = "gitleaks config"
      # add regexes to the regex table
      [[rules]]
      description = "Test for Raw Custom Rulesets"
      regex = '''Custom Raw Ruleset T[est]{3}'''
      """
      
    • 提供包含自定义规则集的文件的名称:

      [secrets]
        description = 'secrets custom rules configuration'
      
        [[secrets.passthrough]]
          type  = "file"
          target = "gitleaks.toml"
          value = "config/gitleaks.toml"
      

日志级别

要控制日志的详细程度,请设置 SECURE_LOG_LEVEL CI/CD 变量。输出此日志级别或更高级别的消息。引入于 13.1 版本。

从最高到最低严重性,日志记录级别是:

  • fatal
  • error
  • warn
  • info (default)
  • debug

全历史 Secret 检测

12.11 版本引入了对扫描仓库完整历史记录的支持。当您首次在仓库中启用 secret 检测并希望执行完整的 secret 检测扫描时,此新功能特别有用。对完整历史记录运行 secret 检测扫描可能需要很长时间,尤其是对于具有较长 Git 历史记录的大型仓库。我们建议不要将此 CI/CD 变量设置为正常作业定义的一部分。

可以设置一个新的配置变量 (SECRET_DETECTION_HISTORIC_SCAN),更改 secret 检测扫描在仓库的整个 Git 历史记录上运行。

在离线环境中运行 secret 检测

对于通过 Internet 对外部资源进行有限、受限或间歇性访问的环境中的私有化部署实例,需要进行一些调整才能使 secret 检测作业成功运行。

离线 secret 检测要求

要在离线环境中使用 secret 检测,您需要:

  • 带有 dockerkubernetes executor 的 GitLab Runner。
  • 具有本地可用的 secret 检测分析器镜像副本的 Docker 容器镜像库。
  • 配置软件包的证书检查(可选)。

GitLab Runner 有一个默认的 pull policyalways,这意味着即使本地副本可用,运行程序也会尝试从极狐GitLab 容器镜像库中提取 Docker 镜像。如果您更喜欢仅使用本地可用的 Docker 镜像,则可以在离线环境中将 GitLab Runner pull_policy 设置为 if-not-present。但是,如果不在离线环境中,我们建议将拉取策略设置保持为 always,因为这样可以在 CI/CD 流水线中使用更新的扫描程序。

在 Docker 镜像库中提供 GitLab secret 检测分析器镜像

将以下默认 secret 检测分析器镜像从 registry.gitlab.cn 导入您的本地 Docker 容器镜像库

registry.gitlab.cn/security-products/secret-detection:3

将 Docker 镜像导入本地离线 Docker 镜像库的流程取决于您的网络安全策略。请咨询您的 IT 人员,找到可以导入或临时访问外部资源的可接受且已获得批准的流程。这些扫描程序会定期更新新定义,您可以自己进行不定期更新。

有关将 Docker 镜像作为文件保存和传输的详细信息,请参阅 Docker 关于 docker savedocker loaddocker exportdocker import 的文档。

设置 Secret Detection CI/CD 变量,使用本地 Secret Detection 分析器容器镜像

将以下配置添加到您的 .gitlab-ci.yml 文件中。 您必须替换 SECURE_ANALYZERS_PREFIX 引用本地 Docker 容器镜像库:

include:
  - template: Security/Secret-Detection.gitlab-ci.yml

variables:
  SECURE_ANALYZERS_PREFIX: "localhost:5000/analyzers"

Secret Detection 作业现在应该使用 Secret Detection Analyzer Docker 镜像的本地副本,来扫描您的代码并生成安全报告,而无需访问 Internet。

如果需要对自定义证书颁发机构的支持

以下版本中引入了对自定义证书颁发机构的支持。

分析器 版本
secrets v3.0.0

要信任自定义证书颁发机构,请将 ADDITIONAL_CA_CERT_BUNDLE 变量设置为您希望在 SAST 环境中信任的 CA 证书包。 ADDITIONAL_CA_CERT_BUNDLE 值应包含 X.509 PEM 公钥证书的文本表示形式。 例如,要在 .gitlab-ci.yml 文件中配置此值,请使用以下命令:

variables:
  ADDITIONAL_CA_CERT_BUNDLE: |
      -----BEGIN CERTIFICATE-----
      MIIGqTCCBJGgAwIBAgIQI7AVxxVwg2kch4d56XNdDjANBgkqhkiG9w0BAQsFADCB
      ...
      jWgmPqF3vUbZE0EyScetPJquRFRKIesyJuBFMAs=
      -----END CERTIFICATE-----

ADDITIONAL_CA_CERT_BUNDLE 值也可以配置为 UI 中的自定义变量,可配置为 file,需要证书的路径;或者作为变量,需要证书的文本表示。

故障排查

警告消息 gl-secret-detection-report.json: no matching files

查看一般应用程序安全故障排查部分

Error: Couldn't run the gitleaks command: exit status 2

如果流水线从包含 60 次提交的合并请求中触发,而 GIT_DEPTH 变量的值小于该值,则 secret 检测作业将失败,因为克隆深度不足以包含所有相关提交。有关当前默认值的信息,查看流水线配置文档

要确认这是错误原因,请将日志记录级别设置为 debug,然后重新运行流水线。日志应类似于以下示例,出现 “object not found” 是此错误的症状。

ERRO[2020-11-18T18:05:52Z] object not found
[ERRO] [secrets] [2020-11-18T18:05:52Z] ▶ Couldn't run the gitleaks command: exit status 2
[ERRO] [secrets] [2020-11-18T18:05:52Z] ▶ Gitleaks analysis failed: exit status 2

要解决此问题,请将 GIT_DEPTH CI/CD 变量设置为更高的值。要将其仅应用于 secret 检测作业,可以将以下内容添加到您的 .gitlab-ci.yml 文件中:

secret_detection:
  variables:
    GIT_DEPTH: 100

secret-detection 作业失败,消息为 ERR fatal: ambiguous argument

如果您的仓库的默认分支与触发该作业的分支无关,您的 secret-detection 作业可能会因 ERR fatal: ambiguous argument 错误而失败。

要解决此问题,请确保在您的仓库上正确设置默认分支。您应该将其设置为与您运行 secret-detection 作业的分支具有相关历史记录的分支。