InfoGrab DocsInfoGrab Docs

의존성 스캐닝 문제 해결

요약

의존성 스캐닝을 사용할 때 다음과 같은 문제가 발생할 수 있습니다. 디버그 수준 로깅은 문제 해결에 도움이 됩니다. 파이프라인을 실행하지 않고도 로컬에서 의존성 스캐닝 분석기를 실행해 문제를 디버깅하거나 동작을 확인할 수 있습니다.

의존성 스캐닝을 사용할 때 다음과 같은 문제가 발생할 수 있습니다.

디버그 수준 로깅#

디버그 수준 로깅은 문제 해결에 도움이 됩니다. 자세한 내용은 디버그 수준 로깅을 참고합니다.

로컬 환경에서 분석기 실행#

파이프라인을 실행하지 않고도 로컬에서 의존성 스캐닝 분석기를 실행해 문제를 디버깅하거나 동작을 확인할 수 있습니다.

예를 들어 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 파일에 전용 변환 job을 정의합니다. 적합한 Docker 이미지, 스크립트 또는 둘 다를 사용해 변환을 수행합니다.
  2. 해당 job 이 변환된 지원 형식 파일을 아티팩트로 업로드하도록 합니다.
  3. 변환된 정의 파일을 사용하도록 dependency_scanning job에 dependencies: [<your-converter-job>]을 추가합니다.

예를 들어 pyproject.toml 파일만 있는 Poetry 프로젝트는 다음과 같이 poetry.lock 파일을 생성할 수 있습니다.

include:
  - template: Jobs/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 lockfile to be analyzed.

의존성 스캐닝 job 이 예기치 않게 실행되는 문제#

의존성 스캐닝 CI 템플릿은 rules:exists 구문을 사용합니다. 이 지시문은 검사 10000회로 제한되며 이 횟수에 도달하면 항상 true를 반환합니다. 이 때문에 리포지터리의 파일 수에 따라, 스캐너가 프로젝트를 지원하지 않더라도 의존성 스캐닝 job 이 트리거될 수 있습니다. 이 제한에 대한 자세한 내용은 rules:exists 문서를 참고합니다.

오류: dependency_scanning is used for configuration only, and its script should not be executed#

자세한 내용은 애플리케이션 보안 테스트 문제 해결을 참고합니다.

Java 기반 프로젝트에 여러 인증서 가져오기#

gemnasium-maven 분석기는 keytool로 ADDITIONAL_CA_CERT_BUNDLE 변수의 내용을 읽으며, 단일 인증서 또는 인증서 체인을 가져옵니다. 서로 연관되지 않은 여러 인증서는 무시되고 keytool은 첫 번째 인증서만 가져옵니다.

서로 연관되지 않은 여러 인증서를 분석기에 추가하려면 gemnasium-maven-dependency_scanning job 정의에 다음과 같은 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

의존성 스캐닝 job 이 strconv.ParseUint: parsing "0.0": invalid syntax 메시지와 함께 실패하는 문제#

Docker-in-Docker는 지원되지 않으며, 이를 호출하려는 시도가 이 오류의 원인일 가능성이 높습니다.

이 오류를 해결하려면 의존성 스캐닝에서 Docker-in-Docker를 비활성화합니다. CI/CD 파이프라인에서 실행되는 분석기마다 개별 <analyzer-name>-dependency_scanning job 이 생성됩니다.

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은 빌드 단계에서 캐시되어 스캔이 시작되기 전에 의존성 스캐닝 job으로 전달됩니다. 캐시는 분석기 실행 전에 다운로드되므로, CI_BUILDS_DIR 디렉터리에 lockfile 이 존재하면 의존성 스캐닝 job 이 트리거됩니다.

이 경고를 방지하려면 lockfile을 커밋해야 합니다.

DS_MAJOR_VERSION 또는 DS_ANALYZER_IMAGE 설정 후 최신 Docker 이미지를 받지 못하는 문제#

특정한 이유로 DS_MAJOR_VERSION 또는 DS_ANALYZER_IMAGE를 직접 설정했고, 이제 분석기의 최신 패치 버전을 다시 받도록 구성을 갱신해야 한다면 .gitlab-ci.yml 파일을 편집해 다음 중 하나를 수행합니다.

  • DS_MAJOR_VERSION을 의존성 스캐닝 템플릿에서 참조하는 버전과 맞춥니다.

  • DS_ANALYZER_IMAGE 변수를 직접 하드코딩했다면 의존성 스캐닝 템플릿의 최신 줄과 맞도록 변경합니다. 줄 번호는 편집한 스캐닝 job에 따라 달라집니다.

    예를 들어 gemnasium-maven-dependency_scanning job은 DS_ANALYZER_IMAGE가 "$SECURE_ANALYZERS_PREFIX/gemnasium-maven:$DS_MAJOR_VERSION"으로 설정되어 있으므로 최신 gemnasium-maven Docker 이미지를 가져옵니다.

setuptools 프로젝트 의존성 스캐닝이 use_2to3 is invalid 오류와 함께 실패하는 문제#

2to3 지원은 setuptools 버전 v58.0.0에서 제거되었습니다. 의존성 스캐닝은 python 3.9로 실행되며 2to3를 지원하지 않는 setuptools 버전 58.1.0+를 사용합니다. 따라서 lib2to3에 의존하는 setuptools 의존성은 다음 메시지와 함께 실패합니다.

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는 Debian 패키지 libpq-dev에 의존하지만, 이 패키지는 gemnasium-python Docker 이미지에 설치되어 있지 않습니다. 이 오류를 우회하려면 before_script에서 libpq-dev 패키지를 설치합니다.

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

CI_JOB_TOKEN과 함께 poetry config http-basic을 사용할 때 발생하는 NoSuchOptionException#

이 오류는 자동으로 생성된 CI_JOB_TOKEN 이 하이픈(-)으로 시작할 때 발생할 수 있습니다. 이 오류를 피하려면 Poetry의 구성 안내를 따릅니다.

오류: project has unresolved dependencies#

다음 오류 메시지는 build.gradle 또는 build.gradle.kts 파일로 인해 발생한 Gradle 의존성 해석 문제를 나타냅니다.

  • project has unresolved dependencies: ["dependency_name:version"]

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 파일의 GOOS 및 GOARCH 환경 변수를 설정해 배포 환경의 운영 체제와 아키텍처를 대상으로 빌드 과정을 구성할 수 있습니다.

예를 들면 다음과 같습니다.

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] ▶ Selecting "go.sum" parser for "/test-projects/gitlab-shell/go.sum". False positives may occur. See https://gitlab.com/gitlab-org/gitlab/-/issues/321081.

ssh 사용 시 발생하는 Host key verification failed#

gemnasium 이미지에 openssh-client를 설치한 뒤 ssh를 사용하면 Host key verification failed 메시지가 나타날 수 있습니다. 이미지를 빌드할 때 $HOME 이 /tmp로 설정되기 때문에, 설정 과정에서 사용자 디렉터리를 ~로 표기하면 이 현상이 발생할 수 있습니다. 이 문제는 Cloning project over SSH fails when using gemnasium-python image에 설명되어 있습니다. openssh-client는 /root/.ssh/known_hosts를 찾지만 이 경로는 존재하지 않고, 대신 /tmp/.ssh/known_hosts가 존재합니다.

openssh-client가 미리 설치된 gemnasium-python에서는 이 문제가 해결되었으나, 다른 이미지에 openssh-client를 새로 설치하면 발생할 수 있습니다. 해결 방법은 다음 두 가지입니다.

  1. 키와 호스트를 설정할 때 ~/.ssh/known_hosts 대신 절대 경로(/root/.ssh/known_hosts)를 사용합니다.
  2. ssh 구성에 해당 known_hosts 파일을 지정하는 UserKnownHostsFile을 추가합니다. 예: 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를 실행해 lockfile에 최신 패키지 해시가 들어 있는지 확인합니다.

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

이 오류는 requirements 파일이 GitLab Runner가 사용하는 플랫폼과 다른 플랫폼에서 생성된 경우에 발생합니다. 다른 플랫폼을 대상으로 하는 지원은 이슈 416376에서 추적하고 있습니다.

Editable 플래그로 인해 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 executor를 사용한다면 기본 Kubernetes 리소스 설정을 재정의해야 할 수 있습니다. 메모리 문제를 방지하기 위한 컨테이너 리소스 조정 방법은 Kubernetes executor 문서를 참고합니다.

NPM 프로젝트에 package-lock.json 파일이 없는 경우#

기본적으로 의존성 스캐닝 job은 리포지터리에 package-lock.json 파일이 있을 때만 실행됩니다. 그러나 일부 NPM 프로젝트는 package-lock.json 파일을 Git 리포지터리에 저장하지 않고 빌드 과정에서 생성합니다.

이러한 프로젝트의 의존성을 스캔하려면 다음과 같이 합니다.

  1. 빌드 job에서 package-lock.json 파일을 생성합니다.
  2. 생성된 파일을 아티팩트로 저장합니다.
  3. 의존성 스캐닝 job 이 그 아티팩트를 사용하도록 수정하고 규칙을 조정합니다.

예를 들어 구성은 다음과 같은 형태가 됩니다.

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

build:
  script:
    - npm i
  artifacts:
    paths:
      - package-lock.json  # Store the generated package-lock.json as an 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/"

파이프라인에 의존성 스캐닝 job 이 추가되지 않는 문제#

의존성 스캐닝 job은 규칙을 사용해 의존성이 담긴 lockfile 또는 빌드 도구 관련 파일이 있는지 확인합니다. 이런 파일이 하나도 감지되지 않으면, 파이프라인의 다른 job 이 lockfile을 생성하더라도 해당 job은 파이프라인에 추가되지 않습니다.

이런 상황이 발생하면 리포지터리에 지원되는 파일 또는 지원되는 파일이 런타임에 생성됨을 나타내는 파일이 있는지 확인합니다. 의존성 스캐닝 job을 트리거할 수 있도록 이런 파일을 리포지터리에 추가할 수 있는지 검토합니다.

리포지터리에 그런 파일이 있는데도 job 이 트리거되지 않는다면 다음 정보를 담아 이슈를 등록합니다.

  • 사용 중인 언어와 빌드 도구.
  • 제공하는 lockfile의 종류와 생성 위치.

의존성 스캐닝 템플릿에 직접 기여할 수도 있습니다.

의존성 스캐닝이 gradlew: permission denied와 함께 실패하는 문제#

gradlew의 permission denied 오류는 대개 실행 비트가 설정되지 않은 채 gradlew가 리포지터리에 커밋되었음을 의미합니다. job에 다음과 같은 메시지로 나타날 수 있습니다.

[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 리포지터리에 푸시합니다.

지원되지 않는 Gradle 버전으로 인해 의존성 스캐닝 nebula lock 생성이 실패하는 문제#

지원되지 않는 Gradle 버전(9.0 이상)으로 dependency.lockfiles을 생성하려고 하면 다음 오류가 발생합니다.

FAILURE: Build failed with an exception.
* Where:
Initialization script '/builds/gitlab-org/app/app/nebula.gradle' line: 11
* What went wrong:
Failed to notify build listener.
> org/gradle/util/NameMatcher

gradle 빌드를 Gradle 8.10.2로 낮춰 봅니다.

의존성 스캐닝 스캐너가 더 이상 Gemnasium 이 아닌 경우#

지금까지 의존성 스캐닝이 사용한 스캐너는 Gemnasium 이었고, 사용자는 취약점 페이지에서 이 값을 확인할 수 있었습니다.

SBOM을 사용한 의존성 스캐닝이 배포되면서 Gemnasium 스캐너는 내장 GitLab SBoM Vulnerability Scanner로 대체되었습니다. 이 새 스캐너는 CI/CD job 이 아니라 GitLab 플랫폼 안에서 실행됩니다. 두 스캐너는 동일한 결과를 제공할 것으로 예상되지만, SBOM 스캔이 기존 의존성 스캐닝 CI/CD job 이후에 일어나므로 기존 취약점의 스캐너 값은 새 GitLab SBoM Vulnerability Scanner로 갱신됩니다.

GitLab 내장 의존성 스캐닝 기능에서 예상되는 값은 GitLab SBoM Vulnerability Scanner 뿐입니다.

프로젝트 의존성 목록이 최신 SBOM 기준으로 업데이트되지 않는 문제#

SBOM을 생성할 job 이 파이프라인에서 실패하면 DeleteNotPresentOccurrencesService가 실행되지 않아 의존성 목록이 변경되거나 업데이트되지 않습니다. SBOM을 업로드하는 다른 job 이 성공하고 파이프라인 전체가 성공하더라도 이 현상이 발생할 수 있습니다. 이는 관련 보안 스캐닝 job 이 실패했을 때 의존성 목록에서 의존성이 실수로 제거되는 것을 막기 위한 설계입니다. 프로젝트 의존성 목록이 예상대로 업데이트되지 않는다면 파이프라인에서 실패한 SBOM 관련 job 이 있는지 확인하고, 해당 job을 수정하거나 제거합니다.

의존성 스캐닝이 open /etc/ssl/certs/ca-certificates.crt: permission denied와 함께 실패하는 문제#

이 오류는 대개 컨테이너를 실행하는 사용자가 root 그룹에 속하지 않았음을 나타냅니다. id를 실행해 사용자가 해당 그룹에 속해 있는지 확인합니다.

$ id
uid=1000(node) gid=0(root) groups=0(root),1000(node)

OpenShift를 실행 중이거나 Kubernetes executor를 사용한다면 러너가 그룹 ID(GID) 0으로 실행되도록 구성합니다.

[[runners]]
[runners.kubernetes]
    [runners.kubernetes.pod_security_context]
    run_as_non_root = true
    run_as_group = 0

사용자 지정 또는 병합된 CycloneDX SBOM에서 취약점 스캔 결과가 나오지 않는 문제#

의존성 스캐닝 CI/CD job은 성공하고 SBOM 컴포넌트도 의존성 목록에 나타나지만, 파이프라인 보안 탭에는 취약점이 보고되지 않습니다.

GitLab 18.10 이상에서는 보안 탭에 "SBOM report is missing required GitLab metadata properties needed for vulnerability scanning." 메시지가 표시됩니다.

이 문제는 SBOM에 필수 GitLab CycloneDX 속성이 없을 때 발생합니다. 이런 속성이 없으면 취약점 스캐너가 SBOM의 컴포넌트에 대한 결과를 구성할 수 없습니다. 의존성 목록은 여전히 채워지지만 취약점은 보고되지 않습니다.

이 현상은 주로 다음과 같은 경우에 발생합니다.

  • 여러 SBOM을 cyclonedx merge로 병합해 메타데이터 속성이 제거된 경우.
  • 서드파티 SBOM 생성기가 GitLab 고유 속성을 포함하지 않는 경우.
  • metadata.properties에 gitlab:meta:schema_version 속성(값은 1 이어야 합니다)이 없는 경우.

취약점 스캔에 필요한 속성#

속성 위치 설명
gitlab:meta:schema_version metadata.properties 반드시 1로 설정해야 합니다.
gitlab:dependency_scanning:input_file:path metadata.properties 또는 각 컴포넌트의 properties 의존성을 생성하기 위해 분석한 lockfile의 경로입니다. 둘 다 없으면 해당 컴포넌트에 대한 취약점 결과가 생성되지 않습니다. GitLab 18.10 이상에서는 파이프라인 보안 탭에 오류가 표시됩니다.

이 문제를 해결하려면 다음 방법 중 하나를 선택합니다.

  • 각 SBOM을 개별적으로 업로드합니다.

    병합하는 대신 각 SBOM을 별도의 artifacts: reports: cyclonedx: 항목으로 업로드합니다. 이렇게 하면 각 파일의 GitLab 고유 속성이 보존됩니다.

  • 서드파티 SBOM에 속성을 추가합니다.

    서드파티 도구가 생성한 SBOM은 대개 GitLab 고유 속성을 포함하지 않습니다. 취약점 스캔을 사용하려면 SBOM의 metadata.properties에 다음이 포함되어야 합니다.

    • gitlab:meta:schema_version을 1로 설정
    • gitlab:dependency_scanning:input_file:path를 lockfile의 리포지터리 기준 상대 경로로 설정(예: package-lock.json 또는 src/Gemfile.lock)

    SBOM에 여러 lockfile의 컴포넌트가 포함되어 있다면 각 컴포넌트가 올바른 소스 파일을 가리키도록 메타데이터가 아니라 각 컴포넌트의 properties 배열에 input_file:path를 설정합니다. 지원되는 속성의 전체 목록은 GitLab CycloneDX 속성 분류를 참고합니다.

자세한 내용은 이슈 542813과 머지 리퀘스트 221549를 참고합니다.

취약점 스캔이 모든 의존성에 잘못된 입력 파일을 표시하는 문제#

취약점 보고서나 의존성 목록의 모든 의존성이 서로 다른 lockfile에서 비롯되었는데도 동일한 입력 파일 경로를 표시합니다.

이 문제는 gitlab:dependency_scanning:input_file:path 속성이 컴포넌트별이 아니라 metadata.properties에 설정되었을 때 발생합니다. 속성 분류에 따르면 메타데이터 수준 속성은 문서의 모든 객체에 적용되므로, 단일 값이 모든 컴포넌트를 재정의합니다.

이 문제를 해결하려면 최상위 메타데이터가 아니라 각 컴포넌트의 properties 배열에 input_file:path를 개별적으로 설정합니다. input_file:path 속성은 서로 다른 lockfile의 컴포넌트를 포함하는 병합된 SBOM에서 특히 중요합니다.

오류: node with package name <package_name> does not exist#

이 문제는 패키지 관리자(대개 nuget)가 패키지를 찾지 못할 때 발생합니다. 애플리케이션을 빌드하는 데 사용한 이미지와 의존성 스캔을 실행하는 데 사용한 이미지가 달라서 발생할 수 있습니다.

이 문제를 해결하려면 의존성 스캐너가 애플리케이션을 빌드할 때 사용하는 것과 동일한 .NET SDK 이미지를 사용합니다. 다음을 실행하면 정확한 이미지를 확인할 수 있습니다.

curl --silent "https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/raw/master/build/gemnasium/alpine/Dockerfile" | grep "vrange-nuget-build" | grep "FROM"

위에 링크된 Dockerfile에서 현재 이미지 버전을 확인합니다.

의존성 스캐닝 문제 해결

GitLab v19.4
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 파일에 전용 변환 job을 정의합니다. 적합한 Docker 이미지, 스크립트 또는 둘 다를 사용해 변환을 수행합니다.
  2. 해당 job 이 변환된 지원 형식 파일을 아티팩트로 업로드하도록 합니다.
  3. 변환된 정의 파일을 사용하도록 dependency_scanning job에 dependencies: [<your-converter-job>]을 추가합니다.

예를 들어 pyproject.toml 파일만 있는 Poetry 프로젝트는 다음과 같이 poetry.lock 파일을 생성할 수 있습니다.

include:
  - template: Jobs/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 lockfile to be analyzed.

의존성 스캐닝 job 이 예기치 않게 실행되는 문제#

의존성 스캐닝 CI 템플릿은 rules:exists 구문을 사용합니다. 이 지시문은 검사 10000회로 제한되며 이 횟수에 도달하면 항상 true를 반환합니다. 이 때문에 리포지터리의 파일 수에 따라, 스캐너가 프로젝트를 지원하지 않더라도 의존성 스캐닝 job 이 트리거될 수 있습니다. 이 제한에 대한 자세한 내용은 rules:exists 문서를 참고합니다.

오류: dependency_scanning is used for configuration only, and its script should not be executed#

자세한 내용은 애플리케이션 보안 테스트 문제 해결을 참고합니다.

Java 기반 프로젝트에 여러 인증서 가져오기#

gemnasium-maven 분석기는 keytool로 ADDITIONAL_CA_CERT_BUNDLE 변수의 내용을 읽으며, 단일 인증서 또는 인증서 체인을 가져옵니다. 서로 연관되지 않은 여러 인증서는 무시되고 keytool은 첫 번째 인증서만 가져옵니다.

서로 연관되지 않은 여러 인증서를 분석기에 추가하려면 gemnasium-maven-dependency_scanning job 정의에 다음과 같은 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

의존성 스캐닝 job 이 strconv.ParseUint: parsing "0.0": invalid syntax 메시지와 함께 실패하는 문제#

Docker-in-Docker는 지원되지 않으며, 이를 호출하려는 시도가 이 오류의 원인일 가능성이 높습니다.

이 오류를 해결하려면 의존성 스캐닝에서 Docker-in-Docker를 비활성화합니다. CI/CD 파이프라인에서 실행되는 분석기마다 개별 <analyzer-name>-dependency_scanning job 이 생성됩니다.

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은 빌드 단계에서 캐시되어 스캔이 시작되기 전에 의존성 스캐닝 job으로 전달됩니다. 캐시는 분석기 실행 전에 다운로드되므로, CI_BUILDS_DIR 디렉터리에 lockfile 이 존재하면 의존성 스캐닝 job 이 트리거됩니다.

이 경고를 방지하려면 lockfile을 커밋해야 합니다.

DS_MAJOR_VERSION 또는 DS_ANALYZER_IMAGE 설정 후 최신 Docker 이미지를 받지 못하는 문제#

특정한 이유로 DS_MAJOR_VERSION 또는 DS_ANALYZER_IMAGE를 직접 설정했고, 이제 분석기의 최신 패치 버전을 다시 받도록 구성을 갱신해야 한다면 .gitlab-ci.yml 파일을 편집해 다음 중 하나를 수행합니다.

  • DS_MAJOR_VERSION을 의존성 스캐닝 템플릿에서 참조하는 버전과 맞춥니다.

  • DS_ANALYZER_IMAGE 변수를 직접 하드코딩했다면 의존성 스캐닝 템플릿의 최신 줄과 맞도록 변경합니다. 줄 번호는 편집한 스캐닝 job에 따라 달라집니다.

    예를 들어 gemnasium-maven-dependency_scanning job은 DS_ANALYZER_IMAGE가 "$SECURE_ANALYZERS_PREFIX/gemnasium-maven:$DS_MAJOR_VERSION"으로 설정되어 있으므로 최신 gemnasium-maven Docker 이미지를 가져옵니다.

setuptools 프로젝트 의존성 스캐닝이 use_2to3 is invalid 오류와 함께 실패하는 문제#

2to3 지원은 setuptools 버전 v58.0.0에서 제거되었습니다. 의존성 스캐닝은 python 3.9로 실행되며 2to3를 지원하지 않는 setuptools 버전 58.1.0+를 사용합니다. 따라서 lib2to3에 의존하는 setuptools 의존성은 다음 메시지와 함께 실패합니다.

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는 Debian 패키지 libpq-dev에 의존하지만, 이 패키지는 gemnasium-python Docker 이미지에 설치되어 있지 않습니다. 이 오류를 우회하려면 before_script에서 libpq-dev 패키지를 설치합니다.

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

CI_JOB_TOKEN과 함께 poetry config http-basic을 사용할 때 발생하는 NoSuchOptionException#

이 오류는 자동으로 생성된 CI_JOB_TOKEN 이 하이픈(-)으로 시작할 때 발생할 수 있습니다. 이 오류를 피하려면 Poetry의 구성 안내를 따릅니다.

오류: project has unresolved dependencies#

다음 오류 메시지는 build.gradle 또는 build.gradle.kts 파일로 인해 발생한 Gradle 의존성 해석 문제를 나타냅니다.

  • project has unresolved dependencies: ["dependency_name:version"]

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 파일의 GOOS 및 GOARCH 환경 변수를 설정해 배포 환경의 운영 체제와 아키텍처를 대상으로 빌드 과정을 구성할 수 있습니다.

예를 들면 다음과 같습니다.

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] ▶ Selecting "go.sum" parser for "/test-projects/gitlab-shell/go.sum". False positives may occur. See https://gitlab.com/gitlab-org/gitlab/-/issues/321081.

ssh 사용 시 발생하는 Host key verification failed#

gemnasium 이미지에 openssh-client를 설치한 뒤 ssh를 사용하면 Host key verification failed 메시지가 나타날 수 있습니다. 이미지를 빌드할 때 $HOME 이 /tmp로 설정되기 때문에, 설정 과정에서 사용자 디렉터리를 ~로 표기하면 이 현상이 발생할 수 있습니다. 이 문제는 Cloning project over SSH fails when using gemnasium-python image에 설명되어 있습니다. openssh-client는 /root/.ssh/known_hosts를 찾지만 이 경로는 존재하지 않고, 대신 /tmp/.ssh/known_hosts가 존재합니다.

openssh-client가 미리 설치된 gemnasium-python에서는 이 문제가 해결되었으나, 다른 이미지에 openssh-client를 새로 설치하면 발생할 수 있습니다. 해결 방법은 다음 두 가지입니다.

  1. 키와 호스트를 설정할 때 ~/.ssh/known_hosts 대신 절대 경로(/root/.ssh/known_hosts)를 사용합니다.
  2. ssh 구성에 해당 known_hosts 파일을 지정하는 UserKnownHostsFile을 추가합니다. 예: 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를 실행해 lockfile에 최신 패키지 해시가 들어 있는지 확인합니다.

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

이 오류는 requirements 파일이 GitLab Runner가 사용하는 플랫폼과 다른 플랫폼에서 생성된 경우에 발생합니다. 다른 플랫폼을 대상으로 하는 지원은 이슈 416376에서 추적하고 있습니다.

Editable 플래그로 인해 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 executor를 사용한다면 기본 Kubernetes 리소스 설정을 재정의해야 할 수 있습니다. 메모리 문제를 방지하기 위한 컨테이너 리소스 조정 방법은 Kubernetes executor 문서를 참고합니다.

NPM 프로젝트에 package-lock.json 파일이 없는 경우#

기본적으로 의존성 스캐닝 job은 리포지터리에 package-lock.json 파일이 있을 때만 실행됩니다. 그러나 일부 NPM 프로젝트는 package-lock.json 파일을 Git 리포지터리에 저장하지 않고 빌드 과정에서 생성합니다.

이러한 프로젝트의 의존성을 스캔하려면 다음과 같이 합니다.

  1. 빌드 job에서 package-lock.json 파일을 생성합니다.
  2. 생성된 파일을 아티팩트로 저장합니다.
  3. 의존성 스캐닝 job 이 그 아티팩트를 사용하도록 수정하고 규칙을 조정합니다.

예를 들어 구성은 다음과 같은 형태가 됩니다.

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

build:
  script:
    - npm i
  artifacts:
    paths:
      - package-lock.json  # Store the generated package-lock.json as an 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/"

파이프라인에 의존성 스캐닝 job 이 추가되지 않는 문제#

의존성 스캐닝 job은 규칙을 사용해 의존성이 담긴 lockfile 또는 빌드 도구 관련 파일이 있는지 확인합니다. 이런 파일이 하나도 감지되지 않으면, 파이프라인의 다른 job 이 lockfile을 생성하더라도 해당 job은 파이프라인에 추가되지 않습니다.

이런 상황이 발생하면 리포지터리에 지원되는 파일 또는 지원되는 파일이 런타임에 생성됨을 나타내는 파일이 있는지 확인합니다. 의존성 스캐닝 job을 트리거할 수 있도록 이런 파일을 리포지터리에 추가할 수 있는지 검토합니다.

리포지터리에 그런 파일이 있는데도 job 이 트리거되지 않는다면 다음 정보를 담아 이슈를 등록합니다.

  • 사용 중인 언어와 빌드 도구.
  • 제공하는 lockfile의 종류와 생성 위치.

의존성 스캐닝 템플릿에 직접 기여할 수도 있습니다.

의존성 스캐닝이 gradlew: permission denied와 함께 실패하는 문제#

gradlew의 permission denied 오류는 대개 실행 비트가 설정되지 않은 채 gradlew가 리포지터리에 커밋되었음을 의미합니다. job에 다음과 같은 메시지로 나타날 수 있습니다.

[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 리포지터리에 푸시합니다.

지원되지 않는 Gradle 버전으로 인해 의존성 스캐닝 nebula lock 생성이 실패하는 문제#

지원되지 않는 Gradle 버전(9.0 이상)으로 dependency.lockfiles을 생성하려고 하면 다음 오류가 발생합니다.

FAILURE: Build failed with an exception.
* Where:
Initialization script '/builds/gitlab-org/app/app/nebula.gradle' line: 11
* What went wrong:
Failed to notify build listener.
> org/gradle/util/NameMatcher

gradle 빌드를 Gradle 8.10.2로 낮춰 봅니다.

의존성 스캐닝 스캐너가 더 이상 Gemnasium 이 아닌 경우#

지금까지 의존성 스캐닝이 사용한 스캐너는 Gemnasium 이었고, 사용자는 취약점 페이지에서 이 값을 확인할 수 있었습니다.

SBOM을 사용한 의존성 스캐닝이 배포되면서 Gemnasium 스캐너는 내장 GitLab SBoM Vulnerability Scanner로 대체되었습니다. 이 새 스캐너는 CI/CD job 이 아니라 GitLab 플랫폼 안에서 실행됩니다. 두 스캐너는 동일한 결과를 제공할 것으로 예상되지만, SBOM 스캔이 기존 의존성 스캐닝 CI/CD job 이후에 일어나므로 기존 취약점의 스캐너 값은 새 GitLab SBoM Vulnerability Scanner로 갱신됩니다.

GitLab 내장 의존성 스캐닝 기능에서 예상되는 값은 GitLab SBoM Vulnerability Scanner 뿐입니다.

프로젝트 의존성 목록이 최신 SBOM 기준으로 업데이트되지 않는 문제#

SBOM을 생성할 job 이 파이프라인에서 실패하면 DeleteNotPresentOccurrencesService가 실행되지 않아 의존성 목록이 변경되거나 업데이트되지 않습니다. SBOM을 업로드하는 다른 job 이 성공하고 파이프라인 전체가 성공하더라도 이 현상이 발생할 수 있습니다. 이는 관련 보안 스캐닝 job 이 실패했을 때 의존성 목록에서 의존성이 실수로 제거되는 것을 막기 위한 설계입니다. 프로젝트 의존성 목록이 예상대로 업데이트되지 않는다면 파이프라인에서 실패한 SBOM 관련 job 이 있는지 확인하고, 해당 job을 수정하거나 제거합니다.

의존성 스캐닝이 open /etc/ssl/certs/ca-certificates.crt: permission denied와 함께 실패하는 문제#

이 오류는 대개 컨테이너를 실행하는 사용자가 root 그룹에 속하지 않았음을 나타냅니다. id를 실행해 사용자가 해당 그룹에 속해 있는지 확인합니다.

$ id
uid=1000(node) gid=0(root) groups=0(root),1000(node)

OpenShift를 실행 중이거나 Kubernetes executor를 사용한다면 러너가 그룹 ID(GID) 0으로 실행되도록 구성합니다.

[[runners]]
[runners.kubernetes]
    [runners.kubernetes.pod_security_context]
    run_as_non_root = true
    run_as_group = 0

사용자 지정 또는 병합된 CycloneDX SBOM에서 취약점 스캔 결과가 나오지 않는 문제#

의존성 스캐닝 CI/CD job은 성공하고 SBOM 컴포넌트도 의존성 목록에 나타나지만, 파이프라인 보안 탭에는 취약점이 보고되지 않습니다.

GitLab 18.10 이상에서는 보안 탭에 "SBOM report is missing required GitLab metadata properties needed for vulnerability scanning." 메시지가 표시됩니다.

이 문제는 SBOM에 필수 GitLab CycloneDX 속성이 없을 때 발생합니다. 이런 속성이 없으면 취약점 스캐너가 SBOM의 컴포넌트에 대한 결과를 구성할 수 없습니다. 의존성 목록은 여전히 채워지지만 취약점은 보고되지 않습니다.

이 현상은 주로 다음과 같은 경우에 발생합니다.

  • 여러 SBOM을 cyclonedx merge로 병합해 메타데이터 속성이 제거된 경우.
  • 서드파티 SBOM 생성기가 GitLab 고유 속성을 포함하지 않는 경우.
  • metadata.properties에 gitlab:meta:schema_version 속성(값은 1 이어야 합니다)이 없는 경우.

취약점 스캔에 필요한 속성#

속성 위치 설명
gitlab:meta:schema_version metadata.properties 반드시 1로 설정해야 합니다.
gitlab:dependency_scanning:input_file:path metadata.properties 또는 각 컴포넌트의 properties 의존성을 생성하기 위해 분석한 lockfile의 경로입니다. 둘 다 없으면 해당 컴포넌트에 대한 취약점 결과가 생성되지 않습니다. GitLab 18.10 이상에서는 파이프라인 보안 탭에 오류가 표시됩니다.

이 문제를 해결하려면 다음 방법 중 하나를 선택합니다.

  • 각 SBOM을 개별적으로 업로드합니다.

    병합하는 대신 각 SBOM을 별도의 artifacts: reports: cyclonedx: 항목으로 업로드합니다. 이렇게 하면 각 파일의 GitLab 고유 속성이 보존됩니다.

  • 서드파티 SBOM에 속성을 추가합니다.

    서드파티 도구가 생성한 SBOM은 대개 GitLab 고유 속성을 포함하지 않습니다. 취약점 스캔을 사용하려면 SBOM의 metadata.properties에 다음이 포함되어야 합니다.

    • gitlab:meta:schema_version을 1로 설정
    • gitlab:dependency_scanning:input_file:path를 lockfile의 리포지터리 기준 상대 경로로 설정(예: package-lock.json 또는 src/Gemfile.lock)

    SBOM에 여러 lockfile의 컴포넌트가 포함되어 있다면 각 컴포넌트가 올바른 소스 파일을 가리키도록 메타데이터가 아니라 각 컴포넌트의 properties 배열에 input_file:path를 설정합니다. 지원되는 속성의 전체 목록은 GitLab CycloneDX 속성 분류를 참고합니다.

자세한 내용은 이슈 542813과 머지 리퀘스트 221549를 참고합니다.

취약점 스캔이 모든 의존성에 잘못된 입력 파일을 표시하는 문제#

취약점 보고서나 의존성 목록의 모든 의존성이 서로 다른 lockfile에서 비롯되었는데도 동일한 입력 파일 경로를 표시합니다.

이 문제는 gitlab:dependency_scanning:input_file:path 속성이 컴포넌트별이 아니라 metadata.properties에 설정되었을 때 발생합니다. 속성 분류에 따르면 메타데이터 수준 속성은 문서의 모든 객체에 적용되므로, 단일 값이 모든 컴포넌트를 재정의합니다.

이 문제를 해결하려면 최상위 메타데이터가 아니라 각 컴포넌트의 properties 배열에 input_file:path를 개별적으로 설정합니다. input_file:path 속성은 서로 다른 lockfile의 컴포넌트를 포함하는 병합된 SBOM에서 특히 중요합니다.

오류: node with package name <package_name> does not exist#

이 문제는 패키지 관리자(대개 nuget)가 패키지를 찾지 못할 때 발생합니다. 애플리케이션을 빌드하는 데 사용한 이미지와 의존성 스캔을 실행하는 데 사용한 이미지가 달라서 발생할 수 있습니다.

이 문제를 해결하려면 의존성 스캐너가 애플리케이션을 빌드할 때 사용하는 것과 동일한 .NET SDK 이미지를 사용합니다. 다음을 실행하면 정확한 이미지를 확인할 수 있습니다.

curl --silent "https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/raw/master/build/gemnasium/alpine/Dockerfile" | grep "vrange-nuget-build" | grep "FROM"

위에 링크된 Dockerfile에서 현재 이미지 버전을 확인합니다.