# CodeQL 쿼리 도구 모음 만들기

CodeQL 분석에서 자주 사용하는 쿼리를 위한 쿼리 모음을 만들 수 있습니다.

> \[!NOTE]
> 이 문서에서는 CodeQL CLI 2.25.6 번들에서 사용할 수 있는 기능을 GitHub Enterprise Server 3.22의 초기 릴리스에 포함되어 있습니다.
>
> 사이트 관리자가 CodeQL CLI 버전을 최신 릴리스로 업데이트한 경우 최신 기능에 대한 자세한 내용은 이 문서의 [GitHub Enterprise Cloud 버전](/ko/enterprise-cloud@latest/code-security/tutorials/customize-code-scanning/create-query-suites)을 참조하세요.

분석에서 자주 사용하려는 쿼리에 대한 쿼리 그룹을 만들 수 CodeQL 있습니다. 자세한 내용은 [CodeQL 쿼리 도구 모음](/ko/enterprise-server@3.22/code-security/concepts/code-scanning/codeql/codeql-query-suites)을(를) 참조하세요.

> \[!NOTE]
> 쿼리 도구 모음에 추가하려는 모든 사용자 지정 쿼리는 팩에 [CodeQL](/ko/enterprise-server@3.22/code-security/tutorials/customize-code-scanning/customize-analysis) 있어야 하며 올바른 쿼리 메타데이터를 포함해야 합니다. 자세한 내용은 [CodeQL CLI에 대한 사용자 지정 쿼리 작성](/ko/enterprise-server@3.22/code-security/how-tos/find-and-fix-code-vulnerabilities/scan-from-the-command-line/write-custom-queries)을(를) 참조하세요.

## 쿼리 도구 모음에 추가할 쿼리 찾기

쿼리 도구 모음을 만들 때 먼저 선택하려는 쿼리의 위치를 지정해야 합니다. 다음을 사용하여 하나 이상의 쿼리 위치를 정의할 수 있습니다:

* `query` 명령: 지정된 CodeQL 파일을 하나 이상 찾도록 지시합니다`.ql`.

  ```yaml
  - query: <path-to-query>
  ```

  인수는 제품군 정의를 포함하는 CodeQL 팩에 상대적인 하나 이상의 파일 경로여야 합니다.

* `queries` 지침: CodeQL에게 디렉터리에서 `.ql` 파일을 재귀적으로 검색하도록 지시합니다:

  ```yaml
  - queries: <path-to-subdirectory>
  ```

  디렉터리의 경로는 제품군 정의 파일을 포함하는 팩의 CodeQL 루트를 기준으로 해야 합니다. 다른 CodeQL 팩을 기준으로 쿼리를 찾으려면 다음 필드를 추가 `from` 합니다.

  ```yaml
  - queries: <path-to-subdirectory>
    from: <ql-pack-name>
    version: ^x.y.z
  ```

`version` 필드는 선택 사항이며 이 CodeQL 팩의 호환되는 버전 범위를 지정합니다.
버전을 지정하지 않으면 팩의 최신 버전이 사용됩니다.

* `qlpack` 지침: CodeQL에게 지정된 CodeQL 팩의 기본 제품군에서 쿼리를 해결하도록 지시합니다.

  ```yaml
  - qlpack: <qlpack-name>
    version: ^x.y.z
  ```

  쿼리 팩의 기본 도구 모음에는 해당 쿼리 팩 내부의 권장 쿼리 집합이 포함됩니다. 모든 쿼리 팩에 기본 도구 모음이 있는 것은 아닙니다. 지정된 쿼리 팩이 기본 도구 모음을 정의하지 않으면, qlpack 명령은 팩 내의 모든 쿼리로 확인됩니다.

`version` 필드는 선택 사항이며 이 CodeQL 팩의 호환되는 버전 범위를 지정합니다.
버전을 지정하지 않으면 팩의 최신 버전이 사용됩니다.

> \[!NOTE]
> 쿼리 도구 모음 정의에 경로 이름이 나타날 때는 디렉터리 구분 기호로 슬래시, `/`, 을(를) 항상 사용해야 합니다. 이를 통해 쿼리 도구 모음 정의가 모든 운영 체제에서 작동합니다.

도구 모음 정의에는 `query`, `queries` 또는 `qlpack` 명령을 최소 1개 추가해야 하며, 그렇지 않으면 어떤 쿼리도 선택되지 않습니다. 제품군에 추가 지침이 없는 경우 파일 목록, 지정된 디렉터리 또는 명명 CodeQL 된 팩에서 찾은 모든 쿼리가 선택됩니다. 추가 필터링 명령이 있으면, 해당 명령이 부과하는 제약 조건과 일치하는 쿼리만 선택됩니다.

## 쿼리 도구 모음에서 쿼리 필터링

`query`, `queries` 또는 `qlpack` 명령을 지정하여 도구 모음에 추가할 초기 쿼리 집합을 정의한 후에는 `include` 및 `exclude` 명령을 추가할 수 있습니다. 이러한 명령은 특정 속성을 기반으로 선택 기준을 정의합니다:

* 쿼리 집합에 대해 `include` 명령을 실행하면, 조건과 일치하는 모든 쿼리가 선택이 유지되고 일치하지 않는 쿼리는 제거됩니다.
* 쿼리 집합에 대해 `exclude` 명령을 실행하면, 조건과 일치하는 모든 쿼리가 선택에서 제거되고 일치하지 않는 쿼리는 유지됩니다.

필터 명령의 순서는 중요합니다. 위치 지정 명령 다음에 나타나는 첫 번째 필터 명령은, 기본적으로 쿼리가 포함되는지 제외되는지를 결정합니다. 첫 번째 필터가 `include`(이)면, 처음 찾은 쿼리는 명시적인 `include` 필터와 일치하는 경우에만 도구 모음에 포함됩니다. 첫 번째 필터가 `exclude`(이)면, 처음 찾은 쿼리는 명시적으로 제외되지 않는 한 도구 모음에 포함됩니다.

후속 지침은 순서대로 실행되며 파일의 뒷부분에 표시되는 지침이 이전 지침보다 우선합니다. 따라서 `include` 명령은 동일한 쿼리와 일치하는 이후의 `exclude` 명령에 의해 재정의될 수 있습니다. 마찬가지로 `exclude`도 이후의 `include`에 의해 재정의될 수 있습니다.

두 명령 모두에서 인수는 제약 조건 블록입니다. 즉, 제약 조건을 나타내는 YAML 맵입니다. 각 제약 조건은 맵 항목이며, 키는 일반적으로 쿼리 메타데이터 속성입니다. 값은 다음 중 하나일 수 있습니다:

* 단일 문자열.
* `/`(으)로 둘러싸인 [정규식](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/regex/Pattern.html).
* 문자열, 정규식 또는 둘 다를 포함하는 목록.

제약 조건과 일치하려면 메타데이터 값이 문자열 또는 정규식 중 하나와 일치해야 합니다. 메타데이터 키가 둘 이상이면 각 키가 모두 일치해야 합니다.
일치에 사용할 수 있는 표준 메타데이터 키는 다음과 같습니다: `description`, `id`, `kind`, `name`, `tags`, `precision` 및 `problem.severity`.
쿼리 메타데이터 속성에 대한 자세한 내용은 [쿼리에 대한 메타데이터를 CodeQL 참조하세요](https://codeql.github.com/docs/writing-codeql-queries/metadata-for-codeql-queries/#metadata-for-codeql-queries).

메타데이터 태그 외에도 제약 조건 블록의 키는 다음과 같을 수 있습니다:

* `query filename`: 쿼리 파일 이름의 마지막 경로 구성 요소와 일치합니다.
* `query path`: CodeQL 팩을 기준으로 쿼리 파일의 경로와 일치하는 항목을 찾습니다.
* `tags contain`: 지정된 일치 문자열 중 하나가 `@tags` 메타데이터 속성 값의 공백으로 구분된 구성 요소 중 하나와 일치해야 합니다.
* `tags contain all`: 지정된 일치 문자열 각각이 `@tags` 메타데이터 속성의 구성 요소 중 하나와 일치해야 합니다.

### 어떤 쿼리가 실행되는지 필터링하는 예시

일반적인 사용 사례는 사용자가 실행하지 않으려는 몇 가지 CodeQL 특정 쿼리를 제외하고 팩의 모든 쿼리를 실행하는 쿼리 그룹을 만드는 것입니다. 일반적으로 각 쿼리에 대해 고유하고 안정적인 식별자인 쿼리 `id`을(를) 기준으로 필터링하는 것을 권장합니다. 다음 세 가지 쿼리 도구 모음 정의는 의미적으로 동일하며 쿼리 `id`(으)로 필터링합니다:

이 필터는 제외된 식별자가 있는 두 개의 쿼리를 제외하고, `codeql/cpp-queries`의 기본 도구 모음에 있는 모든 쿼리와 일치합니다:

```yaml
- qlpack: codeql/cpp-queries
- exclude:
    id:
      - cpp/cleartext-transmission
      - cpp/cleartext-storage-file
```

이 예제에서는 각 쿼리에 대해 별도의 `exclude` 명령이 사용됩니다:

```yaml
- qlpack: codeql/cpp-queries
- exclude:
    id: cpp/cleartext-transmission
- exclude:
    id: cpp/cleartext-storage-file
```

이 예제에서는 정규식을 사용하여 동일한 두 쿼리를 제외합니다. 또한 식별자가 다음으로 시작하는, 이후에 도구 모음에 추가되는 모든 쿼리도 제외합니다: `cpp/cleartext-`:

```yaml
- qlpack: codeql/cpp-queries
- exclude:
    id:
      - /^cpp\/cleartext-.*/
```

팩의 `codeql/cpp-queries`CodeQL 기본 제품군에서 모든 쿼리를 선택한 다음 보안 쿼리만 포함하도록 구체화하는 제품군을 정의하려면 다음을 사용합니다.

```yaml
- qlpack: codeql/cpp-queries
- include:
    tags contain: security
```

`@kind problem` 디렉터리에서 `@precision high` 및 `my-custom-queries`이(가) 있는 모든 쿼리를 선택하는 도구 모음을 정의하려면 다음을 사용하세요:

```yaml
- queries: my-custom-queries
- include:
    kind: problem
    precision: very-high
```

다음 쿼리 도구 모음 정의는 위 정의와 다르게 동작합니다. 이 정의는 `@kind problem`*또는*`@precision very-high`인 쿼리를 선택합니다:

```yaml
- queries: my-custom-queries
- include:
    kind: problem
- include:
    precision: very-high
```

`@kind problem` 디렉터리에서 `my-custom-queries`이(가) 있는 모든 쿼리를 선택하되 `@problem.severity
recommendation`이(가) 있는 쿼리는 제외하는 도구 모음을 만들려면 다음을 사용하세요:

```yaml
- queries: my-custom-queries
- include:
    kind: problem
- exclude:
    problem.severity: recommendation
```

`@tag security`
`@precision high` 팩에서 `very-high` 및 `codeql/cpp-queries` 또는 CodeQL가 있는 모든 쿼리를 선택하는 스위트를 만들려면 다음을 사용하세요.

```yaml
- queries: .
  from: codeql/cpp-queries
- include:
    tags contain: security
    precision:
    - high
    - very-high
```

> \[!NOTE]
> `codeql resolve queries /path/to/suite.qls` 명령을 사용하여 쿼리 도구 모음 정의에서 어떤 쿼리가 선택되는지 확인할 수 있습니다. 자세한 내용은 [쿼리 해결](/ko/enterprise-server@3.22/code-security/reference/code-scanning/codeql/codeql-cli-manual/resolve-queries)을(를) 참조하세요.

## 기존 쿼리 도구 모음 정의 재사용

다음을 지정하여 기존 쿼리 도구 모음 정의를 재사용할 수 있습니다:

* `import` 명령: 이전에 정의된 `.qls` 파일이 선택한 쿼리를 현재 도구 모음에 추가합니다:

  ```yaml
  - import: <path-to-query-suite>
  ```

  가져온 CodeQL 스위트의 경로는 현재 스위트 정의를 포함하는 팩에 대해 상대 경로여야 합니다. 가져온 쿼리 도구 모음이 다른 QL 팩에 있는 경우 다음을 사용할 수 있습니다:

  ```yaml
  - import: <path-to-query-suite>
    from: <ql-pack>
    version: ^x.y.z
  ```

`version` 필드는 선택 사항이며 이 CodeQL 팩의 호환되는 버전 범위를 지정합니다.
버전을 지정하지 않으면 팩의 최신 버전이 사용됩니다.

`import` 명령을 사용하여 추가된 쿼리는 이후의 `exclude` 명령을 사용하여 필터링할 수 있습니다.

* `apply` 명령: 이전에 정의된 `.qls` 파일의 모든 명령을 현재 도구 모음에 추가합니다. 적용된 `.qls` 파일의 명령은 `apply` 위치에 나타나는 것처럼 실행됩니다.
  적용된 도구 모음의 `include` 및 `exclude` 명령은, 더 앞선 명령으로 추가된 쿼리에도 적용됩니다:

  ```yaml
  - apply: <path-to-query-suite>
  ```

`apply` 명령은 `.yml` 파일에 저장된 재사용 가능한 조건 집합을 여러 쿼리 정의에 적용하는 데에도 사용할 수 있습니다. 자세한 내용은 아래의 [예제](#reusability-examples)를 참조하세요.

### 재사용 예제

여러 쿼리 도구 모음 정의에서 동일한 조건을 사용하려면, 명령을 포함하는 별도의 `.yml` 파일을 만드세요. 예를 들어 다음 내용을 `reusable-instructions.yml`(이)라는 파일에 저장하세요:

```yaml
- include:
    kind:
    - problem
    - path-problem
    tags contain: security
    precision:
    - high
    - very-high
```

`reusable-instructions.yml`을 현재 쿼리 제품군과 동일한 CodeQL 팩에 추가합니다. 그런 다음 하나 이상의 쿼리 도구 모음에서 `apply` 명령을 사용하여 재사용 가능한 명령을 현재 도구 모음에 적용하세요. 다음은 그 예입니다.

```yaml
- queries: queries/cpp/custom
- apply: reusable-instructions.yml
```

그러면 `queries/cpp/custom`의 쿼리가 재사용 가능한 조건과 일치하는 항목만 포함하도록 필터링됩니다.

다른 `reusable-instructions.yml` 팩의 쿼리에서 CodeQL를 사용하여 제품군 정의를 만들 수도 있습니다.
`.qls` 파일이 쿼리와 같은 CodeQL 팩에 있는 경우, `from` 명령어 바로 뒤에 `apply` 필드를 추가할 수 있습니다.

```yaml
# load queries from the default suite of my-org/my-other-custom-queries
- qlpack: my-org/my-other-custom-queries

# apply the reusable instructions from the my-org/my-custom-instructions CodeQL pack
- apply: reusable-instructions.yml
  from: my-org/my-custom-instructions
  version: ^1.2.3 # optional
```

`import` 명령의 일반적인 사용 사례는 다른 쿼리 도구 모음의 쿼리에 추가 필터를 적용하는 것입니다. 예를 들어 이 도구 모음은 `cpp-security-and-quality` 도구 모음을 추가로 필터링하고 `low` 및 `medium` 정확도 쿼리를 제외합니다:

```yaml
- import: codeql-suites/cpp-security-and-quality.qls
  from: codeql/cpp-queries
- exclude:
    precision:
      - low
      - medium
```

다른 도구 모음에서 가져온 쿼리를 `include`하려면, 구문이 약간 다릅니다:

```yaml
- import: codeql-suites/cpp-security-and-quality.qls
  from: codeql/cpp-queries
- exclude: {}
- include:
    precision:
      - very-high
      - high
```

비어 있는 `exclude` 명령에 주목하세요. 이는 이후의 `include` 명령이 가져온 도구 모음의 쿼리를 필터링할 수 있도록 하기 위해 필요합니다.

## 쿼리 도구 모음 이름 지정

`description` 명령을 지정하여 쿼리 도구 모음에 이름을 제공할 수 있습니다:

```yaml
- description: <name-of-query-suite>
```

## 쿼리 도구 모음 저장

쿼리 모음을 `.qls` 확장자를 가진 파일에 저장하고 CodeQL에 추가합니다
팩. 자세한 내용은 [CodeQL 팩을 사용하여 분석 사용자 지정](/ko/enterprise-server@3.22/code-security/tutorials/customize-code-scanning/customize-analysis)을(를) 참조하세요.

## CodeQL를 사용하는 쿼리 스위트

`.qls` 파일을 받는 모든 명령에 대해 명령줄에서 쿼리 도구 모음을 지정할 수 있습니다. 예를 들어 `query compile`을(를) 사용하여 도구 모음 정의로 선택된 쿼리를 컴파일하거나, `database analyze`을(를) 사용하여 분석에서 쿼리를 사용할 수 있습니다. 데이터베이스 분석에 대한 자세한 내용은 CodeQL을 [](/ko/enterprise-server@3.22/code-security/tutorials/customize-code-scanning/analyze-code) 참조하세요.

## 추가 읽기

* [
  CodeQL 쿼리](https://codeql.github.com/docs/writing-codeql-queries/codeql-queries/#codeql-queries)