Advanced SAST C/C++ 구성
Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
프로젝트에서 GitLab Advanced SAST C/C++ 분석을 활성화하려면: 상단 표시줄에서 Search or go to를 선택하여 프로젝트를 찾습니다. Build > Pipeline 편집기로 이동합니다. SAST 작업 구성에 C/C++ 분석을 추가합니다.
GitLab Advanced SAST C/C++ 분석 활성화#
사전 요구사항:
프로젝트에서 GitLab Advanced SAST C/C++ 분석을 활성화하려면:
-
상단 표시줄에서 Search or go to를 선택하여 프로젝트를 찾습니다.
-
Build > Pipeline 편집기로 이동합니다.
-
SAST 작업 구성에 C/C++ 분석을 추가합니다. 여기서는 컴파일 데이터베이스 이름이
compile_commands.json이라고 가정합니다.-
CI/CD 템플릿을 사용하는 경우,
include:문 뒤에 다음 CI/CD 변수를 구성에 추가하세요:include: - template: Jobs/SAST.gitlab-ci.yml variables: GITLAB_ADVANCED_SAST_CPP_ENABLED: "true" SAST_COMPILATION_DATABASE: "compile_commands.json" -
CI/CD 컴포넌트를 사용하는 경우, 구성에 다음 입력 파라미터와 CI/CD 변수를 추가하세요:
include: - component: gitlab.com/components/sast/sast@main inputs: run_advanced_sast_cpp: "true" variables: SAST_COMPILATION_DATABASE: "compile_commands.json"
-
-
Validate 탭을 선택한 다음 Validate pipeline을 선택합니다.
Simulation completed successfully 메시지가 파일이 유효함을 확인합니다.
-
Edit 탭을 선택합니다.
-
다음 필드를 작성합니다:
- 커밋 메시지.
- 브랜치. 예:
add-sast.
-
Start a new merge request with these changes 체크박스를 선택한 다음 Commit changes를 선택합니다.
Merge request 페이지가 열립니다.
-
표준 워크플로우에 따라 필드를 작성한 다음 Create merge request를 선택합니다.
-
표준 워크플로우에 따라 Merge request를 검토 및 편집한 다음 Merge를 선택합니다.
컴파일 데이터베이스#
GitLab Advanced SAST CPP 분석기는 소스 파일을 올바르게 파싱하고 분석하기 위해 컴파일 데이터베이스(CDB)가 필요합니다.
CDB는 각 번역 단위에 대해 하나의 항목을 포함하는 JSON 파일(compile_commands.json)입니다.
각 항목은 일반적으로 다음을 지정합니다:
- 파일을 빌드하는 데 사용된 컴파일러 명령
- 컴파일러 플래그 및 포함 경로
- 컴파일이 수행되는 작업 디렉토리
CDB를 통해 분석기는 정확한 빌드 환경을 재현하여 정확한 파싱과 의미론적 분석을 보장합니다.
GitLab Advanced SAST CPP를 사용하려면 CDB를 생성하고 분석기에 제공해야 합니다.
CDB 생성#
CDB를 생성하는 방법은 빌드 시스템에 따라 다릅니다. 아래는 일반적인 예제입니다.
예제: CMake#
CMake는 cmake 호출에 -DCMAKE_EXPORT_COMPILE_COMMANDS=ON 파라미터를 추가하여 CDB를 직접 생성할 수 있습니다:
cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
이 옵션은 프로젝트를 구성하고 각 소스 파일에 대한 컴파일러 명령을 기록하는 compile_commands.json 파일을 build 폴더에 생성합니다.
GitLab Advanced SAST CPP 분석기는 이 파일을 사용하여 빌드 환경을 정확하게 재현합니다.
다음 빌드 작업 예제에서 생성된 compile_commands.json 파일을 작업 아티팩트로 내보내세요:
:
image: ubuntu:24.04
before_script:
- apt update -qq && apt install -y -qq cmake build-essential
script:
- mkdir -p build
- cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
- make -j$(nproc)
artifacts:
paths:
- build/compile_commands.json # Pass the CDB file to the gitlab-advanced-sast-cpp job
다양한 빌드 시스템 예제#
다양한 빌드 시스템으로 CDB를 생성하고 GitLab Advanced SAST CPP를 실행하는 전체 예제도 찾을 수 있습니다:
분석기에 CDB 제공#
SAST_COMPILATION_DATABASE 변수로 GitLab Advanced SAST CPP 분석기에 CDB 위치를 알려주세요:
variables:
SAST_COMPILATION_DATABASE: YOUR_COMPILATION_DATABASE.json
SAST_COMPILATION_DATABASE가 지정되지 않으면 GitLab Advanced SAST CPP 분석기는 기본적으로 프로젝트 루트 디렉토리에 있는 compile_commands.json 파일을 사용합니다.
compile_commands.json 파일을 생성하는 빌드 작업은 gitlab-advanced-sast-cpp 작업이 사용할 수 있도록 이를 작업 아티팩트로 내보내야 합니다:
variables:
SAST_COMPILATION_DATABASE: build/compile_commands.json
:
image: ubuntu:24.04
before_script:
- apt update -qq && apt install -y -qq cmake build-essential
script:
- mkdir -p build
- cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
- make -j$(nproc)
artifacts:
paths:
- build/compile_commands.json # Pass the CDB file to the gitlab-advanced-sast-cpp job
또는 CDB 캐싱을 검토하세요.
분석 런타임 최적화#
C/C++ 코드의 분석 런타임을 최적화하기 위해 CDB를 여러 조각으로 분할하여 병렬로 분석을 실행할 수 있습니다.
GitLab Advanced SAST CPP 저장소는 CDB를 분할하고 병렬 분석을 실행하기 위한 헬퍼 스크립트를 제공합니다.
C/C++ 코드 분석을 병렬로 실행하려면:
-
스크립트를 포함합니다:
include: - project: "gitlab-org/security-products/demos/sast/gitlab-advanced-sast-cpp-templates" file: "templates/scripts.yml" -
빌드 작업에서 헬퍼 스크립트를 참조하고 CDB를 분할합니다:
: script: - <your-script to generate the CDB> - !reference [.gitlab-advanced-sast-cpp-scripts] - split_cdb "${BUILD_DIR}" 1 4 # Split into 4 fragments artifacts: paths: - ${BUILD_DIR} # Pass the split CDB files to the parallelized gitlab-advanced-sast-cpp jobs[!note]
split_cdb는${BUILD_DIR}/compile_commands.json을 읽도록 하드코딩되어 있습니다. 빌드가split_cdb를 호출하기 전에 이 정확한 위치에 CDB를 생성해야 합니다. -
병렬 분석기 작업을 실행합니다:
gitlab-advanced-sast-cpp: parallel: 4 variables: SAST_COMPILATION_DATABASE: "${BUILD_DIR}/compile_commands${CI_NODE_INDEX}.json" needs: - job: artifacts: trueparallel: 4는 실행을 4개 작업으로 분산합니다.${CI_NODE_INDEX}(1, 2, 3, 4)는 올바른 CDB 조각을 선택합니다.needs는 분석기 작업이 빌드 작업에서 생성된 아티팩트를 수신하도록 보장합니다.
이 설정으로 빌드 작업은 단일 compile_commands.json을 생성합니다.
split_cdb 스크립트는 여러 파티션을 생성하고, 분석기 작업은 병렬로 실행되며 각 작업이 하나의 파티션을 처리합니다.
룰셋 구성#
GitLab Advanced SAST CPP는 "규칙"이 GitLab Advanced SAST CPP 체커인 사용자 정의 룰셋을 지원합니다.
사용자 정의 룰셋은 CodeChecker 구성 파일로 구성된 패스스루로 만들 수 있습니다.
패스스루 구성은 다음과 같이 처리됩니다:
targetDir과target은 무시됩니다. 패스스루 처리 후 결과 플래그는CodeChecker에 직접 전달됩니다.overwrite모드는 전체 구성을 교체하고append모드는 플래그를 추가합니다.- 분석기 플래그
-o,--output과 파싱 플래그-o, --output, -e, --export를 포함한 특정CodeChecker플래그는 사용자 정의할 수 없습니다. server및store구성 항목은 무시됩니다.
다음 예제는 다른 소스의 패스스루가 결합되는 방법을 보여줍니다:
파일 .gitlab/sastconfig.toml:
[gitlab-advanced-sast-cpp]
description = "My ruleset"
[[gitlab-advanced-sast-cpp.passthrough]]
# replace the GitLab default configuration with my own
mode = "overwrite"
type = "url"
value = "https://example.com/gitlab-advanced-sast-cpp.yaml"
[[gitlab-advanced-sast-cpp.passthrough]]
# append flags from a file in the current repository
mode = "append"
type = "file"
value = "gitlab-advanced-sast-cpp.yml"
https://example.com/gitlab-advanced-sast-cpp.yaml의 원격 구성:
analyzer:
- --disable-all
- --enable=core.DivideZero
gitlab-advanced-sast-cpp.yml의 로컬 구성:
analyzer:
- --enable=core.CallAndMessage
결합된 결과 구성은 다음과 같습니다:
analyzer:
- --disable-all
- --enable=core.DivideZero
- --enable=core.CallAndMessage
트러블슈팅#
cdb-rebase로 경로 리베이스#
CDB 내부의 경로가 CI/CD 작업의 컨테이너 경로와 일치하지 않는 경우 cdb-rebase로 조정하세요.
설치:
go install gitlab.com/gitlab-org/secure/tools/cdb-rebase@latest
바이너리는 $GOPATH/bin 또는 $HOME/go/bin에 설치됩니다. 이 디렉토리가 PATH에 있는지 확인하세요.
사용 예:
cdb-rebase compile_commands.json /host/path /container/path > rebased_compile_commands.json
CDB 수정#
빌드 환경이 스캔 환경과 다른 경우, 생성된 CDB를 조정해야 할 수 있습니다.
jq로 수정하거나 미리 정의된 헬퍼 스크립트의 셸 함수인 cdb_append를 사용할 수 있습니다.
cdb_append는 기존 CDB에 컴파일러 옵션을 추가합니다.
다음을 허용합니다:
- 첫 번째 인수:
compile_commands.json이 있는 폴더 - 이후 인수: 추가할 추가 컴파일러 옵션
CI/CD에서의 예:
include:
- project: "gitlab-org/security-products/demos/sast/gitlab-advanced-sast-cpp-templates"
file: "templates/scripts.yml"
:
script:
- !reference [.gitlab-advanced-sast-cpp-scripts]
- <your-script to generate the CDB>
- cdb_append "${BUILD_DIR}" "-I'$PWD/include-cache'" "-Wno-error=register"
CDB 캐싱#
컴파일 및 분석 프로세스를 가속화하기 위해 CDB를 캐시할 수 있습니다.
.cdb_cache:
cache: &cdb_cache
key:
files:
- Makefile
- src/
paths:
- compile_commands.json
:
script:
- <your-script to generate the CDB>
cache:
<<: *cdb_cache
policy: pull-push
gitlab-advanced-sast-cpp:
cache:
<<: *cdb_cache
policy: pull
전체 예제는 데모 프로젝트 cached-cdb를 참조하세요.
CDB에서 절대 경로 처리#
데모 프로젝트에서 bear는 Docker 작업의 빌드 디렉토리에서 실행됩니다.
CDB 경로는 /builds/$CI_PROJECT_PATH를 기반으로 절대 경로입니다.
분석기 작업 gitlab-advanced-sast-cpp는 같은 위치에서 실행되므로 경로가 올바릅니다.
CDB가 분석 중에 사용 가능하지 않은 경로에서 생성된 경우 리베이스해야 합니다.
분석기 이미지에 포함된 cdb-rebase 도구는 directory, file, output 경로를 다시 씁니다.
예:
gitlab-advanced-sast-cpp:
before-script:
# Rebase the original CDB to be relative to the current directory.
#
# ORIGINAL_CDB_PATH - Path to the CDB artifact from a previous job (e.g., artifacts/compile_commands.json)
# ORIGINAL_CDB_BASEPATH - The absolute path to the project root when the ORIGINAL_CDB_PATH was generated.
# (e.g., /mnt/custom_build_area/my-project or /home/user/my-project)
- /cdb-rebase --input "$ORIGINAL_CDB_PATH" \
--output compile_commands.json \
--src "$ORIGINAL_CDB_BASEPATH" \
--dst .
전체 데모는 cdb-rebase-demo를 참조하세요.
단순한 경로 리베이스 외에도 cdb-rebase는 빌드 환경과 스캔 환경 사이의 포함 파일을 관리할 수도 있습니다:
- 외부 헤더 캐시:
--include-cache를 사용하면 소스 트리 외부의 헤더가 이동 가능한 캐시로 복사됩니다. - 포함 경로 추가:
--include를 사용하면 캐시할 추가 포함 디렉토리를 지정합니다. - 파일 제외:
--exclude를 사용하면 가져오지 않을 헤더를 건너뜁니다.
예:
/cdb-rebase --src /my-project \
--dst /scan-env \
--input build/compile_commands.json \
--output rebased_cdb.json \
--include-cache include-cache \
--include third_party/include \
--exclude dummy.h
cde-rebase 도구는 Go가 설치된 환경에서도 사용할 수 있으므로 CDB를 생성할 때 리베이스가 가능합니다. 예:
go install gitlab.com/gitlab-org/security-products/analyzers/clangsa/cmd/cdb-rebase@latest
bear -o compile_commands_abs.json -- make
cdb-rebase -i compile_commands_abs.json -o compile_commands.json -s "$PWD" -d .
위의 go install 명령은 cdb-rebase를 GOBIN 경로에 설치합니다. go env GOBIN으로 확인할 수 있습니다.
누락된 헤더 파일로 인한 부분 스캔 커버리지#
필요한 시스템 또는 서드파티 헤더 파일이 스캔 작업에서 사용 가능하지 않을 때 부분 스캔 커버리지가 발생할 수 있습니다. 빌드 작업 중 설치된 헤더는 스캔 작업으로 명시적으로 전달되어야 하며 컴파일 데이터베이스에 기록된 포함 경로를 통해 확인 가능해야 합니다.
일반적인 방법은 필요한 헤더를 캐시하고 해당 헤더를 참조하도록 컴파일 데이터베이스를 업데이트하는 것입니다:
# Create and populate an include cache
mkdir -p include-cache
dpkg -L <build-dependency-packages> | sed -n 's:^/usr/include/::p' > headers.txt
rsync -a --files-from=headers.txt /usr/include/ include-cache/
# Add cached headers to compile flags
cdb_append . "-I'$PWD/include-cache'"
전체 데모는 예제를 참조하세요.
