Sec 섹션 개발 지침

Sec 섹션은 GitLab 애플리케이션 보안 기능, DevSecOps의 “Sec” 부분을 담당합니다. Sec 섹션에 구체적으로 관련된 개발 가이드가 여기에 나열되어 있습니다.

공유 용어집에서 공통 용어에 대한 개요를 확인하세요.

구조

개요

안전한 기능을 지원하는 아키텍처는 주로 두 가지 부분으로 나뉩니다:

  • 스캔
  • 처리, 시각화 및 관리
flowchart LR subgraph G1[스캔] 스캐너 분석기 CI[CI 작업] end subgraph G2[처리, 시각화 및 관리] 구문 분석기 데이터베이스 뷰 상호 작용 end G1 --보고서 아티팩트--> G2

스캔

스캔 파트는 주어진 리소스에서 취약점을 찾고 결과를 내보내는 역할을 합니다. 스캔은 분석기라고 불리는 몇 가지 작은 프로젝트를 통해 CI/CD 작업에서 실행되며, 이는 GitLab에 통합하기 위해 내부적으로 또는 외부적으로 개발된 스캐너라는 보안 도구를 래핑한 것입니다. 분석기는 주로 Go로 작성됩니다.

어떤 3rd party 통합자들은 통합 문서에 따라 추가 스캐너를 사용할 수 있으며, 이는 동일한 아키텍처를 활용합니다.

스캔 결과는 안전 보고 형식을 준수해야 하며, 이를 처리 가능하도록하기 위해 CI/CD 작업 보고서 아티팩트로 업로드됩니다.

처리, 시각화 및 관리

데이터가 보고서 아티팩트로 사용 가능하게 되면 GitLab Rails 애플리케이션에서 처리될 수 있어 안전한 기능들을 활성화할 수 있게 됩니다. 이에는 다음이 포함됩니다:

맥락에 따라 보안 보고서는 데이터베이스에 저장될 수도 있고 보고서 아티팩트로 저장될 수도 있습니다.

보안 보고서 수집 개요

스캐너에서 생성된 보고서를 GitLab이 어떻게 처리하는지에 대한 자세한 내용은 보안 보고서 수집 개요를 참조하세요.

CI/CD 템플릿 개발

CI/CD 템플릿은 검증 섹션이 담당하지만, 많은 경우 Sec 섹션의 기능 사용에 중요합니다. CI/CD 템플릿을 사용하는 경우, GitLab CI/CD 템플릿 개발 가이드를 읽어보세요.

주요 식별자의 중요성

분석기 JSON 보고서 내의 identifiers 필드에는 취약성을 설명하는 데 사용될 수 있는 유형 및 범주의 컬렉션이 포함되어 있습니다 (즉, CWE 패밀리).

identifiers 컬렉션의 첫 번째 항목은 주요 식별자로, 취약성을 설명하고 추적하는 데 중요한 컴포넌트입니다.

대부분의 경우, identifiers 컬렉션은 순서가 없으며 나머지 보조 식별자들은 취약점을 그룹화하기 위한 메타데이터로 작용합니다 (예외 사항은 하단의 분석기 취약점 번역을 참조).

주요 식별자가 변경되고 프로젝트 파이프라인이 다시 실행되면 새 보고서의 수용이 이전의 DB 레코드를 “고아” 상태로 만듭니다. 이는 우리의 처리 논리가 두 가지 다른 취약점의 델타를 생성하는 데 의존하기 때문에 매우 혼란스러울 수 있습니다. 예를 들어:

Merge Request 위젯에서의 주요 식별자 불일치 스크린샷

Merge된 후 이전 취약점은 “해결됨”으로 표시되고 새로 발견된 취약점은 “감지됨”으로 표시됩니다.

주요 식별자 안정성을 보장하기 위한 지침 원칙

  • 강력한 이유가 없는 한 주요 식별자는 변경해서는 안 됩니다.
  • 취약점 번역을 지원하는 분석기는 “고아” 결과를 방지하기 위해 이전 주요 식별자를 보조 위치에 포함해야 합니다.
  • 주요 식별자 이외의 보조 식별자의 순서는 중요하지 않습니다.
  • 식별자는 TypeValue 필드의 조합에 기반하여 고유합니다 (참조: 식별자 지문).
  • 주요 식별자를 변경하면 이전 버전의 분석기를 되돌린다 해도 이전에 데이터베이스에 섭취된 데이터는 고아의 결과입니다. 데이터 이주를 자동화하는 방법이 몇 가지 없으며 이전 결과가 고아가 됩니다.

분석기 취약점 번역

SAST Semgrep 분석기의 경우, 특정 중요한 보조 식별자가 있습니다: 보고서의 취약성을 이전 분석기 (즉, bandit 또는 ESLint)에 연결하는 식별자입니다.

취약점 번역을 활성화하기 위해 Semgrep 분석기는 이전 분석기의 주요 식별자와 정확히 일치하는 보조 식별자에 의존합니다.

예를 들어, 이전에 eslint를 사용하여 취약점 레코드를 생성한 경우, semgrep 분석기는 원래 ESLint 주요 식별자를 포함하는 식별자 컬렉션을 생성해야 합니다.

원래 eslint 보고서:

{
  "version": "14.0.4",
  "vulnerabilities": [
    {
      "identifiers": [
        {
          "type": "eslint_rule_id",
          "name": "ESLint rule ID security/detect-eval-with-expression",
          "value": "security/detect-eval-with-expression"
        }
      ]
    }
  ]
}

해당 Semgrep 보고서는 eslint_rule_id를 포함해야 합니다:

{
  "version": "14.0.4",
  "vulnerabilities": [
    {
      "identifiers": [
        {
          "type": "semgrep_id",
          "name": "eslint.detect-eval-with-expression",
          "value": "eslint.detect-eval-with-expression",
          "url": "https://semgrep.dev/r/gitlab.eslint.detect-eval-with-expression"
        },
        {
          "type": "eslint_rule_id",
          "name": "ESLint rule ID security/detect-eval-with-expression",
          "value": "security/detect-eval-with-expression"
        }
      ]
    }
  ]
}

취약점 추적은 이 두 식별자의 조합을 통해 이전 분석기로 생성된 DB 레코드를 새로운 semgrep으로 생성된 레코드로 다시 매핑하는 데 의존합니다.