flawopen.com/GitHub Actions 보안/Workflow 스크립트 인젝션
GitHub Actions 스크립트 인젝션은 어떻게 발생하고 예방할까요?
Bash가 시작되기 전에 issue 제목이나 pull request 필드를 스크립트에 넣으면 데이터가 shell 문법으로 바뀔 수 있습니다. 이름을 지시로 오해하는 명찰 프린터와 같습니다. 환경 변수로 값을 전달하고 데이터로 쓸 때 확장을 따옴표로 감싸면 Bash는 스크립트와 분리된 값으로 받습니다. 영향은 토큰, 비밀값, runner, 이벤트에 달려 있습니다.
${{ ... }}를 평가합니다. run: 입력이 스크립트 소스에 들어갈 수 있습니다.env:로 전달하면 프로세스 데이터가 됩니다. shell 확장은 인용하고 eval 및 동적 스크립트를 피합니다.근본 원인: shell 분석 전에 데이터가 삽입됨
GitHub는 run 단계의 shell을 시작하기 전에 표현식을 확장합니다. 신뢰할 수 없는 제목을 직접 넣으면 문자가 shell 프로그램을 바꿀 수 있습니다. env: 값은 스크립트 본문과 분리되며 인용하면 일반 명령의 인수로 유지됩니다. 이후 eval, 다른 인터프리터, 인수를 코드로 해석하는 도구에 전달하는 것은 여전히 안전하지 않습니다. GitHub는 이벤트 필드를 공격자가 제어할 수 있는 입력으로 봅니다.
# 위험: 이벤트 데이터가 생성된 shell 스크립트에 포함됨
name: Issue Triage
on:
issues:
types: [opened]
permissions:
contents: read
jobs:
triage:
runs-on: ubuntu-latest
steps:
- name: Print issue title
run: |
printf 'Title: %s\n' "${{ github.event.issue.title }}"
# 더 안전: 이벤트 값을 환경 변수로 전달
name: Issue Triage
on:
issues:
types: [opened]
permissions:
contents: read
jobs:
triage:
runs-on: ubuntu-latest
steps:
- name: Print issue title
env:
ISSUE_TITLE: ${{ github.event.issue.title }}
run: |
printf 'Title: %s\n' "$ISSUE_TITLE"
공격 경로 요약
사용자가 이벤트 필드를 제어
공개 issue나 pull request 제목 또는 브랜치명이 workflow 입력이 될 수 있습니다.
Workflow가 shell 소스에 삽입
run:의 직접적인 ${{ github.event... }}는 Bash가 스크립트를 파싱하기 전에 평가됩니다.
Shell이 바뀐 프로그램을 해석
값이 shell 문법을 바꾸면 job 프로세스 권한으로 명령이 실행될 수 있습니다. 인용된 인수 데이터로 남으면 인젝션은 발생하지 않습니다.
Job 권한이 영향 범위를 결정
침해된 job은 해당 실행에 열린 리소스만 접근합니다. GITHUB_TOKEN 권한, 제공된 비밀값, runner를 확인하고 issue 이벤트와 pull_request_target을 검토하세요.
보안 강화 체크리스트
- ✓신뢰할 수 없는
github.event값을run:에 직접 넣지 않습니다.env:로 전달하고"$ISSUE_TITLE"처럼 인용합니다. - ✓해당 값을
eval, 생성 스크립트, shell 명령 문자열, 인수를 코드나 옵션으로 해석하는 도구에 전달하지 않습니다. - ✓Workflow 또는 job에 제한적인
permissions:를 설정하고 필요한 job에만 쓰기 권한을 줍니다. - ✓
pull_request_target과workflow_run을 권한 경계로 취급합니다. 이 컨텍스트에서 신뢰할 수 없는 PR 코드나 아티팩트를 checkout, build, 실행하지 않습니다. - ✓신뢰할 수 없는 여러 줄 데이터를
GITHUB_ENV나GITHUB_PATH에 쓰지 않습니다.GITHUB_*와RUNNER_*는 보호되지만 다른 값은 후속 단계에 영향을 줄 수 있습니다. - ✓검토한 전체 SHA로 서드파티 action을 고정하고 격리된 일회성 runner를 쓰며 Actions workflow에 CodeQL을 활성화합니다.
1차 자료
- GitHub 문서 — 스크립트 인젝션
- GitHub 문서 — 안전한 사용 참고자료
- GitHub 문서 — pull_request_target 안전하게 사용하기
- GitHub 문서 — workflow 명령과 GITHUB_ENV
- GitHub 문서 — GITHUB_TOKEN 권한