InfoGrab DocsInfoGrab Docs

보안 스캐너 통합

요약

GitLab에 보안 스캐너를 통합하는 작업은 사용자에게 CI/CD job 정의를 제공하는 것으로 이루어집니다. 스캐닝 job은 일반적으로 스캐너와 모든 의존성을 독립적인 환경에 포함하는 Docker 이미지를 기반으로 합니다.

GitLab에 보안 스캐너를 통합하는 작업은 사용자에게 CI/CD job 정의를 제공하는 것으로 이루어집니다. 사용자는 이 정의를 CI/CD 구성 파일에 추가하여 GitLab 프로젝트를 스캔할 수 있습니다. 그런 다음 이 job은 GitLab에서 지정한 형식으로 결과를 출력해야 합니다. 이 결과는 파이프라인 보기, 머지 리퀘스트 위젯, 보안 대시보드 등 GitLab의 다양한 위치에 자동으로 표시됩니다.

스캐닝 job은 일반적으로 스캐너와 모든 의존성을 독립적인 환경에 포함하는 Docker 이미지를 기반으로 합니다.

이 페이지에서는 보안 스캐너를 구현하는 CI/CD job 작성에 대한 요구사항 및 지침과 Docker 이미지에 대한 요구사항 및 지침을 설명합니다.

Job 정의#

이 섹션에서는 보안 스캐너의 job 정의 파일에 추가해야 할 몇 가지 중요한 필드를 설명합니다. 이 필드와 사용 가능한 다른 필드에 대한 전체 문서는 CI/CD 문서에서 확인할 수 있습니다.

이름#

일관성을 위해 스캐닝 job의 이름은 스캐너 이름을 소문자로 사용해야 합니다. job 이름에는 스캐닝 유형이 접미사로 붙습니다:

  • _dependency_scanning

  • _container_scanning

  • _dast

  • _sast

예를 들어, "MySec" 스캐너를 기반으로 하는 종속성 스캐닝 job의 이름은 mysec_dependency_scanning이 됩니다.

이미지#

image 키워드는 보안 스캐너가 포함된 Docker 이미지를 지정하는 데 사용됩니다.

스크립트#

script 키워드는 스캐너를 실행할 명령어를 지정하는 데 사용됩니다. script 항목은 비워둘 수 없으므로, 스캔을 수행하는 명령어로 설정해야 합니다. 어떠한 명령어도 전달하지 않고 Docker 이미지의 미리 정의된 ENTRYPOINTCMD에 의존하여 스캔을 자동으로 수행하도록 하는 것은 불가능합니다.

before_script는 사용자가 스캔 수행 전에 프로젝트를 준비하는 데 활용할 수 있으므로 job 정의에서 사용하지 않아야 합니다. 예를 들어, 정적 애플리케이션 보안 테스트(SAST) 또는 종속성 스캐닝을 수행하기 전에 특정 프로젝트에 필요한 시스템 라이브러리를 설치하기 위해 before_script를 사용하는 것은 일반적인 관행입니다.

마찬가지로, after_script는 사용자가 재정의할 수 있으므로 job 정의에서 사용하지 않아야 합니다.

Stage#

일관성을 위해 스캐닝 job은 가능하면 test Stage에 속해야 합니다. test가 기본값이므로 stage 키워드는 생략할 수 있습니다.

장애 안전 장치#

기본적으로 스캐닝 job이 실패해도 파이프라인을 차단하지 않으므로 allow_failure 파라미터를 true로 설정해야 합니다.

아티팩트#

스캐닝 job은 artifacts:reports 키워드를 사용하여 수행하는 스캐닝 유형에 해당하는 리포트를 선언해야 합니다. 유효한 리포트 유형은 다음과 같습니다:

  • dependency_scanning

  • container_scanning

  • dast

  • api_fuzzing

  • coverage_fuzzing

  • sast

  • secret_detection

예를 들어, gl-sast-report.json이라는 파일을 생성하여 SAST 리포트로 업로드하는 SAST job의 정의는 다음과 같습니다:

mysec_sast:
  image: registry.gitlab.com/secure/mysec
  artifacts:
    reports:
      sast: gl-sast-report.json

gl-sast-report.json은 예시 파일 경로이며 다른 파일명도 사용할 수 있습니다. 자세한 내용은 출력 파일 섹션을 참조하세요. 파일명 때문이 아니라 job 정의의 reports:sast 키 아래에 선언되었기 때문에 SAST 리포트로 처리됩니다.

정책#

AutoDevOps와 같은 일부 GitLab 워크플로는 특정 스캔을 건너뛰어야 함을 나타내는 CI/CD 변수를 정의합니다. 다음과 같은 변수를 확인하여 이를 검사할 수 있습니다:

  • DEPENDENCY_SCANNING_DISABLED

  • CONTAINER_SCANNING_DISABLED

  • SAST_DISABLED

  • DAST_DISABLED

스캐너 유형에 따라 적절한 경우 커스텀 스캐너 실행을 건너뛰어야 합니다.

GitLab은 또한 리포지터리의 언어 목록을 제공하는 CI_PROJECT_REPOSITORY_LANGUAGES 변수를 정의합니다. 이 값에 따라 스캐너가 다르게 동작할 수 있습니다. 언어 감지는 현재 linguist Ruby gem에 의존합니다. 미리 정의된 CI/CD 변수를 참조하세요.

정책 확인 예시#

이 예시는 프로젝트 리포지터리에 Java 소스 코드가 포함되어 있고 dependency_scanning 기능이 활성화된 경우를 제외하고 커스텀 종속성 스캐닝 job인 mysec_dependency_scanning을 건너뛰는 방법을 보여줍니다:

mysec_dependency_scanning:
  rules:
    - if: $DEPENDENCY_SCANNING_DISABLED == 'true'
      when: never
    - if: $GITLAB_FEATURES =~ /\bdependency_scanning\b/
      exists:
        - '**/*.java'

추가적인 job 정책은 사용자의 필요에 따라서만 구성되어야 합니다. 예를 들어, 미리 정의된 정책이 특정 브랜치에 대해 또는 특정 파일 집합이 변경될 때 스캐닝 job을 트리거해서는 안 됩니다.

Docker 이미지#

Docker 이미지는 스캐너를 의존하는 모든 라이브러리 및 도구와 결합한 독립적인 환경입니다. 스캐너를 Docker 이미지로 패키징하면 스캐너가 실행되는 개별 머신에 관계없이 의존성과 구성이 항상 존재하도록 합니다.

이미지 크기#

CI/CD 인프라에 따라 CI/CD가 job이 실행될 때마다 Docker 이미지를 가져와야 할 수 있습니다. 스캐닝 job이 빠르게 실행되고 대역폭 낭비를 피하기 위해 Docker 이미지는 가능한 한 작아야 합니다. 50MB 이하를 목표로 해야 합니다. 그것이 불가능한 경우 DVD-ROM 크기인 1.46GB 미만으로 유지하세요.

스캐너에 완전한 Linux 환경이 필요한 경우 Debian "slim" 배포판이나 Alpine Linux를 사용하는 것이 권장됩니다. 가능하다면 FROM scratch 명령어를 사용하여 처음부터 이미지를 빌드하고 필요한 모든 라이브러리와 함께 스캐너를 컴파일하는 것이 권장됩니다. 멀티 스테이지 빌드도 이미지 크기를 작게 유지하는 데 도움이 될 수 있습니다.

이미지 크기를 작게 유지하려면 dive를 사용하여 Docker 이미지의 레이어를 분석하여 추가적인 비대화가 어디서 발생하는지 파악하는 것을 고려하세요.

경우에 따라 이미지에서 파일을 제거하기 어려울 수 있습니다. 이런 경우 Zstandard를 사용하여 파일이나 대용량 디렉터리를 압축하는 것을 고려하세요. Zstandard는 압축 해제 속도에 거의 영향 없이 이미지 크기를 줄일 수 있는 다양한 압축 레벨을 제공합니다. 이미지가 시작되는 즉시 압축된 디렉터리를 자동으로 압축 해제하는 것이 도움이 될 수 있습니다. Docker 이미지의 /etc/bashrc 또는 특정 사용자의 $HOME/.bashrc에 단계를 추가하여 이를 구현할 수 있습니다. 후자의 옵션을 선택한 경우 bash 로그인 셸을 실행하도록 진입점을 변경해야 합니다.

시작에 도움이 되는 몇 가지 예시:

이미지 태그#

Docker Official Images 프로젝트에 문서화된 것처럼, 버전 번호 태그에 별칭을 부여하여 사용자가 특정 시리즈의 "최신" 릴리스를 참조할 수 있도록 하는 것이 강력히 권장됩니다. Docker 태깅: Docker 이미지 태깅 및 버저닝 모범 사례도 참조하세요.

권한#

루트가 아닌 권한으로 Docker 컨테이너를 실행하려면 컨테이너에 다음 사용자와 그룹이 있어야 합니다:

  • 사용자 ID가 1000gitlab 사용자

  • 그룹 ID가 1000gitlab 그룹

커맨드라인#

스캐너는 환경 변수를 입력으로 받아 리포트로 업로드되는 파일을 생성하는 커맨드라인 도구입니다(job 정의 기반). 또한 표준 출력과 표준 오류 스트림에 텍스트 출력을 생성하고 상태 코드와 함께 종료합니다.

변수#

모든 CI/CD 변수는 환경 변수로 스캐너에 전달됩니다. 스캔할 프로젝트는 미리 정의된 CI/CD 변수로 설명됩니다.

SAST 및 종속성 스캐닝#

SAST 및 종속성 스캐닝 스캐너는 CI_PROJECT_DIR CI/CD 변수로 지정된 프로젝트 디렉터리의 파일을 스캔해야 합니다.

컨테이너 스캐닝#

GitLab의 공식 컨테이너 스캐닝과 일관성을 유지하기 위해 스캐너는 CI_APPLICATION_REPOSITORYCI_APPLICATION_TAG로 지정된 이름과 태그의 Docker 이미지를 스캔해야 합니다. DOCKER_IMAGE CI/CD 변수가 제공되면 CI_APPLICATION_REPOSITORYCI_APPLICATION_TAG 변수는 무시되고 DOCKER_IMAGE 변수에 지정된 이미지가 대신 스캔됩니다.

CI_APPLICATION_REPOSITORY가 제공되지 않으면 미리 정의된 CI/CD 변수의 조합인 $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG로 기본값이 설정됩니다. CI_APPLICATION_TAGCI_COMMIT_SHA로 기본값이 설정됩니다.

스캐너는 DOCKER_USERDOCKER_PASSWORD 변수를 사용하여 Docker 레지스트리에 로그인해야 합니다. 이것들이 정의되지 않은 경우 스캐너는 CI_REGISTRY_USERCI_REGISTRY_PASSWORD를 기본값으로 사용해야 합니다.

구성 파일#

스캐너가 특정 구성 파일을 로드하기 위해 CI_PROJECT_DIR를 사용할 수 있지만, 구성을 파일이 아닌 CI/CD 변수로 노출하는 것이 권장됩니다.

출력 파일#

GitLab CI/CD에 업로드된 모든 아티팩트와 마찬가지로, 스캐너가 생성한 보안 리포트는 CI_PROJECT_DIR CI/CD 변수로 지정된 프로젝트 디렉터리에 작성되어야 합니다.

출력 파일의 이름은 스캐닝 유형을 따르고 gl- 접두사를 사용하는 것이 권장됩니다. 모든 보안 리포트는 JSON 파일이므로 .json 파일 확장자를 사용해야 합니다. 예를 들어, 종속성 스캐닝 리포트의 권장 파일명은 gl-dependency-scanning.json입니다.

job 정의의 artifacts:reports 키워드는 보안 리포트가 작성되는 파일 경로와 일치해야 합니다. 예를 들어, 종속성 스캐닝 분석기가 CI/CD 프로젝트 디렉터리에 리포트를 작성하고 이 리포트 파일명이 depscan.json인 경우, artifacts:reports:dependency_scanningdepscan.json으로 설정해야 합니다.

종료 코드#

POSIX 종료 코드 표준에 따라 스캐너는 성공 시 0, 실패 시 1로 종료합니다. 취약점이 발견된 경우도 성공에 포함됩니다.

CI/CD job이 실패하면 job이 실패를 허용하더라도 GitLab이 보안 리포트 결과를 수집하지 않습니다. 그러나 리포트 아티팩트는 GitLab에 여전히 업로드되며 파이프라인 보안 탭에서 다운로드할 수 있습니다.

로깅#

스캐너는 오류 메시지와 경고를 로깅하여 사용자가 CI/CD 스캐닝 job의 로그를 확인하여 잘못된 구성 및 통합 문제를 조사할 수 있도록 해야 합니다.

스캐너는 ANSI 이스케이프 코드를 사용하여 Unix 표준 출력 및 표준 오류 스트림에 작성하는 메시지에 색상을 적용할 수 있습니다. 오류에는 빨간색, 경고에는 노란색, 알림에는 녹색을 사용하는 것이 권장됩니다. 또한 오류 메시지에는 [ERRO], 경고에는 [WARN], 알림에는 [INFO]를 접두사로 붙이는 것이 권장됩니다.

로깅 레벨#

스캐너는 SECURE_LOG_LEVEL CI/CD 변수에 설정된 로그 레벨보다 낮은 레벨의 로그 메시지를 필터링해야 합니다. 예를 들어, SECURE_LOG_LEVELerror로 설정되어 있으면 infowarn 메시지는 건너뛰어야 합니다. 허용되는 값은 다음과 같으며 가장 높은 것부터 가장 낮은 순으로 나열됩니다:

  • fatal

  • error

  • warn

  • info

  • debug

디버깅에 유용할 수 있는 상세한 로깅에는 debug 레벨을 사용하는 것이 권장됩니다. SECURE_LOG_LEVEL의 기본값은 info로 설정해야 합니다.

명령줄을 실행할 때 스캐너는 명령줄과 출력을 기록하기 위해 debug 레벨을 사용해야 합니다. 명령줄이 실패하면 error 로그 레벨로 기록해야 합니다. 이렇게 하면 로그 레벨을 debug로 변경하고 스캐닝 job을 다시 실행하지 않고도 문제를 디버깅할 수 있습니다.

common logutil 패키지#

gocommon을 사용하는 경우, Logruscommon의 logutil 패키지를 사용하여 Logrus의 포매터를 구성하는 것이 권장됩니다. logutil README를 참조하세요.

리포트#

리포트는 취약점과 가능한 수정 방법을 결합한 JSON 문서입니다.

이 문서는 리포트 JSON 형식, 권장사항, 통합 담당자가 필드를 설정하는 데 도움이 되는 예시를 개요로 제공합니다. 형식은 SAST, DAST, 종속성 스캐닝, 컨테이너 스캐닝 문서에서 광범위하게 설명됩니다.

이 스캐너들의 스키마는 다음에서 확인할 수 있습니다:

리포트 검증#

스캐너가 생성한 리포트가 리포트에 선언된 스키마 버전에 대한 검증을 통과하는지 확인해야 합니다. 검증을 통과하지 못한 리포트는 GitLab이 수집하지 않으며 해당 파이프라인에 오류 메시지가 표시됩니다.

더 이상 사용되지 않는 버전의 보안 리포트 스키마를 사용하는 리포트는 수집되지만 해당 파이프라인에 경고 메시지가 표시됩니다. 이 경고가 표시되면 분석기를 업데이트하여 최신 스키마를 사용하세요.

스키마 버전의 지원 중단 기간이 끝나면 해당 파일이 GitLab에서 제거됩니다. 제거된 버전을 선언하는 리포트는 거부되고 해당 파이프라인에 오류 메시지가 표시됩니다.

리포트가 공급된 스키마 버전과 일치하지 않는 PATCH 버전을 사용하는 경우 최신 공급된 PATCH 버전에 대해 검증됩니다. 예를 들어, 리포트 버전이 15.0.23이고 최신 공급 버전이 15.0.6이면 리포트는 버전 15.0.6에 대해 검증됩니다.

GitLab은 gitlab-security_report_schemas gem에서 읽은 보안 리포트 JSON 스키마에 대해 리포트를 검증합니다. 예를 들어, GitLab 15.4는 버전 0.1.2.min15.0.0.max15.2.0을 사용하는데, 이는 15.0.015.2.0 범위의 버전을 지원함을 의미합니다. GitLab 버전에서 지원되는 스키마 버전은 GitLab 설치의 gem 버전을 확인하여 알 수 있습니다.

정확한 버전을 보려면 로컬 검증 섹션을 참조하세요.

로컬 검증#

GitLab에서 분석기를 실행하기 전에 분석기가 생성한 리포트가 선언된 스키마 버전을 준수하는지 확인하기 위해 리포트를 검증해야 합니다.

  • gitlab-security_report_schemas를 설치합니다.

  • security-report-schemas를 실행하여 지원되는 스키마 버전을 확인합니다.

  • security-report-schemas <report.json>을 실행하여 리포트를 검증합니다.

$ gem install gitlab-security_report_schemas -v 0.1.2.min15.0.0.max15.2.1
Successfully installed gitlab-security_report_schemas-0.1.2.min15.0.0.max15.2.1
Parsing documentation for gitlab-security_report_schemas-0.1.2.min15.0.0.max15.2.1
Done installing documentation for gitlab-security_report_schemas after 0 seconds
1 gem installed

$ security-report-schemas
SecurityReportSchemas 0.1.2.min15.0.0.max15.2.1.
Supported schema versions: ["15.0.0", "15.0.1", "15.0.2", "15.0.4", "15.0.5", "15.0.6", "15.0.7", "15.1.0", "15.1.1", "15.1.2", "15.1.3", "15.1.4", "15.2.0", "15.2.1"]

Usage: security-report-schemas REPORT_FILE_PATH [options]
    -r, --report_type=REPORT_TYPE    Override the report type
    -w, --warnings                   Prints the warning messages

$ security-report-schemas ~/Downloads/gl-dependency-scanning-report.json
Validating dependency_scanning v15.0.0 against schema v15.0.0
Content is invalid
* root is missing required keys: dependency_files

리포트 필드#

버전#

이 필드는 사용 중인 보안 리포트 스키마 버전을 지정합니다. 사용할 버전에 대한 정보는 릴리스를 참조하세요.

GitLab은 이 값으로 지정된 스키마 버전에 대해 리포트를 검증합니다.

취약점#

리포트의 vulnerabilities 필드는 취약점 객체의 배열입니다.

ID#

id 필드는 취약점의 고유 식별자입니다. 수정 객체에서 수정된 취약점을 참조하는 데 사용됩니다. UUID를 생성하여 id 필드의 값으로 사용하는 것이 권장됩니다.

카테고리#

category 필드의 값은 리포트 유형과 일치합니다:

  • dependency_scanning

  • container_scanning

  • sast

  • dast

스캔#

scan 필드는 스캔 자체에 대한 메타 정보를 포함하는 객체입니다: 스캔을 수행한 analyzerscanner, 스캔이 실행된 start_timeend_time, 스캔의 status(성공 또는 실패).

analyzerscanner 필드 모두 사람이 읽을 수 있는 name과 기술적인 id를 포함하는 객체입니다. id는 다른 통합 담당자가 제공하는 다른 분석기 또는 스캐너와 충돌하지 않아야 합니다.

스캔 기본 식별자#

scan.primary_identifiers 필드는 기본 식별자의 배열을 포함하는 선택적 필드입니다. 분석기가 스캔을 수행한 모든 규칙 세트의 완전한 목록입니다.

특정 스캔의 취약점 배열이 비어 있는 경우에도 이 선택적 필드는 어떤 규칙이 실행되었는지 Rails 애플리케이션에 알리기 위해 잠재적 식별자의 완전한 목록을 포함해야 합니다.

이 필드가 채워지면 Rails 애플리케이션은 기본 식별자가 포함되지 않은 경우 이전에 탐지된 취약점을 자동으로 더 이상 관련 없음으로 해결할 수 있습니다.

이름, 메시지, 설명#

namemessage 필드는 취약점에 대한 짧은 설명을 포함합니다. description 필드는 더 자세한 내용을 제공합니다.

name 필드는 컨텍스트에 독립적이며 취약점이 발견된 위치에 대한 정보를 포함하지 않지만 message는 위치를 반복할 수 있습니다.

시각적 예시로, 이 스크린샷은 파이프라인 보기의 일부로 취약점을 볼 때 이 필드들이 사용되는 위치를 강조합니다.

[

](/19.1/development/integrations/img/example_vuln_v13_0.png)

예를 들어, 종속성 스캐닝이 보고한 취약점의 message는 취약한 의존성에 대한 정보를 제공하는데, 이는 취약점의 location 필드와 중복됩니다. name 필드가 선호되지만 컨텍스트/위치를 취약점 제목에서 제거할 수 없는 경우 message 필드가 사용됩니다.

예시로, 다음은 종속성 스캐닝 스캐너가 보고한 취약점 객체이며 messagelocation 필드를 반복합니다:

{
    "location": {
        "dependency": {
            "package": {
            "name": "debug"
          }
        }
    },
    "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."
}

description은 취약점의 작동 방식을 설명하거나 익스플로잇에 대한 컨텍스트를 제공할 수 있습니다. 취약점 객체의 다른 필드를 반복해서는 안 됩니다. 특히 descriptionlocation(영향을 받는 항목)이나 solution(위험 완화 방법)을 반복해서는 안 됩니다.

해결 방법#

solution 필드를 사용하여 사용자에게 식별된 취약점을 수정하거나 위험을 완화하는 방법을 안내할 수 있습니다. 최종 사용자가 이 필드와 상호작용하는 반면, GitLab은 remediations 객체를 자동으로 처리합니다.

식별자#

identifiers 배열은 탐지된 취약점을 설명합니다. 식별자 객체의 typevalue 필드는 두 식별자가 동일한지 여부를 판단하는 데 사용됩니다. 사용자 인터페이스는 객체의 nameurl 필드를 사용하여 식별자를 표시합니다.

identifiers 배열의 첫 번째 항목을 기본 식별자라고 하며, 리포지터리에 새 커밋이 푸시될 때 취약점을 추적하는 데 사용됩니다.

GitLab 스캐너가 이미 정의한 식별자를 사용하는 것이 권장됩니다:

식별자 유형 예시 값 예시 이름
CVE cve CVE-2019-10086 CVE-2019-10086
CWE cwe 1026 CWE-1026
ELSA elsa ELSA-2020-0085 ELSA-2020-0085
OSVD osvdb OSVDB-113928 OSVDB-113928
OWASP owasp A01:2021 A01:2021 - Broken Access Control
RHSA rhsa RHSA-2020:0111 RHSA-2020:0111
USN usn USN-4234-1 USN-4234-1
GHSA ghsa GHSA-38jh-8h67-m7mj GHSA-38jh-8h67-m7mj
HACKERONE hackerone 698789 HACKERONE-698789

위에 나열된 일반 식별자는 GitLab이 유지 관리하는 일부 분석기에서 공유하는 공통 라이브러리에 정의되어 있습니다. 필요한 경우 새 일반 식별자를 기여할 수 있습니다. 분석기는 공통 라이브러리에 속하지 않는 벤더별 또는 제품별 식별자를 생성할 수도 있습니다.

모든 취약점에 CVE가 있는 것은 아니며, CVE는 여러 번 식별될 수 있습니다. 따라서 CVE는 안정적인 식별자가 아니므로 취약점 추적 시 그렇게 가정해서는 안 됩니다.

취약점의 최대 식별자 수는 20개로 설정되어 있습니다. 취약점의 식별자가 20개를 초과하면 시스템은 처음 20개만 저장합니다. 파이프라인 보안 탭의 취약점은 이 제한을 적용하지 않으며 리포트 아티팩트에 있는 모든 식별자가 표시됩니다.

세부 정보#

details 필드는 취약점 정보를 볼 때 표시되는 다양한 콘텐츠 요소를 지원하는 객체입니다. 다양한 데이터 요소의 예시는 security-reports 리포지터리에서 확인할 수 있습니다.

위치#

location은 취약점이 탐지된 위치를 나타냅니다. 위치의 형식은 스캐닝 유형에 따라 다릅니다.

GitLab은 내부적으로 location의 일부 속성을 추출하여 위치 지문을 생성합니다. 이 지문은 리포지터리에 새 커밋이 푸시될 때 취약점을 추적하는 데 사용됩니다. 위치 지문을 생성하는 데 사용되는 속성도 스캐닝 유형에 따라 다릅니다.

종속성 스캐닝#

종속성 스캐닝 취약점의 locationdependencyfile로 구성됩니다. dependency 객체는 영향을 받는 package와 의존성 version을 설명합니다. package는 영향을 받는 라이브러리/모듈의 name을 포함합니다. file은 영향을 받는 의존성을 선언하는 의존성 파일의 경로입니다.

예를 들어, npm 패키지 handlebars의 버전 4.0.11에 영향을 주는 취약점의 location 객체는 다음과 같습니다:

{
    "file": "client/package.json",
    "dependency": {
        "package": {
            "name": "handlebars"
        },
        "version": "4.0.11"
    }
}

이 영향을 받는 의존성은 npm 또는 yarn이 처리하는 의존성 파일인 client/package.json에 나열됩니다.

종속성 스캐닝 취약점의 위치 지문은 file과 패키지 name을 결합하므로 이 속성들은 필수입니다. 다른 모든 속성은 선택 사항입니다.

컨테이너 스캐닝#

종속성 스캐닝과 마찬가지로 컨테이너 스캐닝 취약점의 location에는 dependencyfile이 있습니다. 또한 operating_system 필드도 있습니다.

예를 들어, Debian 패키지 glib2.0의 버전 2.50.3-2+deb9u1에 영향을 주는 취약점의 location 객체는 다음과 같습니다:

{
    "dependency": {
        "package": {
            "name": "glib2.0"
        },
    },
    "version": "2.50.3-2+deb9u1",
    "operating_system": "debian:9",
    "image": "registry.gitlab.com/example/app:latest"
}

영향을 받는 패키지는 Docker 이미지 registry.gitlab.com/example/app:latest를 스캔할 때 발견됩니다. Docker 이미지는 debian:9(Debian Stretch)를 기반으로 합니다.

컨테이너 스캐닝 취약점의 위치 지문은 operating_system과 패키지 name을 결합하므로 이 속성들은 필수입니다. image도 필수입니다. 다른 모든 속성은 선택 사항입니다.

SAST#

SAST 취약점의 location에는 영향을 받는 파일의 경로를 제공하는 file과 영향을 받는 줄 번호가 있는 start_line 필드가 있어야 합니다. 또한 end_line, class, method도 가질 수 있습니다.

예를 들어, com.gitlab.security_products.tests.App Java 클래스의 generateSecretToken 메서드에서 src/main/java/com/gitlab/example/App.java41번째 줄에서 발견된 보안 결함의 location 객체는 다음과 같습니다:

{
    "file": "src/main/java/com/gitlab/example/App.java",
    "start_line": 41,
    "end_line": 41,
    "class": "com.gitlab.security_products.tests.App",
    "method": "generateSecretToken1"
}

SAST 취약점의 위치 지문은 file, start_line, end_line을 결합하므로 이 속성들은 필수입니다. 다른 모든 속성은 선택 사항입니다.

취약점 추적#

줄 번호만으로 취약점을 추적하면 문제가 발생합니다. 코드가 변경될 때 동일한 취약점이 중복될 수 있습니다. GitLab은 다른 접근 방식을 사용하여 이 중복을 최소화합니다. 각 취약점을 범위 및 오프셋 서명으로 추적합니다. 이 서명은 분석기 리포트에 범위 정보를 추가하는 후처리기인 추적 계산기에서 가져옵니다.

영향을 받는 파일의 이름이 변경되거나 관련 코드가 다른 파일로 이동되면 취약점 추적이 적용되지 않습니다.

취약점의 서명은 다음 속성의 해시로 계산된 UUIDv5 다이제스트를 사용하여 계산됩니다:

중복 제거 프로세스도 참조하세요.

심각도#

severity 필드는 취약점이 소프트웨어에 얼마나 큰 영향을 주는지 설명합니다. 심각도는 보안 대시보드에서 취약점을 정렬하는 데 사용됩니다.

심각도는 Info에서 Critical까지 범위가 있으며 Unknown도 될 수 있습니다. 유효한 값은 Unknown, Info, Low, Medium, High, Critical입니다.

Unknown 값은 실제 값을 결정하기 위한 데이터가 없음을 의미합니다. 따라서 high, medium, low일 수 있으며 조사가 필요합니다.

수정 사항#

리포트의 remediations 필드는 수정 객체의 배열입니다. 각 수정 사항은 취약점 집합을 해결하기 위해 적용할 수 있는 패치를 설명합니다.

다음은 수정 사항이 포함된 리포트의 예시입니다.

{
    "vulnerabilities": [
        {
            "category": "dependency_scanning",
            "name": "Regular Expression Denial of Service",
            "id": "123e4567-e89b-12d3-a456-426655440000",
            "solution": "Upgrade to new versions.",
            "scanner": {
                "id": "gemnasium",
                "name": "Gemnasium"
            },
            "identifiers": [
                {
                  "type": "gemnasium",
                  "name": "Gemnasium-642735a5-1425-428d-8d4e-3c854885a3c9",
                  "value": "642735a5-1425-428d-8d4e-3c854885a3c9"
                }
            ]
        }
    ],
    "remediations": [
        {
            "fixes": [
                {
                    "id": "123e4567-e89b-12d3-a456-426655440000"
                }
            ],
            "summary": "Upgrade to new version",
            "diff": "ZGlmZiAtLWdpdCBhL3lhcm4ubG9jayBiL3lhcm4ubG9jawppbmRleCAwZWNjOTJmLi43ZmE0NTU0IDEwMDY0NAotLS0gYS95Y=="
        }
    ]
}
요약#

summary 필드는 취약점을 수정할 수 있는 방법에 대한 개요입니다. 이 필드는 필수입니다.

수정된 취약점#

fixes 필드는 수정 사항으로 수정된 취약점을 참조하는 객체의 배열입니다. fixes[].id에는 수정된 취약점의 고유 식별자가 포함됩니다. 이 필드는 필수입니다.

Diff#

diff 필드는 git apply와 호환되는 base64 인코딩된 수정 코드 diff입니다. 이 필드는 필수입니다.

보안 스캐너 통합

GitLab v19.1
원문 보기
요약

GitLab에 보안 스캐너를 통합하는 작업은 사용자에게 CI/CD job 정의를 제공하는 것으로 이루어집니다. 스캐닝 job은 일반적으로 스캐너와 모든 의존성을 독립적인 환경에 포함하는 Docker 이미지를 기반으로 합니다.

GitLab에 보안 스캐너를 통합하는 작업은 사용자에게 CI/CD job 정의를 제공하는 것으로 이루어집니다. 사용자는 이 정의를 CI/CD 구성 파일에 추가하여 GitLab 프로젝트를 스캔할 수 있습니다. 그런 다음 이 job은 GitLab에서 지정한 형식으로 결과를 출력해야 합니다. 이 결과는 파이프라인 보기, 머지 리퀘스트 위젯, 보안 대시보드 등 GitLab의 다양한 위치에 자동으로 표시됩니다.

스캐닝 job은 일반적으로 스캐너와 모든 의존성을 독립적인 환경에 포함하는 Docker 이미지를 기반으로 합니다.

이 페이지에서는 보안 스캐너를 구현하는 CI/CD job 작성에 대한 요구사항 및 지침과 Docker 이미지에 대한 요구사항 및 지침을 설명합니다.

Job 정의#

이 섹션에서는 보안 스캐너의 job 정의 파일에 추가해야 할 몇 가지 중요한 필드를 설명합니다. 이 필드와 사용 가능한 다른 필드에 대한 전체 문서는 CI/CD 문서에서 확인할 수 있습니다.

이름#

일관성을 위해 스캐닝 job의 이름은 스캐너 이름을 소문자로 사용해야 합니다. job 이름에는 스캐닝 유형이 접미사로 붙습니다:

  • _dependency_scanning

  • _container_scanning

  • _dast

  • _sast

예를 들어, "MySec" 스캐너를 기반으로 하는 종속성 스캐닝 job의 이름은 mysec_dependency_scanning이 됩니다.

이미지#

image 키워드는 보안 스캐너가 포함된 Docker 이미지를 지정하는 데 사용됩니다.

스크립트#

script 키워드는 스캐너를 실행할 명령어를 지정하는 데 사용됩니다. script 항목은 비워둘 수 없으므로, 스캔을 수행하는 명령어로 설정해야 합니다. 어떠한 명령어도 전달하지 않고 Docker 이미지의 미리 정의된 ENTRYPOINTCMD에 의존하여 스캔을 자동으로 수행하도록 하는 것은 불가능합니다.

before_script는 사용자가 스캔 수행 전에 프로젝트를 준비하는 데 활용할 수 있으므로 job 정의에서 사용하지 않아야 합니다. 예를 들어, 정적 애플리케이션 보안 테스트(SAST) 또는 종속성 스캐닝을 수행하기 전에 특정 프로젝트에 필요한 시스템 라이브러리를 설치하기 위해 before_script를 사용하는 것은 일반적인 관행입니다.

마찬가지로, after_script는 사용자가 재정의할 수 있으므로 job 정의에서 사용하지 않아야 합니다.

Stage#

일관성을 위해 스캐닝 job은 가능하면 test Stage에 속해야 합니다. test가 기본값이므로 stage 키워드는 생략할 수 있습니다.

장애 안전 장치#

기본적으로 스캐닝 job이 실패해도 파이프라인을 차단하지 않으므로 allow_failure 파라미터를 true로 설정해야 합니다.

아티팩트#

스캐닝 job은 artifacts:reports 키워드를 사용하여 수행하는 스캐닝 유형에 해당하는 리포트를 선언해야 합니다. 유효한 리포트 유형은 다음과 같습니다:

  • dependency_scanning

  • container_scanning

  • dast

  • api_fuzzing

  • coverage_fuzzing

  • sast

  • secret_detection

예를 들어, gl-sast-report.json이라는 파일을 생성하여 SAST 리포트로 업로드하는 SAST job의 정의는 다음과 같습니다:

mysec_sast:
  image: registry.gitlab.com/secure/mysec
  artifacts:
    reports:
      sast: gl-sast-report.json

gl-sast-report.json은 예시 파일 경로이며 다른 파일명도 사용할 수 있습니다. 자세한 내용은 출력 파일 섹션을 참조하세요. 파일명 때문이 아니라 job 정의의 reports:sast 키 아래에 선언되었기 때문에 SAST 리포트로 처리됩니다.

정책#

AutoDevOps와 같은 일부 GitLab 워크플로는 특정 스캔을 건너뛰어야 함을 나타내는 CI/CD 변수를 정의합니다. 다음과 같은 변수를 확인하여 이를 검사할 수 있습니다:

  • DEPENDENCY_SCANNING_DISABLED

  • CONTAINER_SCANNING_DISABLED

  • SAST_DISABLED

  • DAST_DISABLED

스캐너 유형에 따라 적절한 경우 커스텀 스캐너 실행을 건너뛰어야 합니다.

GitLab은 또한 리포지터리의 언어 목록을 제공하는 CI_PROJECT_REPOSITORY_LANGUAGES 변수를 정의합니다. 이 값에 따라 스캐너가 다르게 동작할 수 있습니다. 언어 감지는 현재 linguist Ruby gem에 의존합니다. 미리 정의된 CI/CD 변수를 참조하세요.

정책 확인 예시#

이 예시는 프로젝트 리포지터리에 Java 소스 코드가 포함되어 있고 dependency_scanning 기능이 활성화된 경우를 제외하고 커스텀 종속성 스캐닝 job인 mysec_dependency_scanning을 건너뛰는 방법을 보여줍니다:

mysec_dependency_scanning:
  rules:
    - if: $DEPENDENCY_SCANNING_DISABLED == 'true'
      when: never
    - if: $GITLAB_FEATURES =~ /\bdependency_scanning\b/
      exists:
        - '**/*.java'

추가적인 job 정책은 사용자의 필요에 따라서만 구성되어야 합니다. 예를 들어, 미리 정의된 정책이 특정 브랜치에 대해 또는 특정 파일 집합이 변경될 때 스캐닝 job을 트리거해서는 안 됩니다.

Docker 이미지#

Docker 이미지는 스캐너를 의존하는 모든 라이브러리 및 도구와 결합한 독립적인 환경입니다. 스캐너를 Docker 이미지로 패키징하면 스캐너가 실행되는 개별 머신에 관계없이 의존성과 구성이 항상 존재하도록 합니다.

이미지 크기#

CI/CD 인프라에 따라 CI/CD가 job이 실행될 때마다 Docker 이미지를 가져와야 할 수 있습니다. 스캐닝 job이 빠르게 실행되고 대역폭 낭비를 피하기 위해 Docker 이미지는 가능한 한 작아야 합니다. 50MB 이하를 목표로 해야 합니다. 그것이 불가능한 경우 DVD-ROM 크기인 1.46GB 미만으로 유지하세요.

스캐너에 완전한 Linux 환경이 필요한 경우 Debian "slim" 배포판이나 Alpine Linux를 사용하는 것이 권장됩니다. 가능하다면 FROM scratch 명령어를 사용하여 처음부터 이미지를 빌드하고 필요한 모든 라이브러리와 함께 스캐너를 컴파일하는 것이 권장됩니다. 멀티 스테이지 빌드도 이미지 크기를 작게 유지하는 데 도움이 될 수 있습니다.

이미지 크기를 작게 유지하려면 dive를 사용하여 Docker 이미지의 레이어를 분석하여 추가적인 비대화가 어디서 발생하는지 파악하는 것을 고려하세요.

경우에 따라 이미지에서 파일을 제거하기 어려울 수 있습니다. 이런 경우 Zstandard를 사용하여 파일이나 대용량 디렉터리를 압축하는 것을 고려하세요. Zstandard는 압축 해제 속도에 거의 영향 없이 이미지 크기를 줄일 수 있는 다양한 압축 레벨을 제공합니다. 이미지가 시작되는 즉시 압축된 디렉터리를 자동으로 압축 해제하는 것이 도움이 될 수 있습니다. Docker 이미지의 /etc/bashrc 또는 특정 사용자의 $HOME/.bashrc에 단계를 추가하여 이를 구현할 수 있습니다. 후자의 옵션을 선택한 경우 bash 로그인 셸을 실행하도록 진입점을 변경해야 합니다.

시작에 도움이 되는 몇 가지 예시:

이미지 태그#

Docker Official Images 프로젝트에 문서화된 것처럼, 버전 번호 태그에 별칭을 부여하여 사용자가 특정 시리즈의 "최신" 릴리스를 참조할 수 있도록 하는 것이 강력히 권장됩니다. Docker 태깅: Docker 이미지 태깅 및 버저닝 모범 사례도 참조하세요.

권한#

루트가 아닌 권한으로 Docker 컨테이너를 실행하려면 컨테이너에 다음 사용자와 그룹이 있어야 합니다:

  • 사용자 ID가 1000gitlab 사용자

  • 그룹 ID가 1000gitlab 그룹

커맨드라인#

스캐너는 환경 변수를 입력으로 받아 리포트로 업로드되는 파일을 생성하는 커맨드라인 도구입니다(job 정의 기반). 또한 표준 출력과 표준 오류 스트림에 텍스트 출력을 생성하고 상태 코드와 함께 종료합니다.

변수#

모든 CI/CD 변수는 환경 변수로 스캐너에 전달됩니다. 스캔할 프로젝트는 미리 정의된 CI/CD 변수로 설명됩니다.

SAST 및 종속성 스캐닝#

SAST 및 종속성 스캐닝 스캐너는 CI_PROJECT_DIR CI/CD 변수로 지정된 프로젝트 디렉터리의 파일을 스캔해야 합니다.

컨테이너 스캐닝#

GitLab의 공식 컨테이너 스캐닝과 일관성을 유지하기 위해 스캐너는 CI_APPLICATION_REPOSITORYCI_APPLICATION_TAG로 지정된 이름과 태그의 Docker 이미지를 스캔해야 합니다. DOCKER_IMAGE CI/CD 변수가 제공되면 CI_APPLICATION_REPOSITORYCI_APPLICATION_TAG 변수는 무시되고 DOCKER_IMAGE 변수에 지정된 이미지가 대신 스캔됩니다.

CI_APPLICATION_REPOSITORY가 제공되지 않으면 미리 정의된 CI/CD 변수의 조합인 $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG로 기본값이 설정됩니다. CI_APPLICATION_TAGCI_COMMIT_SHA로 기본값이 설정됩니다.

스캐너는 DOCKER_USERDOCKER_PASSWORD 변수를 사용하여 Docker 레지스트리에 로그인해야 합니다. 이것들이 정의되지 않은 경우 스캐너는 CI_REGISTRY_USERCI_REGISTRY_PASSWORD를 기본값으로 사용해야 합니다.

구성 파일#

스캐너가 특정 구성 파일을 로드하기 위해 CI_PROJECT_DIR를 사용할 수 있지만, 구성을 파일이 아닌 CI/CD 변수로 노출하는 것이 권장됩니다.

출력 파일#

GitLab CI/CD에 업로드된 모든 아티팩트와 마찬가지로, 스캐너가 생성한 보안 리포트는 CI_PROJECT_DIR CI/CD 변수로 지정된 프로젝트 디렉터리에 작성되어야 합니다.

출력 파일의 이름은 스캐닝 유형을 따르고 gl- 접두사를 사용하는 것이 권장됩니다. 모든 보안 리포트는 JSON 파일이므로 .json 파일 확장자를 사용해야 합니다. 예를 들어, 종속성 스캐닝 리포트의 권장 파일명은 gl-dependency-scanning.json입니다.

job 정의의 artifacts:reports 키워드는 보안 리포트가 작성되는 파일 경로와 일치해야 합니다. 예를 들어, 종속성 스캐닝 분석기가 CI/CD 프로젝트 디렉터리에 리포트를 작성하고 이 리포트 파일명이 depscan.json인 경우, artifacts:reports:dependency_scanningdepscan.json으로 설정해야 합니다.

종료 코드#

POSIX 종료 코드 표준에 따라 스캐너는 성공 시 0, 실패 시 1로 종료합니다. 취약점이 발견된 경우도 성공에 포함됩니다.

CI/CD job이 실패하면 job이 실패를 허용하더라도 GitLab이 보안 리포트 결과를 수집하지 않습니다. 그러나 리포트 아티팩트는 GitLab에 여전히 업로드되며 파이프라인 보안 탭에서 다운로드할 수 있습니다.

로깅#

스캐너는 오류 메시지와 경고를 로깅하여 사용자가 CI/CD 스캐닝 job의 로그를 확인하여 잘못된 구성 및 통합 문제를 조사할 수 있도록 해야 합니다.

스캐너는 ANSI 이스케이프 코드를 사용하여 Unix 표준 출력 및 표준 오류 스트림에 작성하는 메시지에 색상을 적용할 수 있습니다. 오류에는 빨간색, 경고에는 노란색, 알림에는 녹색을 사용하는 것이 권장됩니다. 또한 오류 메시지에는 [ERRO], 경고에는 [WARN], 알림에는 [INFO]를 접두사로 붙이는 것이 권장됩니다.

로깅 레벨#

스캐너는 SECURE_LOG_LEVEL CI/CD 변수에 설정된 로그 레벨보다 낮은 레벨의 로그 메시지를 필터링해야 합니다. 예를 들어, SECURE_LOG_LEVELerror로 설정되어 있으면 infowarn 메시지는 건너뛰어야 합니다. 허용되는 값은 다음과 같으며 가장 높은 것부터 가장 낮은 순으로 나열됩니다:

  • fatal

  • error

  • warn

  • info

  • debug

디버깅에 유용할 수 있는 상세한 로깅에는 debug 레벨을 사용하는 것이 권장됩니다. SECURE_LOG_LEVEL의 기본값은 info로 설정해야 합니다.

명령줄을 실행할 때 스캐너는 명령줄과 출력을 기록하기 위해 debug 레벨을 사용해야 합니다. 명령줄이 실패하면 error 로그 레벨로 기록해야 합니다. 이렇게 하면 로그 레벨을 debug로 변경하고 스캐닝 job을 다시 실행하지 않고도 문제를 디버깅할 수 있습니다.

common logutil 패키지#

gocommon을 사용하는 경우, Logruscommon의 logutil 패키지를 사용하여 Logrus의 포매터를 구성하는 것이 권장됩니다. logutil README를 참조하세요.

리포트#

리포트는 취약점과 가능한 수정 방법을 결합한 JSON 문서입니다.

이 문서는 리포트 JSON 형식, 권장사항, 통합 담당자가 필드를 설정하는 데 도움이 되는 예시를 개요로 제공합니다. 형식은 SAST, DAST, 종속성 스캐닝, 컨테이너 스캐닝 문서에서 광범위하게 설명됩니다.

이 스캐너들의 스키마는 다음에서 확인할 수 있습니다:

리포트 검증#

스캐너가 생성한 리포트가 리포트에 선언된 스키마 버전에 대한 검증을 통과하는지 확인해야 합니다. 검증을 통과하지 못한 리포트는 GitLab이 수집하지 않으며 해당 파이프라인에 오류 메시지가 표시됩니다.

더 이상 사용되지 않는 버전의 보안 리포트 스키마를 사용하는 리포트는 수집되지만 해당 파이프라인에 경고 메시지가 표시됩니다. 이 경고가 표시되면 분석기를 업데이트하여 최신 스키마를 사용하세요.

스키마 버전의 지원 중단 기간이 끝나면 해당 파일이 GitLab에서 제거됩니다. 제거된 버전을 선언하는 리포트는 거부되고 해당 파이프라인에 오류 메시지가 표시됩니다.

리포트가 공급된 스키마 버전과 일치하지 않는 PATCH 버전을 사용하는 경우 최신 공급된 PATCH 버전에 대해 검증됩니다. 예를 들어, 리포트 버전이 15.0.23이고 최신 공급 버전이 15.0.6이면 리포트는 버전 15.0.6에 대해 검증됩니다.

GitLab은 gitlab-security_report_schemas gem에서 읽은 보안 리포트 JSON 스키마에 대해 리포트를 검증합니다. 예를 들어, GitLab 15.4는 버전 0.1.2.min15.0.0.max15.2.0을 사용하는데, 이는 15.0.015.2.0 범위의 버전을 지원함을 의미합니다. GitLab 버전에서 지원되는 스키마 버전은 GitLab 설치의 gem 버전을 확인하여 알 수 있습니다.

정확한 버전을 보려면 로컬 검증 섹션을 참조하세요.

로컬 검증#

GitLab에서 분석기를 실행하기 전에 분석기가 생성한 리포트가 선언된 스키마 버전을 준수하는지 확인하기 위해 리포트를 검증해야 합니다.

  • gitlab-security_report_schemas를 설치합니다.

  • security-report-schemas를 실행하여 지원되는 스키마 버전을 확인합니다.

  • security-report-schemas <report.json>을 실행하여 리포트를 검증합니다.

$ gem install gitlab-security_report_schemas -v 0.1.2.min15.0.0.max15.2.1
Successfully installed gitlab-security_report_schemas-0.1.2.min15.0.0.max15.2.1
Parsing documentation for gitlab-security_report_schemas-0.1.2.min15.0.0.max15.2.1
Done installing documentation for gitlab-security_report_schemas after 0 seconds
1 gem installed

$ security-report-schemas
SecurityReportSchemas 0.1.2.min15.0.0.max15.2.1.
Supported schema versions: ["15.0.0", "15.0.1", "15.0.2", "15.0.4", "15.0.5", "15.0.6", "15.0.7", "15.1.0", "15.1.1", "15.1.2", "15.1.3", "15.1.4", "15.2.0", "15.2.1"]

Usage: security-report-schemas REPORT_FILE_PATH [options]
    -r, --report_type=REPORT_TYPE    Override the report type
    -w, --warnings                   Prints the warning messages

$ security-report-schemas ~/Downloads/gl-dependency-scanning-report.json
Validating dependency_scanning v15.0.0 against schema v15.0.0
Content is invalid
* root is missing required keys: dependency_files

리포트 필드#

버전#

이 필드는 사용 중인 보안 리포트 스키마 버전을 지정합니다. 사용할 버전에 대한 정보는 릴리스를 참조하세요.

GitLab은 이 값으로 지정된 스키마 버전에 대해 리포트를 검증합니다.

취약점#

리포트의 vulnerabilities 필드는 취약점 객체의 배열입니다.

ID#

id 필드는 취약점의 고유 식별자입니다. 수정 객체에서 수정된 취약점을 참조하는 데 사용됩니다. UUID를 생성하여 id 필드의 값으로 사용하는 것이 권장됩니다.

카테고리#

category 필드의 값은 리포트 유형과 일치합니다:

  • dependency_scanning

  • container_scanning

  • sast

  • dast

스캔#

scan 필드는 스캔 자체에 대한 메타 정보를 포함하는 객체입니다: 스캔을 수행한 analyzerscanner, 스캔이 실행된 start_timeend_time, 스캔의 status(성공 또는 실패).

analyzerscanner 필드 모두 사람이 읽을 수 있는 name과 기술적인 id를 포함하는 객체입니다. id는 다른 통합 담당자가 제공하는 다른 분석기 또는 스캐너와 충돌하지 않아야 합니다.

스캔 기본 식별자#

scan.primary_identifiers 필드는 기본 식별자의 배열을 포함하는 선택적 필드입니다. 분석기가 스캔을 수행한 모든 규칙 세트의 완전한 목록입니다.

특정 스캔의 취약점 배열이 비어 있는 경우에도 이 선택적 필드는 어떤 규칙이 실행되었는지 Rails 애플리케이션에 알리기 위해 잠재적 식별자의 완전한 목록을 포함해야 합니다.

이 필드가 채워지면 Rails 애플리케이션은 기본 식별자가 포함되지 않은 경우 이전에 탐지된 취약점을 자동으로 더 이상 관련 없음으로 해결할 수 있습니다.

이름, 메시지, 설명#

namemessage 필드는 취약점에 대한 짧은 설명을 포함합니다. description 필드는 더 자세한 내용을 제공합니다.

name 필드는 컨텍스트에 독립적이며 취약점이 발견된 위치에 대한 정보를 포함하지 않지만 message는 위치를 반복할 수 있습니다.

시각적 예시로, 이 스크린샷은 파이프라인 보기의 일부로 취약점을 볼 때 이 필드들이 사용되는 위치를 강조합니다.

[

](/19.1/development/integrations/img/example_vuln_v13_0.png)

예를 들어, 종속성 스캐닝이 보고한 취약점의 message는 취약한 의존성에 대한 정보를 제공하는데, 이는 취약점의 location 필드와 중복됩니다. name 필드가 선호되지만 컨텍스트/위치를 취약점 제목에서 제거할 수 없는 경우 message 필드가 사용됩니다.

예시로, 다음은 종속성 스캐닝 스캐너가 보고한 취약점 객체이며 messagelocation 필드를 반복합니다:

{
    "location": {
        "dependency": {
            "package": {
            "name": "debug"
          }
        }
    },
    "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."
}

description은 취약점의 작동 방식을 설명하거나 익스플로잇에 대한 컨텍스트를 제공할 수 있습니다. 취약점 객체의 다른 필드를 반복해서는 안 됩니다. 특히 descriptionlocation(영향을 받는 항목)이나 solution(위험 완화 방법)을 반복해서는 안 됩니다.

해결 방법#

solution 필드를 사용하여 사용자에게 식별된 취약점을 수정하거나 위험을 완화하는 방법을 안내할 수 있습니다. 최종 사용자가 이 필드와 상호작용하는 반면, GitLab은 remediations 객체를 자동으로 처리합니다.

식별자#

identifiers 배열은 탐지된 취약점을 설명합니다. 식별자 객체의 typevalue 필드는 두 식별자가 동일한지 여부를 판단하는 데 사용됩니다. 사용자 인터페이스는 객체의 nameurl 필드를 사용하여 식별자를 표시합니다.

identifiers 배열의 첫 번째 항목을 기본 식별자라고 하며, 리포지터리에 새 커밋이 푸시될 때 취약점을 추적하는 데 사용됩니다.

GitLab 스캐너가 이미 정의한 식별자를 사용하는 것이 권장됩니다:

식별자 유형 예시 값 예시 이름
CVE cve CVE-2019-10086 CVE-2019-10086
CWE cwe 1026 CWE-1026
ELSA elsa ELSA-2020-0085 ELSA-2020-0085
OSVD osvdb OSVDB-113928 OSVDB-113928
OWASP owasp A01:2021 A01:2021 - Broken Access Control
RHSA rhsa RHSA-2020:0111 RHSA-2020:0111
USN usn USN-4234-1 USN-4234-1
GHSA ghsa GHSA-38jh-8h67-m7mj GHSA-38jh-8h67-m7mj
HACKERONE hackerone 698789 HACKERONE-698789

위에 나열된 일반 식별자는 GitLab이 유지 관리하는 일부 분석기에서 공유하는 공통 라이브러리에 정의되어 있습니다. 필요한 경우 새 일반 식별자를 기여할 수 있습니다. 분석기는 공통 라이브러리에 속하지 않는 벤더별 또는 제품별 식별자를 생성할 수도 있습니다.

모든 취약점에 CVE가 있는 것은 아니며, CVE는 여러 번 식별될 수 있습니다. 따라서 CVE는 안정적인 식별자가 아니므로 취약점 추적 시 그렇게 가정해서는 안 됩니다.

취약점의 최대 식별자 수는 20개로 설정되어 있습니다. 취약점의 식별자가 20개를 초과하면 시스템은 처음 20개만 저장합니다. 파이프라인 보안 탭의 취약점은 이 제한을 적용하지 않으며 리포트 아티팩트에 있는 모든 식별자가 표시됩니다.

세부 정보#

details 필드는 취약점 정보를 볼 때 표시되는 다양한 콘텐츠 요소를 지원하는 객체입니다. 다양한 데이터 요소의 예시는 security-reports 리포지터리에서 확인할 수 있습니다.

위치#

location은 취약점이 탐지된 위치를 나타냅니다. 위치의 형식은 스캐닝 유형에 따라 다릅니다.

GitLab은 내부적으로 location의 일부 속성을 추출하여 위치 지문을 생성합니다. 이 지문은 리포지터리에 새 커밋이 푸시될 때 취약점을 추적하는 데 사용됩니다. 위치 지문을 생성하는 데 사용되는 속성도 스캐닝 유형에 따라 다릅니다.

종속성 스캐닝#

종속성 스캐닝 취약점의 locationdependencyfile로 구성됩니다. dependency 객체는 영향을 받는 package와 의존성 version을 설명합니다. package는 영향을 받는 라이브러리/모듈의 name을 포함합니다. file은 영향을 받는 의존성을 선언하는 의존성 파일의 경로입니다.

예를 들어, npm 패키지 handlebars의 버전 4.0.11에 영향을 주는 취약점의 location 객체는 다음과 같습니다:

{
    "file": "client/package.json",
    "dependency": {
        "package": {
            "name": "handlebars"
        },
        "version": "4.0.11"
    }
}

이 영향을 받는 의존성은 npm 또는 yarn이 처리하는 의존성 파일인 client/package.json에 나열됩니다.

종속성 스캐닝 취약점의 위치 지문은 file과 패키지 name을 결합하므로 이 속성들은 필수입니다. 다른 모든 속성은 선택 사항입니다.

컨테이너 스캐닝#

종속성 스캐닝과 마찬가지로 컨테이너 스캐닝 취약점의 location에는 dependencyfile이 있습니다. 또한 operating_system 필드도 있습니다.

예를 들어, Debian 패키지 glib2.0의 버전 2.50.3-2+deb9u1에 영향을 주는 취약점의 location 객체는 다음과 같습니다:

{
    "dependency": {
        "package": {
            "name": "glib2.0"
        },
    },
    "version": "2.50.3-2+deb9u1",
    "operating_system": "debian:9",
    "image": "registry.gitlab.com/example/app:latest"
}

영향을 받는 패키지는 Docker 이미지 registry.gitlab.com/example/app:latest를 스캔할 때 발견됩니다. Docker 이미지는 debian:9(Debian Stretch)를 기반으로 합니다.

컨테이너 스캐닝 취약점의 위치 지문은 operating_system과 패키지 name을 결합하므로 이 속성들은 필수입니다. image도 필수입니다. 다른 모든 속성은 선택 사항입니다.

SAST#

SAST 취약점의 location에는 영향을 받는 파일의 경로를 제공하는 file과 영향을 받는 줄 번호가 있는 start_line 필드가 있어야 합니다. 또한 end_line, class, method도 가질 수 있습니다.

예를 들어, com.gitlab.security_products.tests.App Java 클래스의 generateSecretToken 메서드에서 src/main/java/com/gitlab/example/App.java41번째 줄에서 발견된 보안 결함의 location 객체는 다음과 같습니다:

{
    "file": "src/main/java/com/gitlab/example/App.java",
    "start_line": 41,
    "end_line": 41,
    "class": "com.gitlab.security_products.tests.App",
    "method": "generateSecretToken1"
}

SAST 취약점의 위치 지문은 file, start_line, end_line을 결합하므로 이 속성들은 필수입니다. 다른 모든 속성은 선택 사항입니다.

취약점 추적#

줄 번호만으로 취약점을 추적하면 문제가 발생합니다. 코드가 변경될 때 동일한 취약점이 중복될 수 있습니다. GitLab은 다른 접근 방식을 사용하여 이 중복을 최소화합니다. 각 취약점을 범위 및 오프셋 서명으로 추적합니다. 이 서명은 분석기 리포트에 범위 정보를 추가하는 후처리기인 추적 계산기에서 가져옵니다.

영향을 받는 파일의 이름이 변경되거나 관련 코드가 다른 파일로 이동되면 취약점 추적이 적용되지 않습니다.

취약점의 서명은 다음 속성의 해시로 계산된 UUIDv5 다이제스트를 사용하여 계산됩니다:

중복 제거 프로세스도 참조하세요.

심각도#

severity 필드는 취약점이 소프트웨어에 얼마나 큰 영향을 주는지 설명합니다. 심각도는 보안 대시보드에서 취약점을 정렬하는 데 사용됩니다.

심각도는 Info에서 Critical까지 범위가 있으며 Unknown도 될 수 있습니다. 유효한 값은 Unknown, Info, Low, Medium, High, Critical입니다.

Unknown 값은 실제 값을 결정하기 위한 데이터가 없음을 의미합니다. 따라서 high, medium, low일 수 있으며 조사가 필요합니다.

수정 사항#

리포트의 remediations 필드는 수정 객체의 배열입니다. 각 수정 사항은 취약점 집합을 해결하기 위해 적용할 수 있는 패치를 설명합니다.

다음은 수정 사항이 포함된 리포트의 예시입니다.

{
    "vulnerabilities": [
        {
            "category": "dependency_scanning",
            "name": "Regular Expression Denial of Service",
            "id": "123e4567-e89b-12d3-a456-426655440000",
            "solution": "Upgrade to new versions.",
            "scanner": {
                "id": "gemnasium",
                "name": "Gemnasium"
            },
            "identifiers": [
                {
                  "type": "gemnasium",
                  "name": "Gemnasium-642735a5-1425-428d-8d4e-3c854885a3c9",
                  "value": "642735a5-1425-428d-8d4e-3c854885a3c9"
                }
            ]
        }
    ],
    "remediations": [
        {
            "fixes": [
                {
                    "id": "123e4567-e89b-12d3-a456-426655440000"
                }
            ],
            "summary": "Upgrade to new version",
            "diff": "ZGlmZiAtLWdpdCBhL3lhcm4ubG9jayBiL3lhcm4ubG9jawppbmRleCAwZWNjOTJmLi43ZmE0NTU0IDEwMDY0NAotLS0gYS95Y=="
        }
    ]
}
요약#

summary 필드는 취약점을 수정할 수 있는 방법에 대한 개요입니다. 이 필드는 필수입니다.

수정된 취약점#

fixes 필드는 수정 사항으로 수정된 취약점을 참조하는 객체의 배열입니다. fixes[].id에는 수정된 취약점의 고유 식별자가 포함됩니다. 이 필드는 필수입니다.

Diff#

diff 필드는 git apply와 호환되는 base64 인코딩된 수정 코드 diff입니다. 이 필드는 필수입니다.