CodeQL CLI 사용

완료됨

명령줄 인터페이스를 통해서도 GitHub.com의 그래픽 사용자 인터페이스와 동일한 여러 주요 CodeQL 기능에 액세스할 수 있습니다.

이 단원에서는 CodeQL CLI를 사용하여 데이터베이스를 만들고, 데이터베이스를 분석하고, 결과를 GitHub에 업로드하는 방법을 알아봅니다.

CodeQL CLI 명령

CI 시스템의 서버에서 CodeQL CLI를 사용할 수 있도록 설정하고 GitHub에서 인증되는지 확인했다면 데이터를 생성할 준비가 된 것입니다.

다음과 같은 세 가지 명령을 사용하여 결과를 생성하고 GitHub에 업로드할 수 있습니다.

  • database create - CodeQL 데이터베이스를 만들어 리포지토리에서 지원되는 각 프로그래밍 언어의 계층 구조를 나타냅니다.
  • database analyze - 쿼리를 실행하여 각 CodeQL 데이터베이스를 분석하고 결과를 SARIF 파일로 요약합니다.
  • github upload-results - 결과가 분기 또는 끌어오기 요청과 일치하고 코드 검사 경고로 표시되는 경우 결과 SARIF 파일을 GitHub에 업로드합니다.

--help option을 사용하여 명령에 대한 명령줄 도움말을 표시할 수 있습니다.

GitHub에 코드 검사 결과로 표시할 SARIF 데이터를 업로드하는 작업은 GitHub Advanced Security가 활성화된 조직 소유의 리포지토리와 GitHub.com의 퍼블릭 리포지토리에서 지원됩니다.

분석할 CodeQL 데이터베이스 만들기

다음 단계에 따라 분석할 CodeQL 데이터베이스를 만듭니다.

  1. 분석하려는 코드를 체크 아웃합니다.
    • 분기의 경우 분석하려는 분기의 헤드를 체크 아웃합니다.
    • 풀 리퀘스트의 경우, 풀 리퀘스트의 헤드 커밋을 체크아웃하거나 GitHub에서 생성한 풀 리퀘스트의 병합 커밋을 체크아웃하세요.
  2. 모든 종속성을 사용할 수 있도록 코드베이스에 대한 환경을 설정합니다.
  3. 코드베이스에 대한 빌드 명령(있는 경우)을 찾습니다. 일반적으로 이 명령은 CI 시스템의 구성 파일에서 사용할 수 있습니다.
  4. 리포지토리의 체크 아웃 루트에서 codeql database create을 실행하고 코드베이스를 빌드합니다.
    • 지원되는 단일 언어에 대해 하나의 CodeQL 데이터베이스를 만들려면 다음 명령을 사용합니다.

      codeql database create <database> --command <build> --language=<language-identifier>
      
    • 지원되는 여러 언어에 대해 언어당 하나의 CodeQL 데이터베이스를 만들려면 다음 명령을 사용합니다.

      codeql database create <database> --command <build> \
        --db-cluster --language=<language-identifier>,<language-identifier>
      

참고

컨테이너화된 빌드를 사용하는 경우 빌드 작업이 수행되는 컨테이너 내에서 CodeQL CLI를 실행해야 합니다.

아래 표에는 database create 명령의 전체 매개 변수 목록이 나와 있습니다.

옵션 필수 사용량
<database> CodeQL 데이터베이스에 대해 만들 디렉터리의 이름과 위치를 지정합니다. 기존 디렉터리를 덮어쓰려고 하면 명령이 실패합니다. --db-cluster도 지정하면 이것이 부모 디렉터리가 되고 분석되는 각 언어에 대해 하위 디렉터리가 생성됩니다.
--language 언어에 대한 식별자를 지정하여 cpp, csharp, go, java, javascript, python, ruby 중 하나에 대한 데이터베이스를 만듭니다. (JavaScript를 사용하여 TypeScript 코드를 분석하세요.) --db-cluster와 함께 사용할 경우 옵션은 쉼표로 구분된 목록을 허용하거나 두 번 이상 지정할 수 있습니다.
--command 권장됩니다. 코드베이스에 대한 빌드 프로세스를 호출하는 빌드 명령 또는 스크립트를 지정하는 데 사용합니다. 명령은 현재 폴더 또는 정의된 --source-root위치에서 실행됩니다. Python 및 JavaScript/TypeScript 분석에는 필요하지 않습니다.
--db-cluster 선택 사항입니다. 다국어 코드베이스에서 --language에 의해 지정된 각 언어에 대해 하나의 데이터베이스를 생성하는 데 사용합니다.
--no-run-unnecessary-builds 권장됩니다. CodeQL CLI가 빌드를 모니터링할 필요가 없는 언어(예: Python 및 JavaScript/TypeScript)에 대한 빌드 명령을 표시하지 않는 데 사용합니다.
--source-root 선택 사항입니다. 리포지토리의 체크 아웃 루트 외부에서 CLI를 실행하는 경우 사용합니다. database create 명령은 기본적으로 현재 디렉터리가 원본 파일의 루트 디렉터리라고 가정합니다. 다른 위치를 지정하려면 이 옵션을 사용합니다.

단일 언어 예제

이 예제에서는 /checkouts/example-repo에서 체크 아웃된 리포지토리에 대한 CodeQL 데이터베이스를 만듭니다. JavaScript 추출기를 사용하여 리포지토리에 JavaScript 및 TypeScript 코드의 계층적 표현을 만듭니다. 결과 데이터베이스는 /codeql-dbs/example-repo에 저장됩니다.

$ codeql database create /codeql-dbs/example-repo --language=javascript \
    --source-root /checkouts/example-repo

> Initializing database at /codeql-dbs/example-repo.
> Running command [/codeql-home/codeql/javascript/tools/autobuild.cmd]
    in /checkouts/example-repo.
> [build-stdout] Single-threaded extraction.
> [build-stdout] Extracting
...
> Finalizing database at /codeql-dbs/example-repo.
> Successfully created database at /codeql-dbs/example-repo.

여러 언어 예제

이 예제에서는 /checkouts/example-repo-multi에서 체크 아웃된 리포지토리에 대한 두 개의 CodeQL 데이터베이스를 만듭니다. 이는 다음을 사용합니다.

  • --db-cluster - 두 개 이상 언어의 분석을 요청합니다.
  • --language - 데이터베이스를 만들 언어를 지정합니다.
  • --command - 코드베이스에 대한 빌드 명령을 도구에 알립니다(여기서는 make).
  • --no-run-unnecessary-builds 필요하지 않은 언어(예: Python)에 대한 빌드 명령을 건너뛰도록 도구에 지시합니다.

결과 데이터베이스는 pythoncpp/codeql-dbs/example-repo-multi 하위 디렉터리에 저장됩니다.

$ codeql database create /codeql-dbs/example-repo-multi \
    --db-cluster --language python,cpp \
    --command make --no-run-unnecessary-builds \
    --source-root /checkouts/example-repo-multi
Initializing databases at /codeql-dbs/example-repo-multi.
Running build command: [make]
[build-stdout] Calling python3 /codeql-bundle/codeql/python/tools/get_venv_lib.py
[build-stdout] Calling python3 -S /codeql-bundle/codeql/python/tools/python_tracer.py -v -z all -c /codeql-dbs/example-repo-multi/python/working/trap_cache -p ERROR: 'pip' not installed.
[build-stdout] /usr/local/lib/python3.6/dist-packages -R /checkouts/example-repo-multi
[build-stdout] [INFO] Python version 3.6.9
[build-stdout] [INFO] Python extractor version 5.16
[build-stdout] [INFO] [2] Extracted file /checkouts/example-repo-multi/hello.py in 5ms
[build-stdout] [INFO] Processed 1 modules in 0.15s
[build-stdout] <output from calling 'make' to build the C/C++ code>
Finalizing databases at /codeql-dbs/example-repo-multi.
Successfully created databases at /codeql-dbs/example-repo-multi.
$

CodeQL 데이터베이스 분석

CodeQL 데이터베이스를 만든 후에 다음 단계에 따라 데이터베이스를 분석합니다.

  1. 필요에 따라 codeql pack download <packs>를 실행하여 분석 중에 실행하려는 CodeQL 팩(베타)을 다운로드합니다.
  2. codeql database analyze을(를) 데이터베이스에서 실행하고, 사용할 팩 및/또는 쿼리를 지정하세요.
codeql database analyze <database> --format=<format> \
    --output=<output>  <packs,queries>

참고

단일 커밋에 대해 둘 이상의 CodeQL 데이터베이스를 분석하는 경우에는 이 명령에서 생성되는 각 결과 집합에 대해 SARIF 범주를 지정해야 합니다. 결과를 GitHub에 업로드하면 코드 검사는 이 범주를 사용하여 각 언어에 대한 결과를 개별적으로 저장합니다. 이 작업을 수행하지 않으면 각 업로드가 이전 결과를 덮어씁니다.

codeql database analyze <database> --format=<format> \
    --sarif-category=<language-specifier> --output=<output> \
    <packs,queries>

아래 표에는 database analyze 명령의 전체 매개 변수 목록이 나와 있습니다.

옵션 필수 사용량
<database> 분석할 CodeQL 데이터베이스가 포함된 디렉터리의 경로를 지정합니다.
<packs,queries> 실행할 CodeQL 팩 또는 쿼리를 지정합니다. 코드 검사에 사용되는 표준 쿼리를 실행하려면 이 매개 변수를 생략합니다. CodeQL CLI 번들에 포함된 다른 쿼리 도구 모음은 /<extraction-root>/codeql/qlpacks/codeql-<language>/codeql-suites에서 확인할 수 있습니다. 자체 쿼리 도구 모음을 만드는 방법을 알아보려면 CodeQL CLI 설명서의 CodeQL 쿼리 도구 모음 만들기[5]를 참조하세요.
--format 명령에서 생성된 결과 파일의 형식을 지정합니다. GitHub에 업로드하려는 경우에는 값이 sarif-latest여야 합니다.
--output SARIF 결과 파일을 저장할 위치를 지정합니다.
--sarif-category 단일 데이터베이스 분석의 경우 선택 사항입니다. 리포지토리에서 단일 커밋에 대해 여러 데이터베이스를 분석하는 경우 언어를 정의하는 데 필요합니다. 이 분석을 위해 SARIF 결과 파일에 포함할 범주를 지정합니다. 범주는 다양한 언어 또는 다양한 코드 부분에서 수행되지만 동일한 도구와 커밋을 대상으로 하는 여러 분석을 구분하는 데 사용됩니다.
--sarif-add-query-help 선택 사항입니다. 분석에 사용되는 사용자 지정 쿼리에 사용 가능한 markdown 렌더링 쿼리 도움말을 포함하려는 경우 사용합니다. SARIF 출력에 포함된 사용자 지정 쿼리의 쿼리 도움말은 관련 쿼리가 경고를 생성하는 경우 코드 검사 UI에 표시됩니다.
<packs> 선택 사항입니다. CodeQL 쿼리 팩을 다운로드했으며 팩에 지정된 기본 쿼리 또는 쿼리 도구 모음을 실행하려는 경우 사용합니다.
--threads 선택 사항입니다. 둘 이상의 스레드를 사용하여 쿼리를 실행하려는 경우 사용합니다. 기본값은 1입니다. 더 많은 스레드를 지정하여 쿼리 실행 속도를 높일 수 있습니다. 스레드 수를 논리 프로세서 수로 설정하려면 0을 지정합니다.
--verbose 선택 사항입니다. 데이터베이스 생성 프로세스에서 분석 프로세스 및 진단 데이터에 관한 더 자세한 정보를 가져오는 데 사용합니다.

기본 예제

이 예제에서는 /codeql-dbs/example-repo에 저장된 CodeQL 데이터베이스를 분석하고 결과를 SARIF 파일 /temp/example-repo-js.sarif로 저장합니다. --sarif-category를 사용하여 결과를 JavaScript로 식별하는 SARIF 파일에 추가 정보를 포함합니다. 이는 리포지토리에서 단일 커밋에 대해 분석할 CodeQL 데이터베이스가 둘 이상 있는 경우에 필수적입니다.

$ codeql database analyze /codeql-dbs/example-repo  \
    javascript-code-scanning.qls --sarif-category=javascript
    --format=sarif-latest --output=/temp/example-repo-js.sarif

> Running queries.
> Compiling query plan for /codeql-home/codeql/qlpacks/
    codeql-javascript/AngularJS/DisablingSce.ql.
...
> Shutting down query evaluator.
> Interpreting results.

GitHub에 결과 업로드

SARIF 업로드는 업로드당 최대 25,000개의 결과를 지원합니다. 그러나 상위 5,000개의 결과만 표시되고 심각도에 따라 우선 순위가 지정됩니다. 도구에서 너무 많은 결과를 생성하는 경우 가장 중요한 규칙 또는 쿼리의 결과에 초점을 맞추도록 구성을 업데이트해야 합니다.

각 업로드에 대해 SARIF 업로드는 최대 10MB 크기의 gzip 압축 SARIF 파일을 지원합니다. 이 한도를 초과하는 모든 업로드는 거부됩니다. SARIF 파일이 너무 많은 결과를 포함해서 너무 큰 경우 가장 중요한 규칙 또는 쿼리의 결과에 초점을 맞추도록 구성을 업데이트해야 합니다. 제한 사항 및 SARIF 파일 유효성 검사에 대한 자세한 내용은 설명서[6]를 참조하세요.

결과를 GitHub에 업로드하려면 먼저 이전에 만든 GitHub 앱 또는 개인용 액세스 토큰을 CodeQL CLI에 전달하는 가장 좋은 방법을 결정해야 합니다. 비밀 저장소의 안전한 사용에 관한 CI 시스템 참고 자료를 검토하는 것이 좋습니다. CodeQL CLI는 다음을 지원합니다.

  • --github-auth-stdin 옵션을 사용하여 비밀 저장소와 상호 작용합니다. 인증할 때 이 방법을 사용하는 것이 좋습니다.
  • 환경 변수 GITHUB_TOKEN에 비밀을 저장하고 --github-auth-stdin 옵션을 포함하지 않고 CLI 실행.
  • --github-auth-stdin 명령줄 옵션을 전달하고 표준 입력을 통해 임시 토큰을 제공합니다. 테스트 용도로 사용하는 것이 좋습니다.

CI 서버를 위한 가장 안전하고 신뢰할 수 있는 방법을 정했으면 각 SARIF 결과 파일에 대해 codeql github upload-results를 실행하고, 환경 변수 --github-auth-stdin에 토큰이 있지 않다면 GITHUB_TOKEN을 포함합니다.

# GitHub App or personal access token available from a secret store
<call-to-retrieve-secret> | codeql github upload-results \
    --repository=<repository-name> \
    --ref=<ref> --commit=<commit> \
    --sarif=<file> --github-auth-stdin

# GitHub App or personal access token available in GITHUB_TOKEN
codeql github upload-results \
    --repository=<repository-name> \
    --ref=<ref> --commit=<commit> \
    --sarif=<file> 

명령에 대한 github upload-results 매개 변수의 전체 목록은 다음과 같이 표에 나와 있습니다.

옵션 필수 사용량
--repository 데이터를 업로드할 리포지토리의 소유자/이름을 지정합니다. 소유자는 GitHub Advanced Security 라이선스를 보유한 엔터프라이즈의 소속 조직이어야 하고, 퍼블릭 리포지토리가 아니라면 리포지토리에 대해 GitHub Advanced Security를 활성화해야 합니다.
--ref 결과가 올바른 코드와 일치될 수 있도록 체크 아웃하고 분석한 참조의 이름을 지정합니다. 분기에는 refs/heads/BRANCH-NAME을, 끌어오기 요청의 헤드 커밋에는 refs/pulls/NUMBER/head를, 끌어오기 요청의 GitHub 생성 병합 커밋에는 refs/pulls/NUMBER/merge를 사용합니다.
--commit 분석한 커밋의 전체 SHA를 지정합니다.
--sarif 로드할 SARIF 파일을 지정합니다.
--github-auth-stdin 선택 사항입니다. 표준 입력을 통해 GitHub REST API를 사용하여 인증용으로 만든 GitHub 앱 또는 개인용 액세스 토큰을 CLI에 전달하는 데 사용합니다. 해당 명령이 이 토큰으로 설정된 GITHUB_TOKEN 환경 변수에 액세스할 수 있는 경우, 이것은 필요하지 않습니다.