GitHub 캐시 중독

모든 게시물

CI 내부에서 무슨 일이 일어나는지 알고 있나요? 깊은 이해가 없으면 혁신적인 공급망 공격에 취약할 수 있습니다. 이 문서에서는 이러한 공격에 대해 설명합니다.

캐싱은 프로세스 속도를 높이는 데 사용됩니다. 패키지를 계속해서 빌드하거나 다운로드하는 대신 재사용을 위해 간단하고 자동으로 아티팩트를 보관합니다. 그러나 캐시가 중독될 수 있습니다. 예를 들어 테스트 작업 흐름에 사용되는 악성 도구는 캐시를 손상시킬 수 있습니다. 나중에 동일한 캐시를 사용하는 다른 워크플로가 영향을 받을 수 있습니다. 이 워크플로에 더 높은 권한이 있는 경우 이는 실제로 공격을 전환하는 방법입니다. 이 게시물에서는 GitHub CI 파이프라인에 대한 실험적 공격에 대해 보고하지만 다른 CI 제품에도 유사한 논리적 취약점이 존재합니다.

공격은 다음과 같이 진행됩니다. 

  1. 공격자는 Github의 의심하지 않는 작업 흐름에 의해 포착된 악성 도구 또는 Github 작업을 게시합니다.
  2. 워크플로는 캐시로 설계되었습니다.
  3. 악성 페이로드는 악성 데이터를 포함하도록 캐시를 수정합니다.
  4. 이 시점부터 이 캐시를 호출하는 다른 워크플로가 영향을 받을 수 있습니다.

우리의 공개에 대해 GitHub는 이러한 유형의 공격에 대비해 캐시 기능을 강화할 계획이 없다고 말했습니다. 

캐시의 콘텐츠 해시 값을 암호화 방식으로 서명하고 사용하기 전에 서명을 확인하여 완화할 것을 제안합니다. 공격과 완화에 대해 자세히 알아보려면 계속해서 읽어보세요.

캐시 중독 공격

GitHub 캐시

한 실행에서 다른 실행으로 동일한 출력이나 다운로드된 종속성을 재사용하는 경우가 많습니다. (예를 들어 Maven, Gradle, npm 및 Yarn과 같은 패키지 및 종속성 관리 도구로 다운로드한 패키지입니다. 이러한 패키지는 일반적으로 다운로드된 종속성의 로컬 캐시에 보관됩니다.).

CI 실행을 최적화하기 위해 GitHub는 API를 통해 파이프라인 전체에서 사용할 수 있는 캐시 리소스에 대한 액세스 권한을 부여합니다. 캐시의 항목은 키-값 조합으로, 키는 문자열 기반이고 값은 캐시하려는 파일 또는 디렉터리입니다.

사용법 - 작업/캐시 CI의 어느 위치에서든 Git 작업은 두 단계로 실행됩니다. 운영 호출될 때 처리되고 다른 하나는 사후에 발생합니다. 워크플로우 (실행 작업이 캐시 누락을 반환한 경우)

  • 작업 실행 – 캐시를 검색하고 검색하는 데 사용됩니다. 검색은 캐시 키를 사용하여 수행되며 결과는 캐시 적중(성공, 캐시에서 데이터 발견) 또는 캐시 누락입니다. 발견된 경우 해당 파일과 디렉터리는 활성 사용을 위해 캐시에서 검색됩니다. 결과가 캐시 누락이면 원하는 파일과 디렉터리가 처음 호출된 것처럼 다운로드됩니다.
  • 포스트 워크플로 작업 – 캐시를 저장하는 데 사용됩니다. 실행 작업의 캐시 호출 결과가 캐시 누락을 반환하는 경우 이 작업은 제공된 키를 사용하여 캐시하려는 디렉터리의 현재 상태를 저장합니다. 이 작업은 자동으로 발생하며 명시적으로 호출할 필요가 없습니다.

GitHub 캐시 권한

액세스 제한은 다음을 제공합니다. 캐시 격리 서로 다른 지점 사이에 논리적 경계를 만들어 보안을 강화합니다. (예: 브랜치를 위해 생성된 캐시 기능-A [기본 기본] 브랜치에 대한 풀 요청에 액세스할 수 없습니다. 기능-B [베이스 메인이란]).

캐시 작업은 먼저 키에 대한 캐시 적중을 검색하고 해당 키가 포함된 분기의 키를 복원합니다. 워크플로 실행. 현재 분기에 적중 항목이 없으면 캐시 작업은 키를 검색하고 상위 분기 및 업스트림 분기에서 키를 복원합니다.

캐시에 대한 액세스 범위는 분기(현재 및 상위)별로 지정됩니다. 즉, 모든 캐시에 대한 액세스가 제공됩니다. 워크 플로우 가로질러 실행 해당 지점의.

또 다른 중요한 참고 사항은 GitHub에서 항목이 푸시되면 수정을 허용하지 않는다는 것입니다. 캐시 항목은 읽기 전용 레코드입니다.

GitHub CI 범위 지정

GitHub의 범위 다양한 작업에 필요한 액세스 유형을 정확하게 지정할 수 있습니다. GitHub의 CI는 다양한 방식으로 범위가 지정되며 각각 고유한 값과 기능 세트가 있습니다.

  • 각 작업에 대한 가상 머신(VM)
  • 작업 권한
  • 워크플로 범위
  • 워크플로 실행
  • Git 브랜치
  • 워크플로 ID 토큰
  • 다른 사람

GitHub 캐시 범위는 다른 범위 제한 중 일부를 깨뜨릴 수 있는 방식으로 정의되었습니다. (예: GitHub 캐시는 여러 워크플로에 영향을 미칠 수 있습니다).

공격

두 가지 워크플로가 포함된 예시 CI를 사용했습니다. 이 예에서는 공격이 낮은 권한 워크플로에서 높은 권한 워크플로로 어떻게 전환될 수 있는지 보여줍니다.

  • 단위 테스트 단위 테스트 및 코드 적용 도구를 실행하는 워크플로입니다. 우리는 도구 중 하나가 악성이거나 원격 코드 실행에 취약하다고 가정합니다. 워크플로에서는 다음을 사용해야 합니다. 작업/캐시 Git 액션. 모든 워크플로가 캐시에 액세스할 수 있습니다.
  • 해제 워크플로는 애플리케이션 아티팩트를 빌드하고 릴리스합니다. 이 워크플로는 캐시를 사용하여 Golang 종속성을 사용하여 최적화합니다.

XNUMXD덴탈의 단위 테스트 워크플로는 Golang 로깅 라이브러리를 변경하여 악성 콘텐츠가 포함된 캐시 항목을 추가하는 악의적인 작업을 사용합니다. (go.uber.org/zap@v1) 애플리케이션 아티팩트 설명에 'BAD library' 문자열을 추가합니다.

다음으로 공개 워크플로는 이 중독된 캐시 항목을 사용합니다. 결과적으로 구축된 Golang 바이너리와 이미지에 악성코드가 주입됩니다. 캐시는 항목 키가 삭제될 때까지(보통 종속성 업데이트에 의해 트리거됨) 오염된 상태로 유지됩니다. 동일한 중독 캐시가 다른 캐시에 영향을 미칩니다. 워크플로우, 운영하위 지점 동일한 캐시 키를 사용합니다.

우리가 수행한 테스트에서는 이미지 설명에 'BAD library'라는 문자열을 삽입하는 데 성공했습니다.

나쁜 라이브러리

이것은 버전 0.4.1이었습니다. 다음으로 태그를 업데이트하고 이미지를 여러 번 다시 빌드한 결과 설명에 '잘못된 라이브러리'가 남아 있는 것을 관찰했습니다.

GitHub 공개

우리의 공개에 대한 Github의 반응은 Git 액션,  작업/캐시 예상대로 작동하며 캐시 범위를 강화할 계획이 없습니다.
GitHub 팀은 이 동작에 문제가 있다고 생각하지 않지만 DevSecOps 실무자에게 이 공격 벡터에 주의할 것을 권고합니다.

완화

  1. 릴리스 또는 중요한 워크플로우에서는 캐시를 사용하지 마십시오.
  2. 신뢰할 수 있는 워크플로를 먼저 실행하여 워크플로를 순차적으로 실행하여 캐시가 신뢰할 수 있는 워크플로에서 생성되었는지 확인하세요.
  3. 종속성 벤더링 – GoLang의 벤더링은 Go 프로젝트에 사용되는 모든 타사 패키지가 해당 애플리케이션을 개발하는 모든 사람에게 일관되도록 보장하는 방법입니다. 이렇게 하면 캐시된 종속성이 프로젝트의 모든 분기에 대해 유효한 상태로 유지됩니다. 다른 언어에서는 이 방법을 지원하지 않을 수 있습니다.
  4. 캐시 값을 암호화하여 서명하고 사용하기 전에 서명을 확인하십시오.
    Scribe는 캐시와 같은 작업 흐름의 개체나 디렉터리에 세부적으로 서명하여 이러한 공격을 완화합니다. 릴리스 전에 Scribe를 사용하여 신뢰할 수 있는 워크플로에서 생성된 캐시만 릴리스 빌드에 사용되었는지 확인할 수 있습니다.

요약 

이 게시물에서는 DevSecOps 팀의 눈에 보이지 않는 CI 워크플로의 캐시 중독 공격에 대해 설명하고 완화 방법에 대해 논의했습니다.

이 콘텐츠는 소프트웨어 공급망 전반에 걸쳐 코드 아티팩트와 코드 개발 및 전달 프로세스에 최첨단 보안을 제공하는 선도적인 엔드투엔드 소프트웨어 공급망 보안 솔루션 제공업체인 Scribe Security에서 제공합니다. 자세히 알아보기.