依赖扫描

依赖扫描功能可以在您开发和测试应用程序时,自动查找软件依赖项中的安全漏洞。例如,依赖项扫描可以让您知道您的应用程序是否使用已知易受攻击的外部(开源)库。然后,您可以采取措施保护您的应用程序。

依赖扫描通常被认为是软件组合分析 (SCA) 的一部分。SCA 可以包含检查代码使用的项目的各个方面,这些项目通常包括几乎总是从外部源导入的应用程序和系统依赖项,而不是来自您自己编写的项目。

如果您使用极狐GitLab CI/CD,您可以使用依赖扫描来分析已知漏洞的依赖关系。极狐GitLab 扫描所有依赖项,包括传递依赖项(也称为嵌套依赖项)。您可以通过以下任一方式使用依赖项扫描:

极狐GitLab 检查依赖扫描报告,比较源分支和目标分支之间发现的漏洞,并显示合并请求的信息。结果按漏洞的严重性排序。

Dependency scanning Widget

依赖扫描与容器扫描的比较

极狐GitLab 提供依赖扫描和容器扫描,确保覆盖所有依赖类型。为了尽可能多地覆盖您的风险区域,我们鼓励您使用我们所有的安全扫描器:

  • 依赖项扫描分析您的项目,并告诉您哪些软件依赖项(包括上游依赖项)已包含在您的项目中,以及依赖项包含哪些已知风险。依赖扫描根据项目的语言和包管理器修改其行为,它通常会查找锁定文件,然后执行构建来获取上游依赖信息。在容器的情况下,依赖扫描使用兼容的 manifest 并仅报告这些声明的软件依赖项(以及作为子依赖项安装的)。依赖项扫描无法检测预先捆绑到容器基础镜像中的软件依赖项,要识别预先捆绑的依赖项,请使用 CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN 变量启用容器扫描中的语言扫描。
  • 容器扫描分析您的容器,并告诉您操作系统 (OS) 包中的已知风险。如果您启用并使用 CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN 变量,可以将其配置同时报告软件和语言依赖。打开此变量可能会导致一些重复的结果,因为尚未对容器扫描和依赖项扫描之间的结果进行重复数据删除。

下表总结了每个扫描工具可以检测到的依赖类型:

功能 依赖扫描 容器扫描
识别引入依赖的 manifest、锁定文件或静态文件
开发依赖
提交到仓库的锁定文件中的依赖项 1
Go 构建的二进制文件 2 3
操作系统安装的动态关联的特定于语言的依赖项 3
操作系统依赖
安装在操作系统上的特定于语言的依赖项(不是由您的项目构建的)
  1. 锁定文件必须存在于要检测的镜像中。
  2. 二进制文件必须存在于要检测的镜像中。
  3. 仅当使用 Trivy 时。

要求

依赖扫描在 test 阶段运行,默认情况下可用。如果在 .gitlab-ci.yml 文件中重新定义阶段,则需要 test 阶段。

要运行依赖扫描作业,默认情况下,您需要带有 dockerkubernetes executor 的 GitLab Runner。 如果您在 SaaS 上使用共享 runner,则默认启用此功能。提供的分析器镜像适用于 Linux/amd64 架构。

caution如果您使用自己的 runner,请确保您安装的 Docker 版本不是 19.03.0。有关详细信息,请参阅故障排查信息
caution依赖扫描不支持编译器和解释器的运行时安装。

支持的语言和包管理器

依赖扫描自动检测仓库中使用的语言,运行与检测到的语言匹配的所有分析器,通常不需要自定义分析器的选择。我们建议不要指定分析器,以便您自动使用完整选择从而获得最佳覆盖范围,避免在出现弃用或删除时进行调整。 但是,您可以使用变量 DS_EXCLUDED_ANALYZERS 覆盖选择。

语言检测依赖于 CI 作业 rules,并从仓库的根目录中搜索最多两个目录级别。例如,如果仓库包含Gemfileapi/Gemfileapi/client/Gemfile,则启用 gemnasium-dependency_scanning 作业,但如果唯一支持的依赖文件是 api/v1/client/Gemfile,则不会启用。

对于 Java 和 Python,当检测到支持的依赖文件时,依赖扫描会尝试构建项目并执行一些 Java 或 Python 命令以获取依赖项列表。对于所有其他项目,无需先构建项目,即可解析锁定文件以获取依赖项列表。

当检测到支持的依赖文件时,将分析所有依赖项,包括传递依赖项。分析的嵌套或传递依赖项的深度没有限制。

支持以下语言和依赖项管理器:

语言 语言版本 包管理器 支持的文件 处理多个文件?
Ruby 所有版本 Bundler
  • Gemfile.lock
  • gems.locked
Y
PHP 所有版本 Composer composer.lock Y
C 所有版本 Conan conan.lock Y
C++
Go 所有版本 Go
  • go.mod
  • go.sum
Y
Java 8, 11, 131, 141, 151, 161, or 17
  • build.gradle
  • build.gradle.kts
Gemnasium N
Maven pom.xml N
JavaScript 所有版本 npm
  • package-lock.json3
  • npm-shrinkwrap.json
Y
所有版本 yarn yarn.lock Y
.NET 所有版本 NuGet packages.lock.json Y
C#
Python 3.9 setuptools setup.py N
pip
  • requirements.txt
  • requirements.pip
  • requires.txt
N
Pipenv N
Poetry5 poetry.lock Gemnasium N
Scala 所有版本 * sbt6 build.sbt N
  1. 此版本的 Java 不受 gemnasium-maven 的 FIPS-enabled 镜像的支持。

  2. 虽然支持 Java 8 的 Gradle,但目前还存在其他问题,例如 Android 项目构建不受支持。此外,启用 FIPS 模式时不支持 Gradle。

  3. lockfileVersion = 1lockfileVersion = 2 时,仅支持 npm。

  4. Pipfile.lock 文件的存在将不会触发分析器;Pipfile 仍然需要存在才能执行分析器。但是,如果找到 Pipfile.lock 文件,Gemnasium 将使用它来扫描该文件中列出的确切软件包版本。

  5. 对带有 poetry.lock 文件的 Poetry 项目的支持添加于 15.0 版本。

  6. sbt 1.3 及更高版本的支持添加于 13.9 版本。

分析器如何获取依赖信息

极狐GitLab 分析器使用以下两种方法之一获取依赖关系信息:

  1. 直接解析 lockfiles。
  2. 运行包管理器或构建工具来生成依赖信息文件,然后对其进行解析。

通过解析 lockfile 获取依赖信息

以下包管理器使用 GitLab 分析器能够直接解析的 lockfile:

包管理器 支持的文件格式版本 测试版本
Bundler N/A 1.17.3, 2.1.4
Composer N/A 1.x
Conan 0.4 1.x
Go N/A 1.x1
NuGet v1 4.9
npm v1, v2 6.x, 7.x
yarn v1 1.x
Poetry v1 1.x
  1. 如果无法生成 Go 项目使用的构建列表,依赖扫描只会解析 go.sum

通过运行包管理器生成可解析文件获取依赖信息

为了支持以下包管理器,GitLab 分析器分两个步骤进行:

  1. 执行包管理器或特定任务,导出依赖信息。
  2. 解析导出的依赖信息。
包管理器 预装版本 测试版本
sbt 1.6.1 1.0.4, 1.1.4, 1.1.6, 1.2.8, 1.3.12, 1.4.6, 1.6.1
Maven 3.6.3 3.6.3
Gradle 6.7.11**, 7.3.31 5.6.4, 6.5, 6.7.12, 6.9, 7.3, 7.3.32
setuptools 50.3.2 57.5.0
pip 20.2.4 20.x
Pipenv 2018.11.26 2018.11.263, 2018.11.26
Go 1.17 1.174
  1. 不同版本的 Java 需要不同版本的 Gradle。上表中列出的 Gradle 版本已预安装在分析器镜像中。分析器使用的 Gradle 版本取决于您的项目是否使用 gradlew(Gradle 包装器)文件:

    • 如果您的项目 不使用 gradlew 文件, 然后分析器会自动切换到预安装的 Gradle 版本之一,基于由 DS_JAVA_VERSION 变量指定的 Java 版本。

      对于 Java 版本 811,自动选择 Gradle 6.7.1,对于 Java 版本 13 到 < code>17</code>,自动选择 Gradle 7.3.3

    • 如果您的项目 使用 gradlew 文件,那么分析器镜像中预装的 Gradle 版本将被忽略,而使用 gradlew 文件中指定的版本。

  2. 这些测试确认如果 gradlew 文件不存在,则使用预安装在分析器镜像中的 Gradle 版本。

  3. 此测试确认如果找到 Pipfile.lock 文件,Gemnasium 将使用该文件扫描此文件中列出的确切软件包版本。

  4. 由于执行 go build,Go 构建过程需要网络访问,通过 go mod download 获得一个预加载的 modcache via,或供应的依赖项。获取更多信息,参考 Go 文档:编译包和依赖

如何触发分析器

极狐GitLab 依赖 rules:exists 来启动相关分析器,针对仓库中存在的 Supported files 检测到的语言,如上表所示。

当前的检测逻辑将最大搜索深度限制为两个级别。例如,如果仓库包含 Gemfile.lockapi/Gemfile.lockapi/client/Gemfile.lock,则启用 gemnasium-dependency_scanning 作业,但如果唯一支持的依赖文件是 api/v1/client/Gemfile.lock,则不然。

当检测到支持的依赖文件时,将分析所有依赖项,包括传递依赖项。分析的嵌套或传递依赖项的深度没有限制。

Python

我们只在检测到需求文件或锁定文件的目录中执行一次安装。依赖关系仅由 gemnasium-python 分析检测到的第一个文件。按以下顺序搜索文件:

  1. requirements.txtrequirements.piprequires.txt 用于使用 Pip 的项目。
  2. PipfilePipfile.lock 用于使用 Pipenv 的项目。
  3. poetry.lock 用于使用 Poetry 的项目。
  4. 使用 Setuptools 的项目的setup.py

搜索从根目录开始,如果在根目录中未找到任何构建,则继续搜索子目录。因此,将在子目录中的 Pipenv 文件之前,检测到根目录中的 Poetry 锁定文件。

Java and Scala

我们只在检测到构建文件的目录中执行一个构建。对于包含多个 Gradle、Maven 或 sbt 构建或这些构建的任何组合的大型项目,gemnasium-maven 仅分析检测到的第一个构建文件的依赖关系。构建文件按以下顺序搜索:

  1. build.gradlebuild.gradle.kts 用于单个或多项目 Gradle 构建。
  2. pom.xml 用于单个或多模块 Maven 项目。
  3. build.sbt 用于单个或多项目 sbt 构建。

搜索从根目录开始,如果在根目录中未找到任何构建,则继续搜索子目录。因此,将在子目录中的 Gradle 构建文件之前,检测到根目录中的 sbt 构建文件。

JavaScript

执行以下分析器,每个分析器在处理多个文件时具有不同的行为:

  • Gemnasium

    支持多个 lockfile。

  • Retire.js

    不支持多个 lockfile。当存在多个 lockfile 时,Retire.js 会分析在按字母顺序遍历目录树时发现的第一个 lockfile。

从 14.8 版本开始,gemnasium 分析器会扫描支持的 JavaScript 项目,查找供应商库(即检入项目但不受包管理器管理的库)。

Go

扫描 Go 项目时,gemnasium 调用构建器并尝试使用最小版本选择,生成构建列表。如果遇到非致命错误,构建过程会发出信号,指示执行应该继续并返回到解析可用的 go.sum 文件。

PHP, Go, C, C++, .NET, C#, Ruby, JavaScript

这些语言的分析器支持多个 lockfile。

支持其它语言

在以下问题中跟踪对其他语言、依赖管理器和依赖文件的支持:

包管理器 语言 支持的文件 扫描工具
Poetry Python poetry.lock Gemnasium

配置

要启用依赖扫描,您必须 include Dependency-Scanning.gitlab-ci.yml 模板,其作为极狐GitLab 安装的一部分提供。

将以下内容添加到您的 .gitlab-ci.yml 文件中:

include:
  - template: Security/Dependency-Scanning.gitlab-ci.yml

包含的模板在 CI/CD 流水线中创建依赖项扫描作业,并扫描项目的源代码以查找可能的漏洞。 结果保存为依赖扫描报告产物,您可以稍后下载和分析。由于实施限制,我们始终采用可用的最新依赖扫描产物。

通过自动合并请求启用依赖扫描

  • 引入于 14.1 版本,功能标志名为 sec_dependency_scanning_ui_enable。默认启用。
  • 于 14.1 版本适用于私有化部署版
  • 功能标志移除于 14.2 版本。

要在项目中启用依赖扫描,您可以创建合并请求:

  1. 在顶部栏上,选择 主菜单 > 项目 并找到您的项目。
  2. 在左侧边栏上,选择 安全与合规 > 配置
  3. 依赖项扫描 行中,选择 使用合并请求进行配置
  4. 查看并合并合并请求,来启用依赖扫描。

流水线现在包括依赖项扫描作业。

自定义依赖项扫描设置

可以使用 variables 通过 CI/CD 变量(设置 .gitlab-ci.yml 中的参数)更改依赖项扫描。 例如:

include:
  - template: Security/Dependency-Scanning.gitlab-ci.yml

variables:
  SECURE_LOG_LEVEL: error

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

覆盖依赖项扫描作业

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

要覆盖作业定义(例如,更改 variablesdependencies 等属性),请声明一个与要覆盖的作业同名的新作业。将此新作业放在模板 include 之后,并在其下指定任何其它的 key。例如,禁用 gemnasium 分析器的 DS_REMEDIATE

include:
  - template: Security/Dependency-Scanning.gitlab-ci.yml

gemnasium-dependency_scanning:
  variables:
    DS_REMEDIATE: "false"

要覆盖 dependencies: [] 属性,请像上面一样添加一个覆盖作业,以该属性为目标:

include:
  - template: Security/Dependency-Scanning.gitlab-ci.yml

gemnasium-dependency_scanning:
  dependencies: ["build"]

可用的 CI/CD 变量

可以使用环境变量配置依赖扫描。

配置依赖扫描

以下变量允许配置全局依赖扫描设置。

caution在将这些更改合并到默认分支之前,应在合并请求中测试极狐GitLab 安全扫描工具的所有自定义。不这样做会产生意想不到的结果,包括大量误报。
CI/CD 变量 描述
ADDITIONAL_CA_CERT_BUNDLE 要信任的 CA 证书捆绑包。此处提供的证书包也被其他工具在扫描过程中使用,例如 gityarnnpm。查看使用自定义 SSL CA 证书颁发机构,获取更多信息。
DS_EXCLUDED_ANALYZERS 指定要从依赖扫描中排除的分析器(按名称)。有关详细信息,请参阅依赖扫描分析器
DS_DEFAULT_ANALYZERS 已弃用 - 改用 DS_EXCLUDED_ANALYZERS)覆盖官方默认镜像的名称。有关详细信息,请参阅 依赖扫描分析器
DS_EXCLUDED_PATHS 根据路径从扫描中排除文件和目录,以逗号分隔的 pattern 列表。Pattern 可以是 glob(有关支持的模板,请参阅 doublestar.Match)、文件或文件夹路径(例如,doc、spec),父目录也匹配 pattern。默认值:"spec,test,tests,tmp"
DS_IMAGE_SUFFIX 后缀添加到镜像名称。如果设置为 -fips,则使用 FIPS-enabled 镜像进行扫描。有关详细信息,请参阅启用 FIPS 的镜像。引入于 14.10 版本。
SECURE_ANALYZERS_PREFIX 覆盖提供官方默认镜像(代理)的 Docker 镜像库的名称。阅读有关自定义分析器的更多信息。
SECURE_LOG_LEVEL 设置最低日志记录级别,输出此日志级别或更高级别的消息,从最高到最低严重性,日志记录级别是:fatalerrorwarninfodebug。引入于 13.1 版本,默认值:info

配置依赖扫描使用的特定分析器

以下变量用于配置特定分析器(用于特定语言/框架)。

CI/CD 变量 分析器 默认值 描述
GEMNASIUM_DB_LOCAL_PATH gemnasium /gemnasium-db 本地 Gemnasium 数据库的路径。
GEMNASIUM_DB_UPDATE_DISABLED gemnasium "false" 禁用 gemnasium-db 咨询数据库的自动更新
GEMNASIUM_DB_REMOTE_URL gemnasium 用于获取 Gemnasium 数据库的仓库 URL。
GEMNASIUM_DB_REF_NAME gemnasium master 远端仓库数据库的分支名称。需要先配置 GEMNASIUM_DB_REMOTE_URL
DS_REMEDIATE gemnasium "true",FIPS 模式中为 "false" 启用易受攻击的依赖项的自动修复。
GEMNASIUM_LIBRARY_SCAN_ENABLED gemnasium "true" 启用检测供应商 JavaScript 库中的漏洞。目前,gemnasium 利用 Retire.js 来完成这项工作。引入于 14.8 版本。
DS_JAVA_VERSION gemnasium-maven 17 Java 版本。可用版本:8111314151617。启用 FIPS 的镜像中的可用版本:81117
MAVEN_CLI_OPTS gemnasium-maven "-DskipTests --batch-mode" 分析器传递给 maven 的命令行参数列表。
GRADLE_CLI_OPTS gemnasium-maven   分析器传递给 gradle 的命令行参数列表。
SBT_CLI_OPTS gemnasium-maven   分析器传递给 sbt 的命令行参数列表。
PIP_INDEX_URL gemnasium-python https://pypi.org/simple Python 包索引的基本 URL。
PIP_EXTRA_INDEX_URL gemnasium-python   除了 PIP_INDEX_URL 之外要使用的包索引的额外 URL 数组,逗号分隔。警告: 使用此环境变量时请阅读以下安全注意事项
PIP_REQUIREMENTS_FILE gemnasium-python   要扫描的 Pip 需求文件。
DS_PIP_VERSION gemnasium-python   强制安装特定的 pip 版本(例如:"19.3"),否则使用 Docker 镜像中安装的 pip。
DS_PIP_DEPENDENCY_PATH gemnasium-python   从中加载 Python pip 依赖项的路径。
DS_INCLUDE_DEV_DEPENDENCIES gemnasium "true" 当设置为 false 时,不报告开发依赖项及其漏洞。仅支持 NPM 和 Poetry 项目。引入于 15.1 版本。
GOOS gemnasium "linux" 编译 Go 代码的操作系统。
GOARCH gemnasium "amd64" 编译 Go 代码的处理器架构。
GOFLAGS gemansium   传递给 go build 工具的标志。
GOPRIVATE gemnasium   要从源中获取的 glob pattern 和前缀列表。阅读 Go 私有模块文档,了解更多信息。

其它变量

前面的表格并不是可以使用的所有变量的详尽列表,包含我们支持和测试的所有特定极狐GitLab 和分析器变量。有许多变量,例如环境变量,您可以传入并且它们会起作用。这是一个很大的列表,其中许多我们可能不知道,因此没有记录在案。

例如,要将非 GitLab 环境变量 HTTPS_PROXY 传递给所有依赖扫描作业,请将其设置为 .gitlab-ci.yml 文件中的自定义 CI/CD 变量,如下所示:

variables:
  HTTPS_PROXY: "https://squid-proxy:3128"

或者,我们可以在特定的工作中使用它,比如依赖扫描:

dependency_scanning:
  variables:
    HTTPS_PROXY: $HTTPS_PROXY

使用自定义 SSL CA 证书颁发机构

您可以使用 ADDITIONAL_CA_CERT_BUNDLE CI/CD 变量来配置自定义 SSL 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,需要证书的路径;或者作为变量,需要证书的文本表示。

使用私有 Maven 仓库

如果您的私有 Maven 仓库需要登录凭据,您可以使用 MAVEN_CLI_OPTS CI/CD 变量。

FIPS-enabled 镜像

引入于 14.10 版本

极狐GitLab 还提供支持 FIPS 的 Red Hat UBI 版本的 Gemnasium 镜像。因此,您可以用启用 FIPS 的镜像替换标准镜像。

当在实例中启用 FIPS 模式时,Gemnasium 扫描作业会自动使用启用 FIPS 的镜像。(在 15.0 版本中引入。)

要手动切换到启用 FIPS 的镜像,请将变量 DS_IMAGE_SUFFIX 设置为 "-fips"

为确保符合 FIPS,gemnasium-maven 的 FIPS-enabled 的镜像使用 RedHat UBI 的 OpenJDK 包。因此,它仅支持 Java 8、11 和 17。

FIPS 模式不支持 Gradle 项目的依赖扫描和 Yarn 项目的自动修复。

与漏洞交互

一旦发现漏洞,您就可以与之交互。阅读有关如何解决漏洞的更多信息。

漏洞解决方案

一些漏洞可以通过应用极狐GitLab 自动生成的解决方案来修复。阅读有关漏洞解决方案的更多信息。

报告 JSON 格式

依赖项扫描工具会发出一个 JSON 报告文件。

以下是一个示例依赖扫描报告:

{
  "version": "2.0",
  "vulnerabilities": [
    {
      "id": "51e83874-0ff6-4677-a4c5-249060554eae",
      "category": "dependency_scanning",
      "name": "Regular Expression Denial of Service",
      "message": "Regular Expression Denial of Service in debug",
      "description": "The debug module is vulnerable to regular expression denial of service when untrusted user input is passed into the `o` formatter. It takes around 50k characters to block for 2 seconds making this a low severity issue.",
      "severity": "Unknown",
      "solution": "Upgrade to latest versions.",
      "scanner": {
        "id": "gemnasium",
        "name": "Gemnasium"
      },
      "location": {
        "file": "yarn.lock",
        "dependency": {
          "package": {
            "name": "debug"
          },
          "version": "1.0.5"
        }
      },
      "identifiers": [
        {
          "type": "gemnasium",
          "name": "Gemnasium-37283ed4-0380-40d7-ada7-2d994afcc62a",
          "value": "37283ed4-0380-40d7-ada7-2d994afcc62a",
          "url": "https://deps.sec.gitlab.com/packages/npm/debug/versions/1.0.5/advisories"
        }
      ],
      "links": [
        {
          "url": "https://nodesecurity.io/advisories/534"
        },
        {
          "url": "https://github.com/visionmedia/debug/issues/501"
        },
        {
          "url": "https://github.com/visionmedia/debug/pull/504"
        }
      ]
    },
    {
      "id": "5d681b13-e8fa-4668-957e-8d88f932ddc7",
      "category": "dependency_scanning",
      "name": "Authentication bypass via incorrect DOM traversal and canonicalization",
      "message": "Authentication bypass via incorrect DOM traversal and canonicalization in saml2-js",
      "description": "Some XML DOM traversal and canonicalization APIs may be inconsistent in handling of comments within XML nodes. Incorrect use of these APIs by some SAML libraries results in incorrect parsing of the inner text of XML nodes such that any inner text after the comment is lost prior to cryptographically signing the SAML message. Text after the comment, therefore, has no impact on the signature on the SAML message.\r\n\r\nA remote attacker can modify SAML content for a SAML service provider without invalidating the cryptographic signature, which may allow attackers to bypass primary authentication for the affected SAML service provider.",
      "severity": "Unknown",
      "solution": "Upgrade to fixed version.\r\n",
      "scanner": {
        "id": "gemnasium",
        "name": "Gemnasium"
      },
      "location": {
        "file": "yarn.lock",
        "dependency": {
          "package": {
            "name": "saml2-js"
          },
          "version": "1.5.0"
        }
      },
      "identifiers": [
        {
          "type": "gemnasium",
          "name": "Gemnasium-9952e574-7b5b-46fa-a270-aeb694198a98",
          "value": "9952e574-7b5b-46fa-a270-aeb694198a98",
          "url": "https://deps.sec.gitlab.com/packages/npm/saml2-js/versions/1.5.0/advisories"
        },
        {
          "type": "cve",
          "name": "CVE-2017-11429",
          "value": "CVE-2017-11429",
          "url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-11429"
        }
      ],
      "links": [
        {
          "url": "https://github.com/Clever/saml2/commit/3546cb61fd541f219abda364c5b919633609ef3d#diff-af730f9f738de1c9ad87596df3f6de84R279"
        },
        {
          "url": "https://github.com/Clever/saml2/issues/127"
        },
        {
          "url": "https://www.kb.cert.org/vuls/id/475445"
        }
      ]
    }
  ],
  "remediations": [
    {
      "fixes": [
        {
          "id": "5d681b13-e8fa-4668-957e-8d88f932ddc7",
        }
      ],
      "summary": "Upgrade saml2-js",
      "diff": "ZGlmZiAtLWdpdCBhL...OR0d1ZUc2THh3UT09Cg==" // some content is omitted for brevity
    }
  ]
}

CycloneDX 软件物料清单

引入于 14.8 版本,Beta 功能。

noteCycloneDX SBOM 是 Beta 功能,在 Beta 期间报告可能会发生变化。不要构建依赖于这些 SBOM 格式保持一致的集成,因为在该功能一般可用之前,格式可能会发生变化。

除了 JSON 报告文件Gemnasium 依赖扫描工具为它检测到的每个支持的锁定或构建文件输出一个 CycloneDX Software Bill of Materials (SBOM)。这些 CycloneDX SBOM 被命名为 gl-sbom-<package-type>-<package-manager>.json,并保存在与检测到的锁定或构建文件相同的目录中。

例如,如果您的项目具有以下结构:

.
├── ruby-project/
│   └── Gemfile.lock
├── ruby-project-2/
│   └── Gemfile.lock
├── php-project/
│   └── composer.lock
└── go-project/
    └── go.sum

然后 Gemnasium 扫描器生成以下 CycloneDX SBOM:

.
├── ruby-project/
│   ├── Gemfile.lock
│   └── gl-sbom-gem-bundler.cdx.json
├── ruby-project-2/
│   ├── Gemfile.lock
│   └── gl-sbom-gem-bundler.cdx.json
├── php-project/
│   ├── composer.lock
│   └── gl-sbom-packagist-composer.cdx.json
└── go-project/
    ├── go.sum
    └── gl-sbom-go-go.cdx.json

可以下载 CycloneDX SBOM,与下载其他作业产物的方式相同

合并多个 CycloneDX SBOM

您可以使用 CI/CD 作业将多个 CycloneDX SBOM 合并为一个 SBOM。 例如:

stages:
  - test
  - merge-cyclonedx-sboms

include:
  - template: Security/Dependency-Scanning.gitlab-ci.yml

merge cyclonedx sboms:
  stage: merge-cyclonedx-sboms
  image:
    name: cyclonedx/cyclonedx-cli:0.24.0
    entrypoint: [""]
  script:
    - find . -name "gl-sbom-*.cdx.json" -exec /cyclonedx merge --output-file gl-sbom-all.cdx.json --input-files "{}" +
  artifacts:
    paths:
      - gl-sbom-all.cdx.json

极狐GitLab 使用 CycloneDX 属性,在每个 CycloneDX SBOM 的元数据中存储实现特定的详细信息,例如构建和锁定的文件位置。如果多个 CycloneDX SBOM 合并在一起,则此信息将从生成的合并文件中删除。

警告

我们建议您使用所有容器的最新版本,以及所有包管理器和语言的最新支持版本。使用以前的版本会增加安全风险,因为不受支持的版本可能不再受益于主动安全报告和安全修复的反向移植。

Python 项目

使用 PIP_EXTRA_INDEX_URL 环境变量时需要格外小心,因为 CVE-2018-20225

在 pip(所有版本)中发现了一个问题,因为它安装了具有最高版本号的版本,即使用户打算从私有索引中获取私有包。这只会影响 PIP_EXTRA_INDEX_URL 选项的使用,并且利用需要包不存在于公共索引中(因此攻击者可以将包以任意版本号放在那里)。

故障排查

增加日志详细程度

作业日志不包含有关依赖扫描失败的足够信息时,SECURE_LOG_LEVEL 设置为 debug,并检查生成的更详细的日志。

解决缺少对某些语言或包管理器的支持

“支持的语言” 部分中所述,某些依赖项定义文件尚不支持。 但是,如果语言、包管理器或第三方工具可以将定义文件转换为支持的格式,则可以实现依赖扫描。

一般来说,方法如下:

  1. .gitlab-ci.yml 文件中定义一个专用的转换器作业。使用合适的 Docker 镜像、脚本或两者皆有,来促进转换。
  2. 让该作业将转换后的受支持文件作为产物上传。
  3. dependencies: [<your-converter-job>] 添加到您的 dependency_scanning 作业中,来使用转换后的定义文件。

例如,pyproject.toml 文件的 Poetry 项目可以生成 poetry.lock 文件,如下所示。

include:
  - template: Security/Dependency-Scanning.gitlab-ci.yml

stages:
  - test

gemnasium-python-dependency_scanning:
  # Work around https://gitlab.com/gitlab-org/gitlab/-/issues/32774
  before_script:
    - pip install "poetry>=1,<2"  # Or via another method: https://python-poetry.org/docs/#installation
    - poetry update --lock # Generates the lock file to be analyzed.

Error response from daemon: error processing tar file: docker-tar: relocation error

当运行依赖扫描作业的 Docker 版本为 19.03.0 时会出现此错误。考虑更新到 Docker 19.03.1 或更高版本。旧版本不受影响。

警告消息 gl-dependency-scanning-report.json: no matching files

获取更多信息,查阅一般应用程序安全故障排查部分

使用 rules:exists 的限制

依赖项扫描 CI 模板使用 rules:exists 语法。该指令限制为 10000 次检查,并且在达到此数量后始终返回 true。因此,根据仓库中文件的数量,即使扫描程序不支持您的项目,也可能会触发依赖项扫描作业。

为基于 Java 的项目导入多个证书

gemnasium-maven 分析器使用 keytool 读取 ADDITIONAL_CA_CERT_BUNDLE 变量的内容,导入单个证书或证书链。多个不相关的证书被忽略,只有第一个由 keytool 导入。

要将多个不相关的证书添加到分析器,您可以在 gemnasium-maven-dependency_scanning 作业的定义中声明一个 before_script,例如:

gemnasium-maven-dependency_scanning:
  before_script:
    - . $HOME/.bashrc # make the java tools available to the script
    - OIFS="$IFS"; IFS=""; echo $ADDITIONAL_CA_CERT_BUNDLE > multi.pem; IFS="$OIFS" # write ADDITIONAL_CA_CERT_BUNDLE variable to a PEM file
    - csplit -z --digits=2 --prefix=cert multi.pem "/-----END CERTIFICATE-----/+1" "{*}" # split the file into individual certificates
    - for i in `ls cert*`; do keytool -v -importcert -alias "custom-cert-$i" -file $i -trustcacerts -noprompt -storepass changeit -keystore /opt/asdf/installs/java/adoptopenjdk-11.0.7+10.1/lib/security/cacerts 1>/dev/null 2>&1 || true; done # import each certificate using keytool (note the keystore location is related to the Java version being used and should be changed accordingly for other versions)
    - unset ADDITIONAL_CA_CERT_BUNDLE # unset the variable so that the analyzer doesn't duplicate the import

依赖项扫描作业失败并显示消息 strconv.ParseUint: parsing "0.0": invalid syntax

调用 Docker-in-Docker 可能是导致此错误的原因。Docker-in-Docker:

  • 在 13.0 及更高版本中默认禁用。
  • 13.4 及更高版本不支持。

要修复此错误,请禁用 Docker-in-Docker 进行依赖扫描,为在 CI/CD 流水线中运行的每个分析器创建单独的 <analyzer-name>-dependency_scanning 作业。

include:
  - template: Dependency-Scanning.gitlab-ci.yml

variables:
  DS_DISABLE_DIND: "true"

消息 <file> does not exist in <commit SHA>

当显示文件中依赖项的 Location 时,链接中的路径会转到特定的 Git SHA。

但是,如果我们的依赖项扫描工具检查的 lockfile 已被缓存,则选择该链接会将您重定向到仓库根目录,并显示消息:<file> does not exist in <commit SHA>

Lockfile 在构建阶段被缓存,并在扫描发生之前传递给依赖扫描作业。因为缓存是在分析器运行之前下载的,所以在 CI_BUILDS_DIR 目录中存在 lockfile 会触发依赖项扫描作业。

我们建议提交 lockfile,以防止出现此警告。

设置 DS_MAJOR_VERSIONDS_ANALYZER_IMAGE 后,我不再获得最新的 Docker 镜像

如果您出于特定原因手动设置了 DS_MAJOR_VERSIONDS_ANALYZER_IMAGE,现在必须更新配置以再次获取我们分析器的最新修补版本,请编辑 gitlab-ci.yml 文件,然后:

  • 设置您的 DS_MAJOR_VERSION 来匹配最新版本,如我们当前的依赖扫描模板
  • 如果您直接硬编码 DS_ANALYZER_IMAGE 变量,请将其更改为与我们当前的依赖扫描模板中找到的最新行匹配。行号将根据您编辑的扫描作业而有所不同。

    例如,当前 gemnasium-maven-dependency_scanning 作业会拉取最新的 gemnasium-maven Docker 镜像,因为 DS_ANALYZER_IMAGE 设置为 "$SECURE_ANALYZERS_PREFIX/gemnasium-maven:$DS_MAJOR_VERSION"

setuptools 项目的依赖项扫描失败,出现 use_2to3 is invalid 错误

2to3 的支持已在 setuptools 版本 v58.0.0删除。依赖扫描(运行 python 3.9)使用 setuptools 版本 58.1.0+,不支持 2to3。 因此,依赖于 lib2to3setuptools 依赖项将失败并显示以下消息:

error in <dependency name> setup command: use_2to3 is invalid

要解决此错误,请降级分析器的 setuptools 版本(例如 v57.5.0):

gemnasium-python-dependency_scanning:
  before_script:
    - pip install setuptools==57.5.0

使用 psycopg2 对项目的依赖项扫描失败,并出现 pg_config executable not found 错误

扫描依赖于 psycopg2 的 Python 项目可能会失败并显示以下消息:

Error: pg_config executable not found.

psycopg2 依赖于 libpq-dev Debian 软件包,它没有安装在 gemnasium-python Docker 镜像中。要解决此错误,请在 before_script 中安装 libpq-dev 包:

gemnasium-python-dependency_scanning:
  before_script:
    - apt-get update && apt-get install -y libpq-dev