본문으로 건너뛰기
개발 머꼬
개발 노트GitHub Actions
hohyeon.dev21

Self-hosted runner를 fork PR에 그대로 열어뒀다가 생긴 보안 문제

  • #CI/CD
  • #Engineering Note
  • #GitHub Actions
  • #Security

문제 발생

빌드 속도를 높이려고 사내 서버에 self-hosted runner를 설치해 오픈소스 저장소에 연결했는데, 외부 기여자가 만든 Pull Request의 워크플로우가 그 러너에서 실행되면서 내부 네트워크에 접근 가능한 임의 명령을 실행할 수 있는 상황이 만들어졌습니다.

원인 분석

GitHub이 제공하는 호스팅 러너(ubuntu-latest 등)는 매 워크플로우 실행마다 완전히 새로 프로비저닝된 격리 환경입니다 — 실행이 끝나면 그 가상 머신은 통째로 폐기됩니다. Self-hosted runner는 반대로 여러분이 직접 관리하는 지속적인 머신입니다. 매 실행 후 자동으로 초기화되지 않으며(별도로 그렇게 구성하지 않는 한), 그 머신이 접근할 수 있는 네트워크, 파일, 자격 증명에 워크플로우가 그대로 접근할 수 있습니다.

퍼블릭 저장소에서 pull_request 트리거로 self-hosted runner를 쓰면, 누구나 PR을 열어서 그 워크플로우 파일에 원하는 명령을 추가한 뒤 실행시킬 수 있습니다 — GitHub 공식 문서가 이를 명시적으로 강하게 경고하는 이유입니다. fork에서 온 PR은 신뢰할 수 없는 코드로 취급해야 합니다.

해결 방안

  1. 퍼블릭 저장소에서는 fork PR에 self-hosted runner를 노출하지 않습니다. GitHub 공식 문서도 "Public repositories에서 self-hosted runner를 쓰지 말 것"을 강하게 권고합니다 — 꼭 필요하다면 pull_request_target처럼 신중한 검토가 필요한 이벤트로 제한하고, 실행 전 코드 내용을 사람이 직접 확인하는 절차를 둡니다.
  2. Self-hosted runner는 가능하면 프라이빗 저장소나, 신뢰할 수 있는 내부 기여자만 코드를 push할 수 있는 저장소에서만 씁니다.
  3. 러너를 매 job마다 초기화되는 임시 환경(컨테이너, 매번 새로 만들고 버리는 VM 등)으로 구성해, 이전 실행의 상태(자격 증명 캐시, 남은 파일)가 다음 실행에 영향을 주지 않도록 합니다.
  4. 러너가 접근 가능한 네트워크 범위를 최소한으로 제한합니다(방화벽, 별도 네트워크 분리) — 워크플로우가 예상 밖의 명령을 실행하더라도 피해 범위를 줄일 수 있습니다.
  5. 러너에 필요한 최소한의 권한만 있는 자격 증명을 두고, 프로덕션 인프라에 직접 접근 가능한 강한 권한은 별도의 더 엄격하게 통제되는 배포 경로로 분리합니다.

공식 문서

마지막 수정

좋아요북마크

댓글0

아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.