AWS CodeBuild - Untrusted PR Webhook Bypass (CodeBreach-style)
Tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 Discord 그룹 또는 텔레그램 그룹에 참여하거나 Twitter 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
이 공격 벡터는 public-facing PR workflow가 약한 webhook 제어를 가진 privileged CodeBuild project에 연결되어 있을 때 발생합니다.
외부 공격자가 CodeBuild로 하여금 자신의 pull request를 실행하게 만들 수 있다면, 일반적으로 arbitrary code execution inside the build (build scripts, dependency hooks, test scripts 등)을 얻고, 이후 secrets, IAM credentials, 또는 source-provider credentials로 피벗할 수 있습니다.
왜 이것이 위험한가
CodeBuild webhook 필터는 regex 패턴으로 평가됩니다 (non-EVENT 필터의 경우). ACTOR_ACCOUNT_ID 필터에서는 약한 패턴이 의도보다 더 많은 사용자를 매치할 수 있습니다.
신뢰할 수 없는 PR이 권한 있는 AWS role 권한 또는 GitHub 자격증명을 가진 프로젝트에서 빌드되면, 이는 전체 공급망(supply-chain) 침해로 이어질 수 있습니다.
Wiz는 다음과 같은 실전 체인을 보여주었습니다:
- 웹훅 actor allowlist가 unanchored regex를 사용했다.
- 공격자가 신뢰된 ID의 superstring으로 매치되는 GitHub ID를 등록했다.
- 악성 PR이 CodeBuild를 트리거했다.
- 빌드 코드 실행을 이용해 메모리를 덤프하고 source-provider credentials/tokens를 복구했다.
외부 PR 코드 실행을 허용하는 잘못된 구성
다음은 고위험 실수들과 공격자가 각 실수를 악용하는 방식입니다:
EVENTfilters allow untrusted triggers
- 일반적으로 위험한 이벤트:
PULL_REQUEST_CREATED,PULL_REQUEST_UPDATED,PULL_REQUEST_REOPENED. - 권한 있는 빌드에 연결되면 위험해질 수 있는 기타 이벤트:
PUSH,PULL_REQUEST_CLOSED,PULL_REQUEST_MERGED,RELEASED,PRERELEASED,WORKFLOW_JOB_QUEUED. - Bad:
EVENT="PUSH, PULL_REQUEST_CREATED, PULL_REQUEST_UPDATED"(권한 있는 프로젝트에서). - Better: 권한 있는 프로젝트의 경우 PR 코멘트 승인 사용 및 트리거 이벤트 최소화.
- Abuse: 공격자는 자신이 제어하는 브랜치에 대해 PR을 열거나 업데이트하거나 푸시하여 CodeBuild에서 자신의 코드를 실행시킵니다.
ACTOR_ACCOUNT_IDregex is weak
- Bad:
123456|7890123같은 unanchored 패턴. - Better: 정확히 매치하도록 앵커 사용
^(123456|7890123)$. - Abuse: regex의 과도한 매치로 인해 권한 없는 GitHub ID가 allowlist를 통과합니다.
- Other regex filters are weak or missing
HEAD_REF- Bad:
refs/heads/.* - Better:
^refs/heads/main$(또는 명시적 신뢰 목록)
- Bad:
BASE_REF- Bad:
.* - Better:
^refs/heads/main$
- Bad:
FILE_PATH- Bad: 경로 제한 없음
- Better:
^buildspec\\.yml$,^\\.github/workflows/.*,(^|/)package(-lock)?\\.json$와 같이 위험한 파일 제외
COMMIT_MESSAGE- Bad: 느슨한 매치로 신뢰 마커 사용 (예:
trusted) - Better: 커밋 메시지를 PR 실행의 신뢰 경계로 사용하지 않음
- Bad: 느슨한 매치로 신뢰 마커 사용 (예:
REPOSITORY_NAME/ORGANIZATION_NAME- Bad: org/global webhook에
.* - Better: 오직 정확한 repo/org 매치만 허용
- Bad: org/global webhook에
WORKFLOW_NAME- Bad:
.* - Better: 정확한 workflow 이름 매치만 허용 (또는 이를 신뢰 제어로 사용하지 않음)
- Bad:
- Abuse: 공격자는 permissive한 regex를 통과하도록 ref/path/message/repo 컨텍스트를 조작하여 빌드를 트리거합니다.
excludeMatchedPatternis misused
- 이 플래그를 잘못 설정하면 의도한 논리가 반전될 수 있습니다.
- Bad:
FILE_PATH '^buildspec\\.yml$'에 대해 의도는 buildspec 편집을 차단하는 것인데excludeMatchedPattern=false로 설정한 경우. - Better: 같은 패턴에
excludeMatchedPattern=true로 설정하여buildspec.yml을 건드리는 빌드를 거부. - Abuse: 방어자는 위험한 이벤트/경로/액터를 차단한다고 생각하지만 실제로는 허용하고 있을 수 있습니다.
- Multiple
filterGroupscreate accidental bypasses
- CodeBuild는 그룹을 OR로 평가합니다 (하나의 그룹만 통과하면 충분).
- Bad: 엄격한 그룹 하나 + 완화된 폴백 그룹 하나(예:
EVENT=PULL_REQUEST_UPDATED만 있음). - Better: 액터/레퍼런스/경로 제약을 시행하지 않는 폴백 그룹 제거.
- Abuse: 공격자는 가장 약한 그룹만 만족시키면 됩니다.
- Comment approval gate disabled or too permissive
pullRequestBuildPolicy.requiresCommentApproval=DISABLED는 가장 안전하지 않습니다.- 지나치게 넓은 승인자 역할은 통제를 약화시킵니다.
- Bad:
requiresCommentApproval=DISABLED. - Better:
ALL_PULL_REQUESTS또는FORK_PULL_REQUESTS와 최소한의 승인자 역할 사용. - Abuse: 포크/드라이브바이 PR이 신뢰된 유지보수자의 승인 없이 자동 실행됩니다.
- No restrictive branch/path strategy for PR builds
HEAD_REF+BASE_REF+FILE_PATH로 방어층을 구성하지 않음.- Bad:
EVENT+ACTOR_ACCOUNT_ID만 있고 ref/path 제약 없음. - Better: 정확한
ACTOR_ACCOUNT_ID+BASE_REF+HEAD_REF+FILE_PATH제한을 조합. - Abuse: 공격자는 build inputs(buildspec/CI/dependencies 등)을 수정하여 임의의 명령 실행을 얻습니다.
- Public visibility + status URL exposure
- 공개된 빌드/체크 URL은 공격자에게 리컨(recon) 및 반복 테스트 기회를 제공합니다.
- Bad:
projectVisibility=PUBLIC_READ에 민감한 로그/구성이 공개된 경우. - Better: 비즈니스 요구가 강력하지 않다면 프로젝트를 비공개로 유지하고, 로그/아티팩트를 정리(sanitize)합니다.
- Abuse: 공격자는 프로젝트 패턴/동작을 발견하고 페이로드와 우회 시도를 조정합니다.
Token leakage from memory
Wiz의 글은 source-provider credentials가 빌드 런타임 컨텍스트에 존재하며 빌드가 손상된 이후(예: memory dumping을 통해) 탈취될 수 있다는 점을 설명합니다. 권한 범위가 넓다면 이는 리포지토리 takeover로 이어질 수 있습니다.
AWS는 공개 이후 하드닝을 도입했지만, 핵심 교훈은 변하지 않습니다: never execute untrusted PR code in privileged build contexts 그리고 공격자가 제어하는 빌드 코드는 자격증명 탈취를 시도할 것이라고 가정하십시오.
추가적인 CodeBuild 내 자격증명 절취 기법은 다음을 참조하세요:
Finding CodeBuild URLs in GitHub PRs
CodeBuild가 커밋 상태를 GitHub에 리포트하는 경우, CodeBuild 빌드 URL은 보통 다음 위치에 나타납니다:
- PR page -> Checks 탭 (또는 Conversation/Commits의 상태 라인).
- Commit page -> status/checks 섹션 -> Details 링크.
- PR commits list -> 커밋에 붙은 체크 컨텍스트를 클릭.
공개 프로젝트의 경우, 이 링크는 인증되지 않은 사용자에게 빌드 메타데이터/구성을 노출할 수 있습니다.
스크립트: PR에서 CodeBuild URL을 감지하고 공개 여부를 테스트
```bash #!/usr/bin/env bash set -euo pipefailUsage:
./check_pr_codebuild_urls.sh <pr_number>
Requirements: gh, jq, curl
OWNER=“${1:?owner}” REPO=“${2:?repo}” PR=“${3:?pr_number}”
for bin in gh jq curl timeout; do command -v “$bin” >/dev/null || { echo “[!] Missing dependency: $bin” >&2; exit 1; } done
tmp_commits=“$(mktemp)” tmp_urls=“$(mktemp)” trap ‘rm -f “$tmp_commits” “$tmp_urls”’ EXIT
gh_api() { timeout 20s gh api “$@” 2>/dev/null || true }
Get all commit SHAs in the PR (bounded call to avoid hangs)
gh_api “repos/${OWNER}/${REPO}/pulls/${PR}/commits” –paginate –jq ‘.[].sha’ > “$tmp_commits” if [ ! -s “$tmp_commits” ]; then echo “[!] No commits found (or API call timed out/failed).” >&2 exit 1 fi
echo “[*] PR commits:” cat “$tmp_commits” echo
echo “[*] Searching commit statuses/check-runs for CodeBuild URLs…”
while IFS= read -r sha; do [ -z “$sha” ] && continue
Classic commit statuses (target_url)
gh_api “repos/${OWNER}/${REPO}/commits/${sha}/status”
–jq ‘.statuses[]? | .target_url // empty’ 2>/dev/null || true
GitHub Checks API (details_url)
gh_api “repos/${OWNER}/${REPO}/commits/${sha}/check-runs”
–jq ‘.check_runs[]? | .details_url // empty’ 2>/dev/null || true
done < “$tmp_commits” | sort -u > “$tmp_urls”
grep -Ei ‘codebuild|codebuild.aws.amazon.com|console.aws.amazon.com/.*/codebuild’ “$tmp_urls” || true
echo echo “[*] Public-access heuristic:” echo “ - If URL redirects to signin.aws.amazon.com -> likely not public“ echo “ - If URL is directly reachable (HTTP 200) without auth redirect -> potentially public“ echo
cb_urls=“$(grep -Ei ‘codebuild|codebuild.aws.amazon.com|console.aws.amazon.com/./codebuild’ “$tmp_urls” || true)“ if [ -z “$cb_urls” ]; then echo “[] No CodeBuild URLs found in PR statuses/check-runs.” exit 0 fi
while IFS= read -r url; do [ -z “$url” ] && continue final_url=“$(timeout 20s curl -4 -sS -L –connect-timeout 5 –max-time 20 -o /dev/null -w ‘%{url_effective}’ “$url” || true)“ code=“$(timeout 20s curl -4 -sS -L –connect-timeout 5 –max-time 20 -o /dev/null -w ‘%{http_code}’ “$url” || true)“
if echo “$final_url” | grep -qi ‘signin.aws.amazon.com’; then verdict=“NOT_PUBLIC_OR_AUTH_REQUIRED” elif [ “$code” = “200” ]; then verdict=“POTENTIALLY_PUBLIC” else verdict=“UNKNOWN_CHECK_MANUALLY” fi
printf ‘%s\t%s\t%s\n’ “$verdict” “$code” “$url” done <<< “$cb_urls”
다음에서 테스트됨:
```bash
bash /tmp/check_pr_codebuild_urls.sh carlospolop codebuild-codebreach-ctf-lab 1
빠른 감사 체크리스트
# Enumerate projects
aws codebuild list-projects
# Inspect source/webhook configuration
aws codebuild batch-get-projects --names <project-name>
# Inspect global source credentials configured in account
aws codebuild list-source-credentials
각 프로젝트에 대해 다음을 검토하세요:
webhook.filterGroups에 PR 이벤트가 포함되어 있는지.ACTOR_ACCOUNT_ID패턴이^...$로 앵커되어 있지 않은지.pullRequestBuildPolicy.requiresCommentApproval가DISABLED로 설정되어 있는지.- 브랜치/경로 제한이 누락되어 있는지.
- 권한이 높은
serviceRole사용 여부. - 위험한 소스 자격증명 범위 및 재사용 여부.
하드닝 지침
- PR 빌드에 대해 코멘트 승인 요구 (
ALL_PULL_REQUESTS또는FORK_PULL_REQUESTS). - actor 허용 목록을 사용하는 경우, 정규식에 앵커(
^...$)를 추가하고 정확히 일치시키세요. - 신뢰할 수 없는 수정이
buildspec.yml및 CI 스크립트에 반영되는 것을 방지하기 위해FILE_PATH제한을 추가하세요. - 신뢰된 릴리스 빌드를 신뢰할 수 없는 PR 빌드와 별도의 프로젝트/역할로 분리하세요.
- 세분화된 최소권한의 source-provider 토큰을 사용하세요(전용 저권한 계정 권장).
- webhook 필터와 소스 자격증명 사용을 지속적으로 감사하세요.
References
- Wiz: CodeBreach - AWS CodeBuild ACTOR_ID regex bypass and token theft
- AWS CodeBuild API - WebhookFilter
- AWS CLI - codebuild create-webhook
- AWS CodeBuild User Guide - Best practices for webhooks
Tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 Discord 그룹 또는 텔레그램 그룹에 참여하거나 Twitter 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
HackTricks Cloud

