Secret 检测

人们有时会不小心将密钥或 API 令牌等 secret 提交到 Git 仓库。 将敏感值推送到远端仓库后,任何有权访问仓库的人都可以出于恶意目的冒充 secret 的授权用户。 大多数组织都要求撤销和替换暴露的 secret 来解决此风险。

Secret 检测会扫描您的仓库,帮助防止您的 secret 被泄露。 Secret 检测扫描适用于所有文本文件,无论使用何种语言或框架。

启用 secret 检测后,扫描将在名为 secret_detection 的 CI/CD 作业中运行。 您可以运行扫描并查看 Secret 检测 JSON 报告产物

使用旗舰版时,极狐GitLab 还会处理 secret 检测结果,您可以:

检测到的 secret

默认规则集包含超过 100 种样式。

大多数 Secret 检测样式搜索特定类型的 secret。 许多服务在其 secret 中添加前缀或其他结构细节,以便在它们泄露时能够被识别。 例如,极狐GitLab 默认向项目、群组和个人访问令牌添加 glpat- 前缀

为了提供更可靠、可信度更高的结果,Secret 检测仅在 URL 等特定上下文中查找密码或其他非结构化 secret。

添加新样式

要在您的仓库中搜索其他类型的 secret,您可以配置一个自定义规则集

每个级别的功能

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

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

启用 Secret 检测

先决条件

  • 带有 dockerkubernetes 执行器的极狐GitLab Runner。如果您在 SaaS 上使用共享运行器,则默认启用此功能。
  • 如果您使用自己的 runner,请确保安装的 Docker 版本不是 19.03.0
  • Linux/amd64 容器类型。不支持 Windows 容器。
  • 极狐GitLab CI/CD 配置 (.gitlab-ci.yml) 必须包含 test 阶段。

要启用 Secret 检测,您可以:

手动编辑 .gitlab.ci.yml 文件

此方法需要您手动编辑现有的 .gitlab-ci.yml 文件。如果您的极狐GitLab CI/CD 配置文件很复杂,请使用此方法。

  1. 在顶部栏中,选择 主菜单 > 项目 并找到您的项目。
  2. 在左侧边栏中,选择 CI/CD > 编辑器
  3. 将以下内容复制并粘贴到 .gitlab-ci.yml 文件的底部:

    include:
      - template: Jobs/Secret-Detection.gitlab-ci.yml
    
  4. 选择 验证 选项卡,然后选择 验证流水线。显示消息 模拟成功完成 表示文件有效。
  5. 选择 编辑 选项卡。
  6. 可选。在 提交消息 文本框中,自定义提交消息。
  7. 分支 文本框中,输入默认分支的名称。
  8. 选择 提交更改

流水线现在包括 Secret 检测作业。

使用自动配置的合并请求

  • 引入于 13.11 版本,部署在功能标志后,默认启用。
  • 功能标志移除于 14.1 版本。

此方法自动准备合并请求,Secret 检测模板包含在 ·.gitlab-ci.yml· 文件中。然后合并合并请求,启用 Secret 检测。

note此方法在没有现有 .gitlab-ci.yml 文件或最小配置文件的情况下效果最佳。如果您有一个复杂的极狐GitLab 配置文件,它可能无法解析成功,并且可能会出现错误。在这种情况下,请改用手动方法。

要在项目中自动启用 Secret Detection:

  1. 在顶部栏上,选择 主菜单 > 项目 并找到您的项目。
  2. 在左侧边栏上,选择 安全与合规 > 配置
  3. Secret 检测 行中,选择 使用合并请求进行配置
  4. 可选。填写字段。
  5. 选择 创建合并请求
  6. 查看并合并合并请求。

流水线现在包含一个 Secret 检测作业。

响应泄露的 Secret

如果扫描器检测到 secret,我们建议您立即替换它。从仓库的历史记录中清除文件可能无法有效删除对该文件的所有引用。此外,Secret 仍然存在于仓库的任何分支中。

固定到特定的分析器版本

极狐GitLab 管理的 CI/CD 模板指定一个主要版本,并自动在该主要版本中提取最新的分析器版本。

在某些情况下,您可能需要使用特定版本。例如,您可能需要避免在以后的版本中出现回归。

要覆盖自动更新行为,请在包含 Secret-Detection.gitlab-ci.yml 模板中设置 SECRETS_ANALYZER_VERSION CI/CD 变量。

您可以将标签设置为:

  • 一个主要版本,例如 4。您的流水线将使用在此主要版本中发布的任何次要更新或补丁更新。
  • 一个次要版本,例如 4.5。 您的流水线将使用在此次要版本中发布的任何补丁更新。
  • 一个补丁版本,比如 4.5.0。您的流水线不会收到任何更新。

此示例使用分析器的特定次要版本:

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

secret_detection:
  variables:
    SECRETS_ANALYZER_VERSION: "4.5"

配置扫描设置

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

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

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

在以下 .gitlab-ci.yml 文件的示例摘录中:

  • 包含 Secret 检测模板。
  • secret_detection 作业中,CI/CD 变量 SECRET_DETECTION_HISTORIC_SCAN 设置为 true。因为模板是在流水线配置之前评估的,所以最后提到的变量优先。
include:
  - template: Security/Secret-Detection.gitlab-ci.yml

secret_detection:
  variables:
    SECRET_DETECTION_HISTORIC_SCAN: "true"

忽略 Secrets

在某些情况下,您可能想要忽略一个 secret。例如,您可能在示例或测试套件中使用了伪造的 secret。在这些情况下,您希望忽略 secret,而不是将其报告为漏洞。

要忽略 secret,请将 gitleaks:allow 作为注释添加到包含 secret 的行。

例如:

 "A personal token for GitLab will look like glpat-JUST20LETTERSANDNUMB" #gitleaks:allow

可用的 CI/CD 变量

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

CI/CD 变量 默认值 描述
SECRET_DETECTION_EXCLUDED_PATHS ”” 根据路径从输出中排除漏洞。这是一个逗号分隔的模式列表,pattern 可以是 glob(查看 doublestar.Match),也可以是文件或文件夹路径(例如,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 版本。

使用 FIPS-enabled 镜像

引入于 14.10 版本。

默认扫描器镜像是基于 Alpine 基础镜像构建的,以确保大小和可维护性。极狐GitLab 提供 FIPS-enabled 的镜像的 Red Hat UBI 版本。

要使用 FIPS-enabled 的镜像,请执行以下任一操作:

  • SECRET_DETECTION_IMAGE_SUFFIX CI/CD 变量设置为 -fips
  • -fips 扩展添加到默认镜像名称。

例如:

variables:
  SECRET_DETECTION_IMAGE_SUFFIX: '-fips'

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

完整历史 Secret 检测

默认情况下,Secret 检测仅扫描 Git 仓库的当前状态。不会检测到仓库历史记录中包含的任何 Secret。为了解决这个问题,Secret 检测可以扫描 Git 仓库的完整历史记录。

我们建议您在启用 Secret 检测后仅执行一次完整的历史扫描。完整的历史记录可能需要很长时间,尤其是对于具有较长 Git 历史记录的大型仓库。完成初始完整历史扫描后,仅使用标准 Secret 检测作为流水线的一部分。

启用完整历史 Secret 检测

要启用完整的历史 Secret 检测,请在 .gitlab-ci.yml 文件中将变量 SECRET_DETECTION_HISTORIC_SCAN 设置为 true

自定义规则集

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

您可以自定义极狐GitLab 提供的默认 secret 检测规则。

以下自定义选项可以单独使用,也可以组合使用:

禁用预定义的分析器规则

如果有您不想激活的特定 Secret 检测规则,您可以禁用它们。

要禁用分析器规则:

  1. 在项目的根目录下创建一个 .gitlab 目录,如果该目录尚不存在。
  2. .gitlab 目录中创建一个名为 secret-detection-ruleset.toml 的自定义规则集文件(如果尚不存在)。
  3. ruleset 部分的上下文中,将 disabled 标志设置为 true
  4. 在一个或多个 ruleset.identifier 小节中,列出要禁用的规则。每个 ruleset.identifier 部分都有:
    • type 字段:预定义规则标识符
    • value 字段:规则名称

在以下示例 secret-detection-ruleset.toml 文件中,通过匹配标识符的 typevalue 将禁用的规则分配给 secrets

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

覆盖预定义的分析器规则

如果您要自定义特定的 Secret 检测规则,您可以覆盖它们。例如,您可能会增加特定 Secret 的严重性。

要覆盖规则:

  1. 在项目的根目录下创建一个 .gitlab 目录,如果该目录尚不存在。
  2. .gitlab 目录中创建一个名为 secret-detection-ruleset.toml 的自定义规则集文件(如果尚不存在)。
  3. 在一个或多个 ruleset.identifier 中,列出您要覆盖的规则。每个 ruleset.identifier 部分都有:
    • 一个 type 字段,命名 secret 检测分析器使用的预定义规则标识符。
    • 一个 value 字段,命名要覆盖的规则。
  4. ruleset 部分的 ruleset.override 上下文中,提供要覆盖的键。可以覆盖任何键组合。有效的键是:
    • description
    • message
    • name
    • severity (有效选项:Critical, High, Medium, Low, Unknown, Info)

在以下示例 secret-detection-ruleset.toml 文件中,规则由标识符的 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"

合成自定义配置

要创建自定义配置,您可以使用透传链,构建更复杂的配置。有关更多详细信息,请参阅 SAST 自定义规则集

secrets 分析器仅支持以下透传类型:

  • file
  • raw

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"
    

扩展默认配置

您可以使用 Gitleaks extend 支持,对默认配置进行额外更改。

在下面的 file 透传示例中,Secret 检测忽略了字符串 glpat-1234567890abcdefghij。极狐GitLab 个人访问令牌 (PAT) 用于测试用例,对它的检测为误报。

secret-detection-ruleset.toml 文件定义要包含 extended-gitleaks-config.toml 文件中的配置。extended-gitleaks-config.toml 文件定义了自定义 Gitleaks 配置。allowlist 节定义了一个正则表达式,它匹配要忽略的 secret。

# .gitlab/secret-detection-ruleset.toml
[secrets]
  description = 'secrets custom rules configuration'

  [[secrets.passthrough]]
    type  = "file"
    target = "gitleaks.toml"
    value = "extended-gitleaks-config.toml"
# extended-gitleaks-config.toml
title = "extension of gitlab's default gitleaks config"

[extend]
# Extends default packaged path
path = "/gitleaks.toml"

[allowlist]
  description = "allow list of test tokens to ignore in detection"
  regexTarget = "match"
  regexes = [
    '''glpat-1234567890abcdefghij''',
  ]

在离线环境中运行 secret 检测

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

配置极狐GitLab Runner

默认情况下,即使本地副本可用,Runner 也会尝试从极狐GitLab 容器镜像库中提取 Docker 镜像。我们建议使用此默认设置,以确保 Docker 镜像保持最新。 但是,如果没有可用的网络连接,则必须更改默认的极狐GitLab Runner pull_policy 变量。

将极狐GitLab Runner CI/CD 变量 pull_policy 配置为 if-not-present

使用本地 Secret 检测分析器镜像

如果要从本地 Docker 镜像库而不是极狐GitLab 容器镜像库获取镜像,请使用本地 Secret 检测分析器镜像。

先决条件:

  • 将 Docker 镜像导入本地离线 Docker 镜像库取决于您的网络安全策略。请咨询您的 IT 人员,找到一个接受和批准的流程来导入或临时访问外部资源。
  1. registry.gitlab.cn 将默认的 Secret 检测分析器镜像导入您的本地 Docker 容器镜像库

    registry.gitlab.cn/security-products/secrets:4
    

    Secret 检测分析器的镜像会定期更新,因此您可能需要定期更新本地副本。

  2. 将 CI/CD 变量 SECURE_ANALYZERS_PREFIX 设置为本地 Docker 容器镜像库。

    include:
      - template: Security/Secret-Detection.gitlab-ci.yml
    
    variables:
      SECURE_ANALYZERS_PREFIX: "localhost:5000/analyzers"
    

Secret 检测作业现在应该使用 Secret 检测分析器 Docker 镜像的本地副本,而无需访问 Internet。

配置自定义证书颁发机构

要信任自定义证书颁发机构,请将 ADDITIONAL_CA_CERT_BUNDLE 变量设置为您信任的 CA 证书包。在 .gitlab-ci.yml 文件、文件变量或 CI/CD 变量中执行此操作。

  • .gitlab-ci.yml 文件中,ADDITIONAL_CA_CERT_BUNDLE 值必须包含 X.509 PEM公钥证书的文本表示

    例如:

    variables:
      ADDITIONAL_CA_CERT_BUNDLE: |
          -----BEGIN CERTIFICATE-----
          MIIGqTCCBJGgAwIBAgIQI7AVxxVwg2kch4d56XNdDjANBgkqhkiG9w0BAQsFADCB
          ...
          jWgmPqF3vUbZE0EyScetPJquRFRKIesyJuBFMAs=
          -----END CERTIFICATE-----
    
  • 如果使用文件变量,请将 ADDITIONAL_CA_CERT_BUNDLE 的值设置为证书的路径。

  • 如果使用变量,请将 ADDITIONAL_CA_CERT_BUNDLE 的值设置为证书的文本表示。

文本内容潜在泄漏的警告

引入于 15.11 版本。

当您创建议题、提出合并请求或撰写评论时,您可能会不小心发布敏感值。 例如,您可能会粘贴 API 请求的详细信息或包含身份验证令牌的环境变量。

极狐GitLab 检查您的议题描述、合并请求描述、评论或回复的文本是否包含敏感令牌。 如果找到令牌,则会显示一条警告消息。然后,您可以在发布之前编辑您的消息。 在将消息发送到服务器之前,此检查会在您的浏览器中进行。 检查一直打开,您无需设置。

系统检查您的文本是否有以下 secret 类型:

此功能独立于 Secret 检测扫描,后者会检查 Git 仓库中是否存在泄露的 secret。

故障排查

设置日志级别

当您需要 Secret 检测作业日志中的诊断信息时,将日志记录级别设置为 debug

caution调试日志记录可能是一个严重的安全风险。输出可能包含环境变量的内容和作业可用的其他 Secret。输出将上传到极狐GitLab 服务器并在作业日志中可见。
  1. .gitlab-ci.yml 文件中,将 SECURE_LOG_LEVEL CI/CD 变量设置为 debug
  2. 运行 Secret 检测作业。
  3. 分析 Secret 检测作业的内容。
  4. .gitlab-ci.yml 文件中,将 SECURE_LOG_LEVEL CI/CD 变量设置为 info(默认)。

Warning: gl-secret-detection-report.json: no matching files

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

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

Secret 检测分析器依赖于在提交之间生成补丁来扫描 Secret 内容。如果合并请求中的提交次数大于 GIT_DEPTH CI/CD 变量的值,Secret 检测无法检测到 Secret。

例如,从包含 60 个提交的合并请求触发流水线,并且 GIT_DEPTH 变量的值小于 60,则 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

错误:ERR fatal: ambiguous argument

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

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