의존성 스캐닝
GitLab v19.4Offering: GitLab Self-Managed
요약
Gemnasium 분석기 기반 의존성 스캔 기능은 GitLab 17.9에서 더 이상 사용되지 않으며(deprecated), GitLab 20.0에서 제거될 예정입니다. 의존성 스캔은 CI/CD 파이프라인에 통합되어 자동으로 실행되며, 애플리케이션 의존성의 보안 취약점을 식별합니다.
Gemnasium 분석기 기반 의존성 스캔 기능은 GitLab 17.9에서 더 이상 사용되지 않으며(deprecated), GitLab 20.0에서 제거될 예정입니다. 다만 제거 시점은 확정되지 않았으며, 필요에 따라 Gemnasium을 계속 사용할 수 있습니다. 자세한 내용은 에픽 15961을 참고합니다.
의존성 스캔은 CI/CD 파이프라인에 통합되어 자동으로 실행되며, 애플리케이션 의존성의 보안 취약점을 식별합니다. 브랜치를 병합하기 전에 스캔하면 머지 리퀘스트에서 보안 문제를 즉시 확인할 수 있습니다. 이를 통해 코드를 병합하기 전에 잠재적 취약점에 대해 충분한 정보를 바탕으로 결정을 내릴 수 있습니다.
기본적으로 의존성 스캔은 런타임, 개발, 전이(중첩) 의존성을 포함해 코드의 모든 의존성을 분석합니다. 필요에 따라 스캔에서 개발 의존성을 제외할 수 있습니다.
- 개요는 Dependency scanning - Advanced Security Testing을 참고합니다.
- 이 의존성 스캔 문서를 함께 읽으며 따라 하는 대화형 실습 데모는 How to use dependency scanning tutorial hands-on GitLab Application Security part 3을 참고합니다.
- 그 밖의 대화형 실습 데모는 Get Started With GitLab Application Security Playlist를 참고합니다.
파이프라인 밖에서 의존성의 취약점을 스캔하려면 지속적 취약점 스캔을 참고합니다.
의존성 스캔 켜기#
다음 단계에 따라 프로젝트에서 의존성 스캔을 켭니다.
분석기를 사용 설정하려면 다음 중 하나를 수행합니다.
- 의존성 스캔이 포함된 Auto DevOps를 사용 설정합니다.
- 사전 구성된 머지 리퀘스트를 사용합니다.
- 의존성 스캔을 강제하는 스캔 실행 정책을 생성합니다.
.gitlab-ci.yml파일을 직접 편집합니다.- CI/CD 컴포넌트를 사용합니다.
사전 구성된 머지 리퀘스트 사용#
이 방법은 .gitlab-ci.yml 파일에 의존성 스캔 템플릿을 포함한 머지 리퀘스트를
자동으로 준비합니다. 그런 다음 머지 리퀘스트를 병합하면 의존성 스캔이 사용 설정됩니다.
이 방법은 기존 .gitlab-ci.yml 파일이 없거나 최소한의 구성 파일만 있을 때 가장 잘 동작합니다.
GitLab 구성 파일이 복잡하면 파싱에 성공하지 못해 오류가 발생할 수
있습니다. 그 경우에는 수동 방법을 대신 사용합니다.
사전 요구 사항:
- 프로젝트의 Maintainer 또는 Owner 권한.
.gitlab-ci.yml파일에testStage가 있어야 합니다.- 자체 관리형 러너의 경우
docker또는kubernetesexecutor를 사용하는 GitLab Runner. - GitLab.com의 호스팅 러너는 이 구성이 기본적으로 사용 설정되어 있습니다.
의존성 스캔을 켜려면 다음을 수행합니다.
- 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.
- 왼쪽 사이드바에서 Secure > Security configuration을 선택합니다.
- Dependency Scanning 행에서 Configure with a merge request를 선택합니다.
- Create merge request를 선택합니다.
- 머지 리퀘스트를 검토한 다음 Merge를 선택합니다.
이제 파이프라인에 의존성 스캔 job이 포함됩니다.
.gitlab-ci.yml 파일 직접 편집#
이 방법은 기존 .gitlab-ci.yml 파일을 직접 편집해야 합니다. GitLab CI/CD 구성 파일이
복잡한 경우 이 방법을 사용합니다.
사전 요구 사항:
- 프로젝트의 Maintainer 또는 Owner 권한.
.gitlab-ci.yml파일에testStage가 있어야 합니다.- 자체 관리형 러너의 경우
docker또는kubernetesexecutor를 사용하는 GitLab Runner. - GitLab.com의 호스팅 러너는 이 구성이 기본적으로 사용 설정되어 있습니다.
의존성 스캔을 켜려면 다음을 수행합니다.
-
상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.
-
왼쪽 사이드바에서 Build > Pipeline editor를 선택합니다.
-
.gitlab-ci.yml파일이 없으면 Configure pipeline을 선택한 다음 예시 내용을 삭제합니다. -
다음을 복사해
.gitlab-ci.yml파일 맨 아래에 붙여넣습니다.include줄이 이미 있으면 그 아래에template줄만 추가합니다.include: - template: Jobs/Dependency-Scanning.gitlab-ci.yml -
Validate 탭을 선택한 다음 Validate pipeline을 선택합니다.
Simulation completed successfully 메시지가 표시되면 파일이 유효한 것입니다.
-
Edit 탭을 선택합니다.
-
필드를 입력합니다. Branch 필드에는 기본 브랜치를 사용하지 않습니다.
-
Start a new merge request with these changes 체크박스를 선택한 다음 Commit changes를 선택합니다.
-
표준 워크플로에 따라 필드를 입력한 다음 Create merge request를 선택합니다.
-
표준 워크플로에 따라 머지 리퀘스트를 검토하고 편집한 다음 Merge를 선택합니다.
이제 파이프라인에 의존성 스캔 job이 포함됩니다.
CI/CD 컴포넌트 사용#
의존성 스캔 CI/CD 컴포넌트는 Android 프로젝트만 지원합니다.
CI/CD 컴포넌트를 사용해 애플리케이션의 의존성 스캔을 수행합니다. 방법은 해당 컴포넌트의 README 파일을 참고합니다.
사용 가능한 CI/CD 컴포넌트#
https://gitlab.com/explore/catalog/components/dependency-scanning을 참고합니다.
이 단계를 완료하면 다음을 할 수 있습니다.
결과 이해#
의존성 스캔 결과는 여러 형식으로 제공됩니다. 파이프라인 UI, 상세 스캔 보고서, 또는 스캔 중 생성되는 소프트웨어 자재 명세서(SBOM, Software Bill of Materials)에서 직접 확인할 수 있습니다.
파이프라인의 취약점 검토#
파이프라인에서 탐지된 취약점을 검토하고 머지 리퀘스트가 병합되기 전에 조치합니다.
사전 요구 사항:
- 프로젝트의 Developer, Maintainer 또는 Owner 권한.
파이프라인에서 의존성 스캔 결과를 검토하려면 다음을 수행합니다.
- 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.
- 왼쪽 사이드바에서 Build > Pipelines를 선택합니다.
- 파이프라인을 선택합니다.
- Security 탭을 선택합니다.
- 취약점을 선택하면 다음을 포함한 세부 정보를 볼 수 있습니다.
- Status: 취약점이 분류(triage)되었는지 또는 해결되었는지를 나타냅니다.
- Description: 취약점의 원인, 잠재적 영향, 권장 해결 단계를 설명합니다.
- Severity: 영향도에 따라 6단계로 분류됩니다. 심각도 수준에 대해 자세히 알아봅니다.
- CVSS score: 심각도에 대응하는 수치 값을 제공합니다.
- EPSS: 취약점이 실제로 악용될 가능성을 보여 줍니다.
- Has Known Exploit (KEV): 해당 취약점이 악용된 적이 있음을 나타냅니다.
- Project: 취약점이 식별된 프로젝트를 강조해 표시합니다.
- Report type / Scanner: 출력 유형과 해당 출력을 생성한 스캐너를 설명합니다.
- Reachable: 취약한 의존성이 코드에서 사용되는지 여부를 나타냅니다.
- Scanner: 어떤 분석기가 취약점을 탐지했는지 식별합니다.
- Location: 취약한 의존성이 있는 파일을 나타냅니다.
- Links: 취약점이 여러 어드바이저리 데이터베이스에 등재되었다는 근거입니다.
- Identifiers: CVE 식별자 등 취약점을 분류하는 데 사용되는 참조 목록입니다.
의존성 스캔 보고서#
의존성 스캔은 모든 취약점의 세부 정보를 담은 보고서를 출력합니다. 이 보고서는
내부적으로 처리되어 결과가 UI에 표시됩니다. 보고서는 의존성 스캔 job의 아티팩트로도
출력되며 이름은 gl-dependency-scanning-report.json이고, 항상 프로젝트의 루트에
생성됩니다.
의존성 스캔 보고서에 대한 자세한 내용은 의존성 스캔 보고서 스키마를 참고합니다.
CycloneDX 소프트웨어 자재 명세서#
의존성 스캔은 감지한 지원 대상 잠금 파일 또는 빌드 파일마다 CycloneDX 소프트웨어 자재 명세서(SBOM)를 출력합니다.
CycloneDX SBOM은 다음과 같습니다.
- 이름은
gl-sbom-<package-type>-<package-manager>.cdx.json입니다. - 의존성 스캔 job의 job 아티팩트로 제공됩니다.
- 감지된 잠금 파일 또는 빌드 파일과 같은 디렉터리에 저장됩니다.
예를 들어 프로젝트가 다음과 같은 구조라고 가정합니다.
.
├── 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
단계적 적용#
단일 프로젝트의 의존성 스캔 결과를 신뢰할 수 있게 되면 다른 프로젝트로 적용 범위를 넓힐 수 있습니다.
지원되는 언어 및 패키지 관리자#
의존성 스캔은 컴파일러와 인터프리터의 런타임 설치를 지원하지 않습니다.
의존성 스캔은 다음 언어와 의존성 관리자를 지원합니다.
| 언어 | 언어 버전 | 패키지 관리자 | 지원되는 파일 | 여러 파일 처리 여부 |
|---|---|---|---|---|
| .NET | 모든 버전 | NuGet | packages.lock.json |
Y |
| C# | ||||
| C | 모든 버전 | Conan | conan.lock |
Y |
| C++ | ||||
| Go | 모든 버전 | Go |
|
Y |
| Java 및 Kotlin | 8 LTS, 11 LTS, 17 LTS, 또는 21 LTS1 | Gradle2 |
|
N |
| Maven6 | pom.xml |
N | ||
| JavaScript 및 TypeScript | 모든 버전 | npm |
|
Y |
| yarn | yarn.lock |
Y | ||
| pnpm3 | pnpm-lock.yaml |
Y | ||
| PHP | 모든 버전 | Composer | composer.lock |
Y |
| Python | 3.117 | setuptools8 | setup.py |
N |
| pip |
|
N | ||
| Pipenv | N | |||
| Poetry4 | poetry.lock |
N | ||
| uv11 | uv.lock |
Y | ||
| Ruby | 모든 버전 | Bundler |
|
Y |
| Scala | 모든 버전 | sbt5 | build.sbt |
N |
| Swift | 모든 버전 | Swift Package Manager | Package.resolved |
N |
| CocoaPods9 | 모든 버전 | CocoaPods | Podfile.lock |
N |
| Dart10 | 모든 버전 | Pub | pubspec.lock |
N |
각주:
- sbt의 Java 21 LTS는 1.9.7 버전으로 제한됩니다. 더 많은 sbt 버전에 대한 지원은 이슈 430335에서 추적할 수 있습니다. FIPS 모드가 사용 설정되어 있으면 지원되지 않습니다.
- FIPS 모드가 사용 설정되어 있으면 Gradle은 지원되지 않습니다.
- pnpm 잠금 파일은 번들된 의존성을 저장하지 않으므로 보고되는 의존성이 npm 또는 yarn과 다를 수 있습니다.
poetry.lock파일이 없는 프로젝트에 대한 지원은 이슈 32774에서 추적합니다.- sbt 1.0.x 지원은 GitLab 16.8에서 더 이상 사용되지 않게 되었고 GitLab 17.0에서 제거되었습니다.
- 3.8.8 미만 Maven 지원은 GitLab 16.9에서 더 이상 사용되지 않게 되었고 GitLab 17.0에서 제거되었습니다.
- 이전 Python 버전 지원은 GitLab 16.9에서 더 이상 사용되지 않게 되었고 GitLab 17.0에서 제거되었습니다.
- 설치 프로그램에 필요하므로
pip와setuptools는 모두 보고서에서 제외됩니다. - 권고 정보 없이 SBOM만 제공됩니다. 이슈 468764를 참고합니다.
- 라이선스 탐지는 지원되지 않습니다. 에픽 17037을 참고합니다.
- 잠금 파일에 같은 패키지에 대해 환경 마커가 다른 항목이 여러 개 있으면(예: Python <3.11용 numpy==2.2.6과 Python ≥3.11용 numpy==2.4.1) 첫 번째 항목만 파싱되어 보고됩니다.
지원되는 개발 의존성#
개발 의존성 탐지는 다음 언어와 패키지 관리자에서 지원됩니다.
| 언어 | 패키지 관리자 | 파일 |
|---|---|---|
| C/C++/Fortran/Go/Python/R | conda | conda-lock.yml |
| Java | Maven | maven.graph.json |
| Java/Kotlin | Gradle | dependencies.lock, dependencies.direct.lock, gradle-html-dependency-report.js, gradle.lockfile |
| JavaScript/TypeScript | npm | package-lock.json, npm-shrinkwrap.json |
| JavaScript/TypeScript | pnpm | pnpm-lock.yaml |
| PHP | Composer | composer.lock |
| Python | Pipenv | Pipfile.lock |
| Python | Poetry | poetry.lock |
| Python | uv | uv.lock |
머지 리퀘스트 파이프라인에서 job 실행#
머지 리퀘스트 파이프라인에서 보안 스캔 도구 사용을 참고합니다.
분석기 동작 사용자 지정#
의존성 스캔을 사용자 지정하려면 CI/CD 변수를 사용합니다.
GitLab 분석기의 모든 사용자 지정은 기본 브랜치에 병합하기 전에 머지 리퀘스트에서 테스트합니다. 그렇지 않으면 다수의 오탐을 포함해 예기치 않은 결과가 발생할 수 있습니다.
의존성 스캔 job 재정의#
job 정의를 재정의하려면(예: variables 또는 dependencies 같은 속성 변경), 재정의할 job과
같은 이름으로 새 job을 선언합니다. 이 새 job은 템플릿 포함(include) 뒤에 배치하고
그 아래에 필요한 추가 키를 지정합니다.
예를 들어 다음은 gemnasium 분석기의 취약한 의존성 자동 해결을
비활성화합니다.
include:
- template: Jobs/Dependency-Scanning.gitlab-ci.yml
gemnasium-dependency_scanning:
variables:
DS_REMEDIATE: "false"
dependencies: [] 속성을 재정의하려면 앞에서 설명한 대로 이 속성을 대상으로 하는 재정의 job을 추가합니다.
include:
- template: Jobs/Dependency-Scanning.gitlab-ci.yml
gemnasium-dependency_scanning:
dependencies: ["build"]
사용 가능한 CI/CD 변수#
CI/CD 변수를 사용해 의존성 스캔 동작을 사용자 지정할 수 있습니다.
전역 분석기 설정#
다음 변수로 전역 의존성 스캔 설정을 구성할 수 있습니다.
| CI/CD 변수 | 설명 |
|---|---|
ADDITIONAL_CA_CERT_BUNDLE |
신뢰할 CA 인증서 번들입니다. 여기에 제공한 인증서 번들은 스캔 과정에서 git, yarn, npm 같은 다른 도구에서도 사용됩니다. 자세한 내용은 사용자 지정 TLS 인증 기관을 참고합니다. |
DS_EXCLUDED_ANALYZERS |
의존성 스캔에서 제외할 분석기를 이름으로 지정합니다. 자세한 내용은 분석기를 참고합니다. |
DS_EXCLUDED_PATHS |
경로를 기준으로 스캔에서 파일과 디렉터리를 제외합니다. 패턴을 쉼표로 구분한 목록입니다. 패턴은 glob(지원되는 패턴은 doublestar.Match 참고)이거나 파일 또는 폴더 경로(예: doc,spec)일 수 있습니다. 상위 디렉터리도 패턴과 일치합니다. 스캔이 실행되기 전에 적용되는 사전 필터입니다. 기본값: "spec, test, tests, tmp". |
DS_IMAGE_SUFFIX |
이미지 이름에 추가되는 접미사입니다. (GitLab 팀 구성원은 이 비공개 이슈에서 더 많은 정보를 볼 수 있습니다: https://gitlab.com/gitlab-org/gitlab/-/issues/354796). FIPS 모드가 사용 설정되면 자동으로 "-fips"로 설정됩니다. |
DS_MAX_DEPTH |
분석기가 스캔할 지원 대상 파일을 몇 단계 깊이의 디렉터리까지 검색할지 정의합니다. 값이 -1이면 깊이에 관계없이 모든 디렉터리를 스캔합니다. 기본값: 2. |
SECURE_ANALYZERS_PREFIX |
공식 기본 이미지를 제공하는 Docker 레지스트리(프록시)의 이름을 재정의합니다. |
분석기별 설정#
다음 변수로 특정 의존성 스캔 분석기의 동작을 구성합니다.
| CI/CD 변수 | 분석기 | 기본값 | 설명 |
|---|---|---|---|
GEMNASIUM_DB_LOCAL_PATH |
gemnasium |
/gemnasium-db |
로컬 Gemnasium 데이터베이스의 경로입니다. |
GEMNASIUM_DB_UPDATE_DISABLED |
gemnasium |
"false" |
gemnasium-db 어드바이저리 데이터베이스의 자동 업데이트를 비활성화합니다. 사용법은 GitLab 어드바이저리 데이터베이스 접근을 참고합니다. |
GEMNASIUM_DB_REMOTE_URL |
gemnasium |
https://gitlab.com/gitlab-org/security-products/gemnasium-db.git |
GitLab 어드바이저리 데이터베이스를 가져올 리포지터리 URL입니다. |
GEMNASIUM_DB_REF_NAME |
gemnasium |
master |
원격 리포지터리 데이터베이스의 브랜치 이름입니다. GEMNASIUM_DB_REMOTE_URL이 필요합니다. |
GEMNASIUM_IGNORED_SCOPES |
gemnasium |
무시할 Maven 의존성 스코프를 쉼표로 구분한 목록입니다. 자세한 내용은 Maven 의존성 스코프 문서를 참고합니다. | |
DS_REMEDIATE |
gemnasium |
"true", FIPS 모드에서는 "false" |
취약한 의존성의 자동 해결을 사용 설정합니다. FIPS 모드에서는 지원되지 않습니다. |
DS_REMEDIATE_TIMEOUT |
gemnasium |
5m |
자동 해결의 제한 시간입니다. |
GEMNASIUM_LIBRARY_SCAN_ENABLED |
gemnasium |
"true" |
벤더링된 JavaScript 라이브러리(패키지 관리자가 관리하지 않는 라이브러리)의 취약점 탐지를 사용 설정합니다. 이 기능을 쓰려면 커밋에 JavaScript 잠금 파일이 있어야 하며, 없으면 의존성 스캔이 실행되지 않고 벤더링된 파일도 스캔되지 않습니다. 의존성 스캔은 Retire.js 스캐너를 사용해 제한된 범위의 취약점을 탐지합니다. 탐지되는 취약점에 대한 자세한 내용은 Retire.js 리포지터리를 참고합니다. |
DS_INCLUDE_DEV_DEPENDENCIES |
gemnasium |
"true" |
"false"로 설정하면 개발 의존성과 그 취약점이 보고되지 않습니다. Composer, Maven, npm, pnpm, Pipenv 또는 Poetry를 사용하는 프로젝트만 지원됩니다. |
GOOS |
gemnasium |
"linux" |
Go 코드를 컴파일할 대상 운영 체제입니다. |
GOARCH |
gemnasium |
"amd64" |
Go 코드를 컴파일할 대상 프로세서의 아키텍처입니다. |
GOFLAGS |
gemnasium |
go build 도구에 전달되는 플래그입니다. |
|
GOPRIVATE |
gemnasium |
소스에서 직접 가져올 glob 패턴과 접두사의 목록입니다. 자세한 내용은 Go 프라이빗 모듈 문서를 참고합니다. | |
DS_JAVA_VERSION |
gemnasium-maven |
17 |
Java 버전입니다. 사용 가능한 버전: 8, 11, 17, 21. |
MAVEN_CLI_OPTS |
gemnasium-maven |
"-DskipTests --batch-mode" |
분석기가 maven에 전달하는 명령줄 인수의 목록입니다. 프라이빗 리포지터리 사용 예시를 참고합니다. |
GRADLE_CLI_OPTS |
gemnasium-maven |
분석기가 gradle에 전달하는 명령줄 인수의 목록입니다. |
|
GRADLE_PLUGIN_INIT_PATH |
gemnasium-maven |
"gemnasium-init.gradle" |
Gradle 초기화 스크립트의 경로를 지정합니다. 호환성을 위해 초기화 스크립트에 allprojects { apply plugin: 'project-report' }가 포함되어야 합니다. |
DS_GRADLE_RESOLUTION_POLICY |
gemnasium-maven |
"failed" |
Gradle 의존성 해석의 엄격도를 제어합니다. 부분 결과를 허용하려면 "none"을, 의존성 해석에 하나라도 실패하면 스캔을 실패 처리하려면 "failed"를 지정합니다. |
SBT_CLI_OPTS |
gemnasium-maven |
분석기가 sbt에 전달하는 명령줄 인수의 목록입니다. |
|
PIP_INDEX_URL |
gemnasium-python |
https://pypi.org/simple |
Python Package Index의 기본 URL입니다. |
PIP_EXTRA_INDEX_URL |
gemnasium-python |
PIP_INDEX_URL 외에 사용할 패키지 인덱스의 추가 URL 배열입니다. 쉼표로 구분합니다. Warning: 이 환경 변수를 사용할 때는 다음 보안 고려 사항을 읽어 봅니다. |
|
PIP_REQUIREMENTS_FILE |
gemnasium-python |
스캔할 Pip requirements 파일입니다. 경로가 아니라 파일 이름입니다. 이 환경 변수를 설정하면 지정한 파일만 스캔됩니다. | |
PIPENV_PYPI_MIRROR |
gemnasium-python |
설정하면 Pipenv가 사용하는 PyPi 인덱스를 미러로 재정의합니다. | |
DS_PIP_VERSION |
gemnasium-python |
특정 pip 버전(예: "19.3")의 설치를 강제합니다. 설정하지 않으면 Docker 이미지에 설치된 pip를 사용합니다. |
|
DS_PIP_DEPENDENCY_PATH |
gemnasium-python |
Python pip 의존성을 불러올 경로입니다. |
기타 변수#
앞의 표는 사용할 수 있는 모든 변수를 망라한 목록이 아닙니다. 이 표에는 지원되고 테스트된 GitLab 및 분석기 고유 변수가 모두 들어 있습니다. 환경 변수 같은 다른 많은 변수도 전달해서 올바르게 동작하게 할 수 있습니다. 이 목록은 방대하며 모두 문서화되어 있지는 않습니다.
예를 들어 GitLab 변수가 아닌 환경 변수 HTTPS_PROXY를 모든 의존성 스캔 job에 전달하려면
다음과 같이 .gitlab-ci.yml의 CI/CD 변수로
설정합니다.
variables:
HTTPS_PROXY: "https://squid-proxy:3128"
Gradle 프로젝트에서 프록시를 사용하려면 추가 변수를 설정해야 합니다.
또는 의존성 스캔 같은 특정 job에서만 사용할 수도 있습니다.
dependency_scanning:
variables:
HTTPS_PROXY: $HTTPS_PROXY
모든 변수를 테스트한 것은 아니므로 일부는 동작하고 일부는 동작하지 않을 수 있습니다. 동작하지 않는 변수가 필요하면 기능 요청을 제출하거나 해당 변수를 사용할 수 있도록 코드에 기여할 수 있습니다.
사용자 지정 TLS 인증 기관#
의존성 스캔에서는 분석기 컨테이너 이미지에 기본으로 포함된 인증서 대신 SSL/TLS 연결에 사용자 지정 TLS 인증서를 사용할 수 있습니다.
사용자 지정 인증 기관 지원은 다음 버전에서 도입되었습니다.
사용자 지정 TLS 인증 기관 사용#
사전 요구 사항:
- 프로젝트의 Maintainer 또는 Owner 권한.
사용자 지정 TLS 인증 기관을 사용하려면 다음을 수행합니다.
- X.509 PEM 공개 키 인증서의 텍스트 표현을
CI/CD 변수
ADDITIONAL_CA_CERT_BUNDLE에 할당합니다.
예를 들어 .gitlab-ci.yml 파일에서 인증서를 구성하려면 다음과 같이 합니다.
variables:
ADDITIONAL_CA_CERT_BUNDLE: |
-----BEGIN CERTIFICATE-----
MIIGqTCCBJGgAwIBAgIQI7AVxxVwg2kch4d56XNdDjANBgkqhkiG9w0BAQsFADCB
...
jWgmPqF3vUbZE0EyScetPJquRFRKIesyJuBFMAs=
-----END CERTIFICATE-----
프라이빗 Maven 리포지터리로 인증#
의존성 분석기가 프라이빗 Maven 리포지터리로 인증할 수 있게 하려면 CI/CD 파이프라인에서 자격 증명을 구성해야 합니다. 인증하지 않으면 의존성 분석기가 프라이빗 의존성에 접근할 수 없어 스캔이 실패합니다.
자격 증명을 .gitlab-ci.yml 파일에 추가하지 않습니다.
사전 요구 사항:
- 프로젝트의 Maintainer 또는 Owner 권한.
의존성 분석기가 프라이빗 Maven 리포지터리로 인증할 수 있게 하려면 다음을 수행합니다.
-
MAVEN_CLI_OPTS라는 이름의 프로젝트 CI/CD 변수를 생성하고 값에 자격 증명이 포함되도록 설정합니다.예를 들어 설정 파일 이름이
mysettings.xml, 사용자 이름이myuser, 비밀번호가verysecret이라면MAVEN_CLI_OPTSCI/CD 변수를 다음과 같이 설정합니다.--settings mysettings.xml -Drepository.password=verysecret -Drepository.user=myuser -
서버 구성이 담긴
mysettings.xmlMaven 설정 파일을 생성합니다. 파일 이름은 1단계에서--settings옵션에 지정한 값과 일치해야 합니다.<!-- mysettings.xml --> <settings> ... <servers> <server> <id>private_server</id> <username>${repository.user}</username> <password>${repository.password}</password> </server> </servers> </settings>
FIPS 지원 이미지#
GitLab은 Gemnasium 이미지의 FIPS 지원 Red Hat UBI
버전도 제공합니다. GitLab 인스턴스에서 FIPS 모드가 사용 설정되면 Gemnasium
스캔 job은 FIPS 지원 이미지를 자동으로 사용합니다. FIPS 지원 이미지로 직접 전환하려면
변수 DS_IMAGE_SUFFIX를 "-fips"로 설정합니다.
FIPS 모드에서는 Gradle 프로젝트의 의존성 스캔과 Yarn 프로젝트의 자동 해결이 지원되지 않습니다.
FIPS 지원 이미지는 RedHat의 UBI micro를 기반으로 합니다.
이 이미지에는 dnf나 microdnf 같은 패키지 관리자가 없으므로
런타임에 시스템 패키지를 설치할 수 없습니다.
오프라인 환경#
인터넷을 통한 외부 리소스 접근이 제한적이거나 차단되었거나 간헐적인 환경의 인스턴스에서는 의존성 스캔 job이 성공적으로 실행되도록 일부 조정이 필요합니다. 자세한 내용은 오프라인 환경을 참고합니다.
사전 요구 사항:
- 관리자 접근 권한.
docker또는kubernetesexecutor를 사용하는 GitLab Runner- 의존성 스캔 분석기 이미지의 로컬 사본
- GitLab 어드바이저리 데이터베이스에 대한 접근
- 패키지 메타데이터 데이터베이스에 대한 접근
분석기 이미지의 로컬 사본#
모든 지원되는 언어 및 프레임워크에서 의존성 스캔을 사용하려면 다음을 수행합니다.
-
registry.gitlab.com의 다음 기본 의존성 스캔 분석기 이미지를 로컬 Docker 컨테이너 레지스트리로 가져옵니다.registry.gitlab.com/security-products/gemnasium:6 registry.gitlab.com/security-products/gemnasium:6-fips registry.gitlab.com/security-products/gemnasium-maven:6 registry.gitlab.com/security-products/gemnasium-maven:6-fips registry.gitlab.com/security-products/gemnasium-python:6 registry.gitlab.com/security-products/gemnasium-python:6-fipsDocker 이미지를 로컬 오프라인 Docker 레지스트리로 가져오는 절차는 네트워크 보안 정책에 따라 다릅니다. 외부 리소스를 가져오거나 일시적으로 접근할 수 있는 허용되고 승인된 절차를 IT 담당자와 상의합니다. 이 스캐너는 새 정의로 주기적으로 업데이트되므로 정기적으로 내려받는 것이 좋을 수 있습니다.
-
로컬 분석기를 사용하도록 GitLab CI/CD를 구성합니다.
CI/CD 변수
SECURE_ANALYZERS_PREFIX의 값을 로컬 Docker 레지스트리로 설정합니다. 이 예시에서는docker-registry.example.com입니다.include: - template: Jobs/Dependency-Scanning.gitlab-ci.yml variables: SECURE_ANALYZERS_PREFIX: "docker-registry.example.com/analyzers"
GitLab 어드바이저리 데이터베이스 접근#
GitLab 어드바이저리 데이터베이스는
gemnasium, gemnasium-maven, gemnasium-python 분석기가 사용하는 취약점 데이터의
원천입니다. 이 분석기의 Docker 이미지에는 데이터베이스의 클론이 포함되어 있습니다.
분석기가 최신 취약점 데이터를 사용하도록 스캔을 시작하기 전에
클론이 데이터베이스와 동기화됩니다.
오프라인 환경에서는 GitLab 어드바이저리 데이터베이스의 기본 호스트에 접근할 수 없습니다. 대신 GitLab 러너가 접근할 수 있는 곳에 데이터베이스를 호스팅해야 합니다. 또한 원하는 일정에 따라 데이터베이스를 직접 업데이트해야 합니다.
데이터베이스를 호스팅하는 방법은 다음과 같습니다.
GitLab 어드바이저리 데이터베이스의 클론 사용#
GitLab 어드바이저리 데이터베이스의 클론을 사용하는 방법이 가장 효율적이므로 권장됩니다.
GitLab 어드바이저리 데이터베이스의 클론을 호스팅하려면 다음을 수행합니다.
- GitLab 러너에서 HTTP로 접근할 수 있는 호스트에 GitLab 어드바이저리 데이터베이스를 클론합니다.
.gitlab-ci.yml파일에서 CI/CD 변수GEMNASIUM_DB_REMOTE_URL의 값을 Git 리포지터리의 URL로 설정합니다.
예를 들면 다음과 같습니다.
variables:
GEMNASIUM_DB_REMOTE_URL: https://users-own-copy.example.com/gemnasium-db.git
GitLab 어드바이저리 데이터베이스의 사본 사용#
GitLab 어드바이저리 데이터베이스의 사본을 사용하려면 분석기가 내려받는 아카이브 파일을 호스팅해야 합니다.
GitLab 어드바이저리 데이터베이스의 사본을 사용하려면 다음을 수행합니다.
-
GitLab 러너에서 HTTP로 접근할 수 있는 호스트에 GitLab 어드바이저리 데이터베이스의 아카이브를 내려받습니다. 아카이브는 다음 위치에 있습니다.
https://gitlab.com/gitlab-org/security-products/gemnasium-db/-/archive/master/gemnasium-db-master.tar.gz. -
.gitlab-ci.yml파일을 업데이트합니다.- 데이터베이스의 로컬 사본을 사용하도록 CI/CD 변수
GEMNASIUM_DB_LOCAL_PATH를 설정합니다. - 데이터베이스 업데이트를 비활성화하도록 CI/CD 변수
GEMNASIUM_DB_UPDATE_DISABLED를 설정합니다. - 스캔이 시작되기 전에 어드바이저리 데이터베이스를 내려받아 압축을 풉니다.
variables: GEMNASIUM_DB_LOCAL_PATH: ./gemnasium-db-local GEMNASIUM_DB_UPDATE_DISABLED: "true" dependency_scanning: before_script: - wget https://local.example.com/gemnasium_db.tar.gz - mkdir -p $GEMNASIUM_DB_LOCAL_PATH - tar -xzvf gemnasium_db.tar.gz --strip-components=1 -C $GEMNASIUM_DB_LOCAL_PATH - 데이터베이스의 로컬 사본을 사용하도록 CI/CD 변수
Gradle 프로젝트에서 프록시 사용#
Gradle 래퍼 스크립트는 HTTP(S)_PROXY 환경 변수를 읽지 않습니다. 자세한 내용은
Gradle 이슈 11065를 참고합니다.
사전 요구 사항:
- 프로젝트의 Maintainer 또는 Owner 권한.
Gradle 래퍼 스크립트가 프록시를 사용하게 하려면 다음을 수행합니다.
-
GRADLE_CLI_OPTSCI/CD 변수로 프록시 옵션을 지정합니다.variables: GRADLE_CLI_OPTS: "-Dhttps.proxyHost=squid-proxy -Dhttps.proxyPort=3128 -Dhttp.proxyHost=squid-proxy -Dhttp.proxyPort=3128 -Dhttp.nonProxyHosts=localhost"
Maven 프로젝트에서 프록시 사용#
Maven은 HTTP(S)_PROXY 환경 변수를 읽지 않습니다. 대신 Maven
설정 파일을 사용해야 합니다.
사전 요구 사항:
- 프로젝트의 Maintainer 또는 Owner 권한.
Maven 의존성 스캐너가 프록시를 사용하도록 구성하려면 다음을 수행합니다.
-
프로젝트의 리포지터리에
mysettings.xml파일을 생성합니다. 그 파일에서 Maven 프록시 설정을 구성합니다.프록시 구성을 지정하는 방법은 Maven 문서를 참고합니다.
-
프로젝트의
.gitlab-ci.yml파일에서MAVEN_CLI_OPTSCI/CD 변수를 정의해 설정 파일mysettings.xml을 참조하게 합니다.variables: MAVEN_CLI_OPTS: "--settings mysettings.xml"
언어 및 패키지 관리자별 설정#
특정 언어와 패키지 관리자를 구성하는 방법은 다음 절을 참고합니다.
Python (pip)#
분석기를 실행하기 전에 Python 패키지를 설치해야 하면 스캔 job의 before_script에서 pip install --user를 사용해야 합니다. --user 플래그를 사용하면 프로젝트 의존성이 사용자 디렉터리에 설치됩니다. --user 옵션을 전달하지 않으면 패키지가 전역으로 설치되어 스캔되지 않으며 프로젝트 의존성을 나열할 때도 표시되지 않습니다.
Python (setuptools)#
분석기를 실행하기 전에 Python 패키지를 설치해야 하면 스캔 job의 before_script에서 python setup.py install --user를 사용해야 합니다. --user 플래그를 사용하면 프로젝트 의존성이 사용자 디렉터리에 설치됩니다. --user 옵션을 전달하지 않으면 패키지가 전역으로 설치되어 스캔되지 않으며 프로젝트 의존성을 나열할 때도 표시되지 않습니다.
프라이빗 PyPi 리포지터리에 자체 서명 인증서를 사용하는 경우 (앞의 .gitlab-ci.yml 템플릿 외에는)
추가 job 구성이 필요하지 않습니다. 다만 setup.py가 프라이빗 리포지터리에 도달할 수 있도록
업데이트해야 합니다. 구성 예시는 다음과 같습니다.
-
install_requires목록의 각 의존성에 대해 프라이빗 리포지터리를 가리키는dependency_links속성을 만들도록setup.py를 업데이트합니다.install_requires=['pyparsing>=2.0.3'], dependency_links=['https://pypi.example.com/simple/pyparsing'], -
리포지터리 URL에서 인증서를 가져와 프로젝트에 추가합니다.
printf "\n" | openssl s_client -connect pypi.example.com:443 -servername pypi.example.com | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > internal.crt -
setup.py가 새로 내려받은 인증서를 가리키게 합니다.import setuptools.ssl_support setuptools.ssl_support.cert_paths = ['internal.crt']
Python (Pipenv)#
네트워크 연결이 제한된 환경에서 실행하는 경우 PIPENV_PYPI_MIRROR 변수를 구성해
프라이빗 PyPi 미러를 사용해야 합니다. 이 미러에는 기본 의존성과 개발 의존성이 모두 있어야 합니다.
variables:
PIPENV_PYPI_MIRROR: https://pypi.example.com/simple
또는 프라이빗 레지스트리를 사용할 수 없으면 필요한 패키지를
Pipenv 가상 환경 캐시에 불러올 수 있습니다. 이 방법을 쓰려면 프로젝트가
Pipfile.lock을 리포지터리에 커밋해야 하며, 기본 패키지와 개발 패키지를 모두 캐시에 불러와야 합니다.
이를 구현하는 방법은 예시 python-pipenv
프로젝트를 참고합니다.
의존성 탐지#
의존성 스캔은 리포지터리에서 사용하는 언어를 자동으로 감지합니다. 감지된 언어와 일치하는
모든 분석기가 실행됩니다. 일반적으로 분석기 선택을 사용자 지정할 필요는 없습니다.
분석기를 지정하지 않으면 전체 선택을 자동으로 사용해 최상의 적용 범위를 확보하고,
더 이상 사용되지 않거나 제거될 때 조정할 필요도 없습니다.
다만 변수 DS_EXCLUDED_ANALYZERS를 사용해 선택을 재정의할 수 있습니다.
언어 감지는 CI job rules에 의존해
지원되는 의존성 파일을 감지합니다.
Java와 Python에서는 지원되는 의존성 파일이 감지되면 의존성 스캔이 프로젝트를 빌드하고 일부 Java 또는 Python 명령을 실행해 의존성 목록을 가져오려 시도합니다. 그 밖의 모든 프로젝트에서는 프로젝트를 먼저 빌드하지 않고도 잠금 파일을 파싱해 의존성 목록을 얻습니다.
모든 직접 의존성과 전이 의존성이 분석되며, 전이 의존성의 깊이에는 제한이 없습니다.
분석기#
의존성 스캔은 다음 공식 Gemnasium 기반 분석기를 지원합니다.
gemnasiumgemnasium-mavengemnasium-python
분석기는 Docker 이미지로 게시되며, 의존성 스캔은 이 이미지를 사용해 분석마다 전용 컨테이너를 시작합니다. 사용자 지정 보안 스캐너를 통합할 수도 있습니다.
각 분석기는 Gemnasium의 새 버전이 릴리스될 때마다 업데이트됩니다.
분석기가 의존성 정보를 얻는 방법#
GitLab 분석기는 다음 두 가지 방법 중 하나로 의존성 정보를 얻습니다.
잠금 파일을 파싱해 의존성 정보 얻기#
다음 패키지 관리자는 GitLab 분석기가 직접 파싱할 수 있는 잠금 파일을 사용합니다.
| 패키지 관리자 | 지원되는 파일 형식 버전 | 테스트된 패키지 관리자 버전 |
|---|---|---|
| Bundler | 해당 없음 | 1.17.3, 2.1.4 |
| Composer | 해당 없음 | 1.x |
| Conan | 0.4 | 1.x |
| Go | 해당 없음 | 1.x |
| NuGet | v1, v2 | 4.9 |
| npm | v1, v2, v3 | 6.x, 7.x, 9.x |
| pnpm | v5, v6, v9 | 7.x, 8.x 9.x |
| yarn | 버전 1, 2, 3, 41 | 1.x, 2.x, 3.x |
| Poetry | v1 | 1.x |
| uv | v0.x | 0.x |
Footnotes:
-
Yarn Berry에서는 다음 기능이 지원되지 않습니다.
- 워크스페이스
yarn patch
패치, 워크스페이스 또는 둘 다 포함한 Yarn 파일도 여전히 처리되지만 이 기능은 무시됩니다.
패키지 관리자를 실행해 파싱 가능한 파일을 생성하여 의존성 정보 얻기#
다음 패키지 관리자를 지원하기 위해 GitLab 분석기는 두 단계로 진행합니다.
- 패키지 관리자 또는 특정 태스크를 실행해 의존성 정보를 내보냅니다.
- 내보낸 의존성 정보를 파싱합니다.
| 패키지 관리자 | 사전 설치된 버전 | 테스트된 버전 |
|---|---|---|
| sbt | 1.6.2 | 1.1.6, 1.2.8, 1.3.12, 1.4.6, 1.5.8, 1.6.2, 1.7.3, 1.8.3, 1.9.6, 1.9.7 |
| maven | 3.9.8 | 3.9.81 |
| Gradle | 6.7.1, 7.6.4, 8.82 | 5.6, 6.7, 6.9, 7.6, 8.8 |
| setuptools | 70.3.0 | >= 70.3.0 |
| pip | 24 | 24 |
| Pipenv | 2023.11.15 | 2023.11.153, 2023.11.15 |
| Go | 1.21 | 1.214 |
Footnotes:
- 이 테스트는
.tool-versions파일에 지정된 maven 기본 버전을 사용합니다. - Java 버전마다 필요한 Gradle 버전이 다릅니다. 앞의 표에 나열된 Gradle 버전은 분석기 이미지에 사전 설치되어 있습니다. 분석기가 사용하는 Gradle 버전은 프로젝트가
gradlew(Gradle 래퍼) 파일을 사용하는지에 따라 달라집니다.-
프로젝트가
gradlew파일을 사용하지 않으면 분석기는DS_JAVA_VERSION변수에 지정된 Java 버전(기본 버전은 17)에 따라 사전 설치된 Gradle 버전 중 하나로 자동 전환합니다.Java 8과 11에서는 Gradle 6.7.1이 자동으로 선택되고, Java 17은 Gradle 7.6.4를, Java 21은 Gradle 8.8을 사용합니다.
-
프로젝트가
gradlew파일을 사용하면 분석기 이미지에 사전 설치된 Gradle 버전은 무시되고gradlew파일에 지정된 버전이 대신 사용됩니다.
-
- 이 테스트는
Pipfile.lock파일이 발견되면 Gemnasium이 이 파일에 나열된 정확한 패키지 버전을 스캔하는 데 사용함을 확인합니다. go build의 구현 방식 때문에 Go 빌드 과정에는 네트워크 접근,go mod download로 미리 불러온 mod 캐시 또는 벤더링된 의존성이 필요합니다. 자세한 내용은 패키지와 의존성 컴파일에 대한 Go 문서를 참고합니다.
분석기가 트리거되는 방식#
GitLab은 리포지터리에 지원되는 파일이 있는지로 감지한 언어에 해당하는 분석기를 시작하기 위해
rules:exists를 사용합니다.
리포지터리 루트에서 최대 두 단계의 디렉터리까지 검색합니다. 예를 들어
리포지터리에 Gemfile, api/Gemfile, api/client/Gemfile 중 하나가 있으면
gemnasium-dependency_scanning job이 활성화되지만, 지원되는 의존성 파일이
api/v1/client/Gemfile뿐이면 활성화되지 않습니다.
여러 파일이 처리되는 방식#
여러 파일을 스캔하는 중에 문제가 발생했다면 이 이슈에 댓글을 남겨 주십시오.
Python#
GitLab은 requirements 파일 또는 잠금 파일이 감지된 디렉터리에서 설치를 한 번만 실행합니다. 의존성은 감지된 첫 번째 파일에 대해서만 gemnasium-python이 분석합니다. 파일은 다음 순서로 검색합니다.
- Pip를 사용하는 프로젝트의
requirements.txt,requirements.pip또는requires.txt. - Pipenv를 사용하는 프로젝트의
Pipfile또는Pipfile.lock. - Poetry를 사용하는 프로젝트의
poetry.lock. - Setuptools를 사용하는 프로젝트의
setup.py.
검색은 루트 디렉터리에서 시작하며, 루트 디렉터리에서 빌드를 찾지 못하면 하위 디렉터리로 이어집니다. 따라서 루트 디렉터리의 Poetry 잠금 파일이 하위 디렉터리의 Pipenv 파일보다 먼저 감지됩니다.
Java 및 Scala#
GitLab은 빌드 파일이 감지된 디렉터리에서 빌드를 한 번만 실행합니다. Gradle, Maven, sbt 빌드를 여러 개 포함하거나 이를 조합한 대규모 프로젝트에서는
gemnasium-maven이 감지된 첫 번째 빌드 파일에 대해서만
의존성을 분석합니다. 빌드 파일은 다음 순서로 검색합니다.
- 단일 또는 멀티 모듈 Maven 프로젝트의
pom.xml. - 단일 또는 멀티 프로젝트 Gradle 빌드의
build.gradle또는build.gradle.kts. - 단일 또는 멀티 프로젝트 sbt 빌드의
build.sbt.
검색은 루트 디렉터리에서 시작하며, 루트 디렉터리에서 빌드를 찾지 못하면 하위 디렉터리로 이어집니다. 따라서 루트 디렉터리의 sbt 빌드 파일이 하위 디렉터리의 Gradle 빌드 파일보다 먼저 감지됩니다. 멀티 모듈 Maven 프로젝트와 멀티 프로젝트 Gradle 및 sbt 빌드에서는 하위 모듈과 하위 프로젝트 파일이 상위 빌드 파일에 선언되어 있으면 분석됩니다.
JavaScript#
다음 분석기가 실행되며, 각 분석기는 여러 파일을 처리할 때 동작이 다릅니다.
-
여러 잠금 파일을 지원합니다.
-
여러 잠금 파일을 지원하지 않습니다. 잠금 파일이 여러 개 있으면
Retire.js는 디렉터리 트리를 알파벳 순서로 순회하며 처음 발견한 잠금 파일을 분석합니다.
gemnasium 분석기는 JavaScript 프로젝트에서 벤더링된 라이브러리
(즉, 프로젝트에 커밋되었지만 패키지 관리자가 관리하지 않는 라이브러리)를 스캔합니다.
Go#
여러 파일이 지원됩니다. go.mod 파일이 감지되면 분석기는 최소 버전 선택(Minimal Version Selection)을 사용해
빌드 목록을 생성하려 시도합니다. 실패하면 분석기는 대신 go.mod 파일 안의 의존성을 파싱하려 시도합니다.
요구 사항으로, 의존성이 올바르게 관리되도록 go.mod 파일을 go mod tidy 명령으로 정리해야 합니다. 이 과정은 감지된 모든 go.mod 파일에 대해 반복됩니다.
PHP, C, C++, .NET, C#, Ruby, JavaScript#
이 언어들의 분석기는 여러 잠금 파일을 지원합니다.
추가 언어 지원#
추가 언어, 의존성 관리자, 의존성 파일에 대한 지원은 다음 이슈에서 추적합니다.
| 패키지 관리자 | 언어 | 지원되는 파일 | 스캔 도구 | 이슈 |
|---|---|---|---|---|
| Poetry | Python | pyproject.toml |
Gemnasium | GitLab#32774 |
경고#
모든 컨테이너는 최신 버전을 사용하고, 모든 패키지 관리자와 언어는 지원되는 최신 버전을 사용합니다. 이전 버전을 사용하면 지원되지 않는 버전이 더 이상 적극적인 보안 보고와 보안 수정의 백포트 혜택을 받지 못할 수 있으므로 보안 위험이 커집니다.
Gradle 프로젝트#
Gradle 프로젝트에서 HTML 의존성 보고서를 생성할 때 reports.html.destination 또는 reports.html.outputLocation 속성을 재정의하지 않습니다. 재정의하면 의존성 스캔이 올바르게 동작하지 않습니다.
Maven 프로젝트#
격리된 네트워크에서 중앙 리포지터리가 프라이빗 레지스트리(<mirror> 지시문으로 명시적으로 설정)인 경우 Maven 빌드가 gemnasium-maven-plugin 의존성을 찾지 못할 수 있습니다. Maven이 기본적으로 로컬 리포지터리(/root/.m2)를 검색하지 않고 중앙 리포지터리에서 가져오려 하기 때문에 발생하는 문제이며, 그 결과 누락된 의존성에 대한 오류가 발생합니다.
해결 방법#
이 문제를 해결하려면 settings.xml 파일에 <pluginRepositories> 섹션을 추가합니다. 그러면 Maven이 로컬 리포지터리에서 플러그인을 찾을 수 있습니다.
시작하기 전에 다음 사항을 고려합니다.
- 이 해결 방법은 기본 Maven 중앙 리포지터리가 프라이빗 레지스트리로 미러링된 환경에만 해당합니다.
- 이 해결 방법을 적용하면 Maven이 로컬 리포지터리에서 플러그인을 검색하며, 일부 환경에서는 보안에 영향을 줄 수 있습니다. 조직의 보안 정책에 부합하는지 확인합니다.
사전 요구 사항:
- 프로젝트의 Maintainer 또는 Owner 권한.
다음 단계에 따라 settings.xml 파일을 수정합니다.
-
Maven
settings.xml파일을 찾습니다. 이 파일은 일반적으로 다음 위치 중 하나에 있습니다.- root 사용자의 경우
/root/.m2/settings.xml. - 일반 사용자의 경우
~/.m2/settings.xml. - 전역 설정의 경우
${maven.home}/conf/settings.xml.
- root 사용자의 경우
-
파일에 기존
<pluginRepositories>섹션이 있는지 확인합니다. -
<pluginRepositories>섹션이 이미 있으면 그 안에 다음<pluginRepository>요소만 추가합니다. 없으면<pluginRepositories>섹션 전체를 추가합니다.<pluginRepositories> <pluginRepository> <id>local2</id> <name>local repository</name> <url>file:///root/.m2/repository/</url> </pluginRepository> </pluginRepositories> -
Maven 빌드 또는 의존성 스캔 과정을 다시 실행합니다.
Python 프로젝트#
PIP_EXTRA_INDEX_URL 환경 변수를 사용할 때는
CVE-2018-20225에 문서화된 악용 가능성 때문에 각별한 주의가 필요합니다.
pip(모든 버전)에서 사용자가 프라이빗 인덱스의 프라이빗 패키지를 받으려 했더라도 가장 높은 버전 번호의 버전을 설치하는
문제가 발견되었습니다. 이 문제는 PIP_EXTRA_INDEX_URL 옵션을 사용할 때만 영향을 주며, 악용하려면
해당 패키지가 공개 인덱스에 아직 존재하지 않아야 합니다(따라서 공격자가 임의의 버전 번호로
그곳에 패키지를 올릴 수 있습니다).
버전 번호 파싱#
경우에 따라 프로젝트 의존성의 버전이 보안 권고의 영향 범위에 속하는지 판단할 수 없습니다.
예를 들면 다음과 같습니다.
- 버전을 알 수 없습니다.
- 버전이 유효하지 않습니다.
- 버전을 파싱하거나 범위와 비교하는 데 실패합니다.
- 버전이
dev-master나1.5.x같은 브랜치입니다. - 비교 대상 버전이 모호합니다. 예를 들어
1.0.0-20241502는1.0.0-2와 비교할 수 없는데, 한 버전은 타임스탬프를 포함하고 다른 버전은 포함하지 않기 때문입니다.
이런 경우 분석기는 해당 의존성을 건너뛰고 로그에 메시지를 출력합니다.
GitLab 분석기는 가정을 하지 않습니다. 가정은 오탐 또는 미탐을 낳을 수 있기 때문입니다. 논의는 이슈 442027을 참고합니다.
Swift 프로젝트 빌드#
Swift Package Manager(SPM)는 Swift 코드의 배포를 관리하는 공식 도구입니다. Swift 빌드 시스템과 통합되어 의존성을 내려받고 컴파일하고 링크하는 과정을 자동화합니다.
SPM으로 Swift 프로젝트를 빌드할 때는 다음 모범 사례를 따릅니다.
-
Package.resolved파일을 포함합니다.Package.resolved파일은 의존성을 특정 버전으로 고정합니다. 환경 간 일관성을 보장하려면 이 파일을 항상 리포지터리에 커밋합니다.git add Package.resolved git commit -m "Add Package.resolved to lock dependencies" -
Swift 프로젝트를 빌드하려면 다음 명령을 사용합니다.
# Update dependencies swift package update # Build the project swift build -
CI/CD를 구성하려면
.gitlab-ci.yml파일에 다음 단계를 추가합니다.swift-build: stage: build script: - swift package update - swift build -
선택 사항. 자체 서명 인증서를 사용하는 프라이빗 Swift 패키지 리포지터리를 사용한다면 프로젝트에 인증서를 추가하고 Swift가 이를 신뢰하도록 구성해야 할 수 있습니다.
-
인증서를 가져옵니다.
echo | openssl s_client -servername your.repo.url -connect your.repo.url:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > repo-cert.crt -
Swift 패키지 매니페스트(
Package.swift)에 다음 줄을 추가합니다.import Foundation #if canImport(Security) import Security #endif extension Package { public static func addCustomCertificate() { guard let certPath = Bundle.module.path(forResource: "repo-cert", ofType: "crt") else { fatalError("Certificate not found") } SecCertificateAddToSystemStore(SecCertificateCreateWithData(nil, try! Data(contentsOf: URL(fileURLWithPath: certPath)) as CFData)!) } } // Call this before defining your package Package.addCustomCertificate()
-
의존성이 올바르게 지정되고 자동으로 해석되도록 빌드 과정은 항상 깨끗한 환경에서 테스트합니다.
CocoaPods 프로젝트 빌드#
CocoaPods는 Swift 및 Objective-C Cocoa 프로젝트에서 널리 쓰이는 의존성 관리자입니다. iOS, macOS, watchOS, tvOS 프로젝트에서 외부 라이브러리를 관리하는 표준 형식을 제공합니다.
의존성 관리에 CocoaPods를 사용하는 프로젝트를 빌드할 때는 다음 모범 사례를 따릅니다.
-
Podfile.lock파일을 포함합니다.Podfile.lock파일은 의존성을 특정 버전으로 고정하는 데 필수적입니다. 환경 간 일관성을 보장하려면 이 파일을 항상 리포지터리에 커밋합니다.git add Podfile.lock git commit -m "Add Podfile.lock to lock CocoaPods dependencies" -
다음 중 하나로 프로젝트를 빌드할 수 있습니다.
-
xcodebuild명령줄 도구:# Install CocoaPods dependencies pod install # Build the project xcodebuild -workspace YourWorkspace.xcworkspace -scheme YourScheme build -
Xcode IDE:
- Xcode에서
.xcworkspace파일을 엽니다. - 대상 스킴을 선택합니다.
- Product > Build를 선택합니다. ⌘+B를 눌러도 됩니다.
- Xcode에서
-
iOS 및 Android 앱의 빌드와 릴리스를 자동화하는 도구인 fastlane:
-
fastlane을 설치합니다.sudo gem install fastlane -
프로젝트에서
fastlane을 구성합니다.fastlane init -
fastfile에 lane을 추가합니다.lane :build do cocoapods gym(scheme: "YourScheme") end -
빌드를 실행합니다.
fastlane build
-
-
프로젝트가 CocoaPods와 Carthage를 모두 사용하면 Carthage로 의존성을 빌드할 수 있습니다.
-
CocoaPods 의존성을 포함하는
Cartfile을 생성합니다. -
다음을 실행합니다.
carthage update --platform iOS
-
-
-
선호하는 방법에 따라 프로젝트를 빌드하도록 CI/CD를 구성합니다.
예를 들어
xcodebuild를 사용하면 다음과 같습니다.cocoapods-build: stage: build script: - pod install - xcodebuild -workspace YourWorkspace.xcworkspace -scheme YourScheme build -
선택 사항. 프라이빗 CocoaPods 리포지터리를 사용한다면 해당 리포지터리에 접근하도록 프로젝트를 구성해야 할 수 있습니다.
-
프라이빗 spec 리포지터리를 추가합니다.
pod repo add REPO_NAME SOURCE_URL -
Podfile에 소스를 지정합니다.
source 'https://github.com/CocoaPods/Specs.git' source 'SOURCE_URL'
-
-
선택 사항. 프라이빗 CocoaPods 리포지터리가 SSL을 사용한다면 SSL 인증서가 올바르게 구성되어 있는지 확인합니다.
-
자체 서명 인증서를 사용한다면 시스템의 신뢰할 수 있는 인증서에 추가합니다.
.netrc파일에 SSL 구성을 지정할 수도 있습니다.machine your.private.repo.url login your_username password your_password
-
-
Podfile을 업데이트한 후
pod install을 실행해 의존성을 설치하고 워크스페이스를 업데이트합니다.
모든 의존성이 올바르게 설치되고 워크스페이스가 업데이트되도록 Podfile을 업데이트한 후에는 항상 pod install을 실행합니다.
취약점 데이터베이스에 기여#
취약점을 찾으려면 GitLab advisory database에서 검색할 수 있습니다.
새 취약점을 제출할 수도 있습니다.