Help us learn about your current experience with the documentation. Take the survey.

依赖扫描故障排除

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated

在使用依赖扫描时,您可能会遇到以下问题。

调试级别日志

调试级别日志可以帮助故障排除。详细信息请参阅调试级别日志

在本地环境中运行分析器

您可以在本地运行依赖扫描分析器来调试问题或在不运行管道的情况下验证行为。

例如,运行 Python 分析器:

cd project-git-repository

docker run \
   --interactive --tty --rm \
   --volume "$PWD":/tmp/app \
   --env CI_PROJECT_DIR=/tmp/app \
   --env SECURE_LOG_LEVEL=debug \
   -w /tmp/app \
   registry.gitlab.com/security-products/gemnasium-python:5 /analyzer run

此命令以调试级别日志运行分析器,并挂载您的本地仓库来分析依赖项。 您可以将 registry.gitlab.com/security-products/gemnasium-python:5 替换为适合您项目语言和包管理器的扫描器 image:tag 组合。

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

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

通常,方法如下:

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

例如,只有 pyproject.toml 文件的 Poetry 项目可以按如下方式生成 poetry.lock 文件。

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

stages:
  - test

gemnasium-python-dependency_scanning:
  # 解决 https://gitlab.com/gitlab-org/gitlab/-/issues/32774
  before_script:
    - pip install "poetry>=1,<2"  # 或通过其他方法:https://python-poetry.org/docs/#installation
    - poetry update --lock # 生成要分析的锁文件。

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

相关信息请参阅通用应用安全故障排除部分

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

当运行依赖扫描任务的 Docker 版本为 19.03.0 时会发生此错误。 请考虑更新到 Docker 19.03.1 或更高版本。旧版本不受影响。 更多信息请参阅此问题

依赖扫描任务意外运行

依赖扫描 CI 模板 使用 rules:exists 语法。此指令限制为 10000 次检查,达到此数量后总是返回 true。 因此,根据您仓库中的文件数量,即使扫描器不支持您的项目,也可能触发依赖扫描任务。 有关此限制的更多详细信息,请参阅 rules:exists 文档

错误:dependency_scanning 仅用于配置,不应执行其脚本

相关信息请参阅GitLab 安全故障排除部分

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

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

要向分析器添加多个不相关的证书,您可以在 gemnasium-maven-dependency_scanning 任务的定义中声明一个 before_script,如下所示:

gemnasium-maven-dependency_scanning:
  before_script:
    - . $HOME/.bashrc # 使 Java 工具对脚本可用
    - OIFS="$IFS"; IFS=""; echo $ADDITIONAL_CA_CERT_BUNDLE > multi.pem; IFS="$OIFS" # 将 ADDITIONAL_CA_CERT_BUNDLE 变量写入 PEM 文件
    - csplit -z --digits=2 --prefix=cert multi.pem "/-----END CERTIFICATE-----/+1" "{*}" # 将文件拆分为单个证书
    - 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 # 使用 keytool 导入每个证书(注意密钥库位置与使用的 Java 版本相关,其他版本应相应更改)
    - unset ADDITIONAL_CA_CERT_BUNDLE # 取消设置变量,避免分析器重复导入

依赖扫描任务失败,消息为 strconv.ParseUint: parsing "0.0": invalid syntax

Docker-in-Docker 不受支持,尝试调用它很可能是导致此错误的原因。

要修复此错误,请为依赖扫描禁用 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。

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

锁文件在构建阶段被缓存,并在扫描发生前传递给依赖扫描任务。因为缓存在分析器运行前被下载,所以 CI_BUILDS_DIR 目录中锁文件的存在会触发依赖扫描任务。

要防止此警告,应该提交锁文件。

设置 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

使用 CI_JOB_TOKENpoetry config http-basic 时出现 NoSuchOptionException

当自动生成的 CI_JOB_TOKEN 以连字符(-)开头时,可能会发生此错误。 要避免此错误,请遵循Poetry 的配置建议

错误:项目有未解析的依赖项

以下错误消息表明您的 build.gradlebuild.gradle.kts 文件存在 Gradle 依赖解析问题:

  • Project has <number> unresolved dependencies (GitLab 16.7 到 16.9)
  • project has unresolved dependencies: ["dependency_name:version"] (GitLab 17.0 及更高版本)

在 GitLab 16.7 到 16.9 中,当遇到未解析的依赖项时,gemnasium-maven 无法继续处理。

在 GitLab 17.0 及更高版本中,gemnasium-maven 支持 DS_GRADLE_RESOLUTION_POLICY 环境变量,您可以使用它来控制如何处理未解析的依赖项。默认情况下,遇到未解析的依赖项时扫描会失败。但是,您可以将环境变量 DS_GRADLE_RESOLUTION_POLICY 设置为 "none",以允许扫描继续并生成部分结果。

有关修复 build.gradle 文件的指导,请参阅Gradle 依赖解析文档。更多详细信息,请参阅问题 482650

此外,Kotlin 2.0.0 中存在一个已知的依赖解析问题,计划在 Kotlin 2.0.20 中修复。 更多信息请参阅此问题

扫描 Go 项目时设置构建约束

依赖扫描在 linux/amd64 容器中运行。因此,为 Go 项目生成的构建列表包含与此环境兼容的依赖项。如果您的部署环境不是 linux/amd64,最终的依赖项列表可能包含额外的兼容模块。依赖项列表也可能省略仅与您的部署环境兼容的模块。为防止此问题,您可以通过设置 .gitlab-ci.yml 文件的 GOOSGOARCH 环境变量来配置构建过程以针对部署环境的操作系统和架构。

例如:

variables:
  GOOS: "darwin"
  GOARCH: "arm64"

您还可以使用 GOFLAGS 变量提供构建标签约束:

variables:
  GOFLAGS: "-tags=test_feature"

Go 项目的依赖扫描返回误报

go.sum 文件包含在生成项目构建列表时考虑的每个模块的条目。 模块的多个版本包含在 go.sum 文件中,但 go build 使用的MVS 算法只选择一个。因此,当依赖扫描使用 go.sum 时,可能会报告误报。

为防止误报,Gemnasium 仅在无法为 Go 项目生成构建列表时才使用 go.sum。如果选择了 go.sum,会出现警告:

[WARN] [Gemnasium] [2022-09-14T20:59:38Z] ▶ 为 "/test-projects/gitlab-shell/go.sum" 选择 "go.sum" 解析器。可能会出现误报。请参阅 https://gitlab.com/gitlab-org/gitlab/-/issues/321081。

尝试使用 ssh 时出现 Host key verification failed

在任何 gemnasium 镜像上安装 openssh-client 后,使用 ssh 可能会导致 Host key verification failed 消息。如果在设置期间使用 ~ 表示用户目录,由于构建镜像时将 $HOME 设置为 /tmp,可能会发生此问题。此问题在使用 gemnasium-python 镜像通过 SSH 克隆项目失败中有所描述。openssh-client 期望找到 /root/.ssh/known_hosts,但此路径不存在;实际存在的是 /tmp/.ssh/known_hosts

这已在 gemnasium-python 中得到解决,其中 openssh-client 是预安装的,但在其他镜像上从头安装 openssh-client 时仍可能发生此问题。要解决此问题,您可以:

  1. 在设置密钥和主机时使用绝对路径(使用 /root/.ssh/known_hosts 而不是 ~/.ssh/known_hosts)。
  2. 向您的 ssh 配置添加 UserKnownHostsFile,指定相关的 known_hosts 文件,例如:echo 'UserKnownHostsFile /tmp/.ssh/known_hosts' >> /etc/ssh/ssh_config

ERROR: THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE

requirements.txt 文件中某个包的哈希值与下载包的哈希值不匹配时,会发生此错误。 作为安全措施,pip 会假设包已被篡改并拒绝安装它。 要修复此问题,请确保 requirements 文件中包含的哈希值是正确的。 对于由 pip-compile 生成的 requirements 文件,运行 pip-compile --generate-hashes 以确保哈希值是最新的。 如果使用由 pipenv 生成的 Pipfile.lock,运行 pipenv verify 以验证锁文件包含最新的包哈希值。

ERROR: In --require-hashes mode, all requirements must have their versions pinned with ==

如果 requirements 文件是在与 GitLab Runner 使用的平台不同的平台上生成的,则会发生此错误。 支持针对其他平台的功能在问题 416376中跟踪。

可编辑标志可能导致 Python 依赖扫描挂起

如果在 requirements.txt 文件中使用 -e/--editable 标志来定位当前目录,您可能会遇到一个问题,导致 Gemnasium Python 依赖扫描器在运行 pip3 download 时挂起。 此命令是构建目标项目所必需的。

要解决此问题,在运行 Python 依赖扫描时不要使用 -e/--editable 标志。

使用 SBT 处理内存不足错误

如果在 Scala 项目中使用依赖扫描时遇到 SBT 内存不足错误,您可以通过设置 SBT_CLI_OPTS 环境变量来解决此问题。示例配置如下:

variables:
  SBT_CLI_OPTS: "-J-Xmx8192m -J-Xms4192m -J-Xss2M"

如果您使用 Kubernetes 执行器,可能需要覆盖默认的 Kubernetes 资源设置。有关如何调整容器资源以防止内存问题的详细信息,请参阅Kubernetes 执行器文档

NPM 项目中没有 package-lock.json 文件

默认情况下,依赖扫描任务仅在仓库中存在 package-lock.json 文件时运行。但是,一些 NPM 项目在构建过程中生成 package-lock.json 文件,而不是将其存储在 Git 仓库中。

要扫描这些项目中的依赖项:

  1. 在构建任务中生成 package-lock.json 文件。
  2. 将生成的文件存储为 artifact。
  3. 修改依赖扫描任务以使用该 artifact 并调整其规则。

例如,您的配置可能如下所示:

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

build:
  script:
    - npm i
  artifacts:
    paths:
      - package-lock.json  # 将生成的 package-lock.json 存储为 artifact

gemnasium-dependency_scanning:
  needs: ["build"]
  rules:
    - if: "$DEPENDENCY_SCANNING_DISABLED == 'true' || $DEPENDENCY_SCANNING_DISABLED == '1'"
      when: never
    - if: "$DS_EXCLUDED_ANALYZERS =~ /gemnasium([^-]|$)/"
      when: never
    - if: "$CI_COMMIT_BRANCH && $GITLAB_FEATURES =~ /\bdependency_scanning\b/ && $CI_GITLAB_FIPS_MODE == "true""
      variables:
        DS_IMAGE_SUFFIX: "-fips"
        DS_REMEDIATE: 'false'
    - if: "$CI_COMMIT_BRANCH && $GITLAB_FEATURES =~ /\bdependency_scanning\b/"

管道中没有添加依赖扫描任务

依赖扫描任务使用规则来检查是否存在包含依赖项的锁文件或构建工具相关文件。如果未检测到这些文件,则不会将任务添加到管道中,即使锁文件是由管道中的另一个任务生成的。

如果您遇到这种情况,请确保您的仓库包含支持文件, 或指示支持文件在运行时生成的文件。 考虑是否可以将此类文件添加到您的仓库中以触发依赖扫描任务。

如果您相信您的仓库确实包含此类文件但任务仍未触发,打开一个问题并提供以下信息:

  • 您使用的语言和构建工具。
  • 您提供什么类型的锁文件以及它在何处生成。

您也可以直接贡献到依赖扫描模板

依赖扫描失败,出现 gradlew: permission denied 错误

gradlew 上的 permission denied 错误通常表示 gradlew 被检入仓库时没有设置可执行位。错误可能以以下消息出现在您的任务中:

[FATA] [gemnasium-maven] [2024-11-14T21:55:59Z] [/go/src/app/cmd/gemnasium-maven/main.go:65] ▶ fork/exec /builds/path/to/gradlew: permission denied

通过在本地运行 chmod +ux gradlew 并将其推送到您的 Git 仓库来使文件可执行。

依赖扫描扫描器不再是 Gemnasium

历史上,依赖扫描使用的扫描器是 Gemnasium,这是用户可以在漏洞页面上看到的。

随着使用 SBOM 进行依赖扫描的推出,我们正在用内置的 GitLab SBoM 漏洞扫描器 替换 Gemnasium 扫描器。这个新扫描器不再在 CI/CD 任务中执行,而是在 GitLab 平台中执行。虽然两个扫描器预期会提供相同的结果,但由于 SBOM 扫描发生在现有的依赖扫描 CI/CD 任务之后,现有漏洞的扫描器值已更新为新的 GitLab SBoM 漏洞扫描器

随着我们继续推进部署并最终替换现有的 Gemnasium 分析器,GitLab SBoM 漏洞扫描器 将是 GitLab 内置依赖扫描功能的唯一预期值。

项目的依赖列表未根据最新的 SBOM 更新

当管道中有生成 SBOM 的失败任务时,DeleteNotPresentOccurrencesService 不会执行,这会阻止依赖列表被更改或更新。即使有其他成功上传 SBOM 的任务,并且管道整体成功,也可能发生这种情况。这是为了防止在相关安全扫描任务失败时意外从依赖列表中删除依赖项。如果项目依赖列表未按预期更新,请检查管道中可能失败的任何 SBOM 相关任务,并修复或删除它们。