AWS CodeBuild - Untrusted PR Webhook Bypass (CodeBreach-style)

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Este vetor de ataque aparece quando um fluxo de trabalho de PR pĂșblico estĂĄ ligado a um projeto CodeBuild privilegiado com controles de webhook fracos.

Se um atacante externo conseguir fazer o CodeBuild executar o seu pull request, normalmente ele pode obter arbitrary code execution inside the build (build scripts, dependency hooks, test scripts, etc.), e entĂŁo pivotar para secrets, IAM credentials, ou source-provider credentials.

Por que isto Ă© perigoso

CodeBuild webhook filters são avaliados com padrÔes regex (para filtros não-EVENT). No filtro ACTOR_ACCOUNT_ID, isso significa que um padrão fraco pode corresponder a mais usuårios do que o pretendido. Se PRs não confiåveis forem buildados em um projeto que tem permissÔes de role AWS privilegiadas ou credenciais do GitHub, isso pode se tornar um comprometimento completo da cadeia de suprimentos.

Wiz mostrou uma cadeia prĂĄtica onde:

  1. Uma allowlist de atores do webhook usava um regex sem ancoração.
  2. Um atacante registrou um GitHub ID que correspondia como superstring de um ID confiĂĄvel.
  3. Um PR malicioso acionou o CodeBuild.
  4. A execução do código no build foi usada para despejar memória e recuperar source-provider credentials/tokens.

MisconfiguraçÔes that allow external PR code execution

A seguir estĂŁo erros de alto risco e como atacantes abusam de cada um:

  1. EVENT filters allow untrusted triggers
  • Eventos comuns e arriscados: PULL_REQUEST_CREATED, PULL_REQUEST_UPDATED, PULL_REQUEST_REOPENED.
  • Outros eventos que tambĂ©m podem se tornar perigosos se ligados a builds privilegiados: PUSH, PULL_REQUEST_CLOSED, PULL_REQUEST_MERGED, RELEASED, PRERELEASED, WORKFLOW_JOB_QUEUED.
  • Bad: EVENT="PUSH, PULL_REQUEST_CREATED, PULL_REQUEST_UPDATED" em um projeto privilegiado.
  • Better: use PR comment approval e minimize trigger events para projetos privilegiados.
  • Abuse: atacante abre/atualiza PR ou faz push para uma branch que controla, e seu cĂłdigo Ă© executado no CodeBuild.
  1. ACTOR_ACCOUNT_ID regex is weak
  • Bad: padrĂ”es sem ancoração como 123456|7890123.
  • Better: ancorar para correspondĂȘncia exata ^(123456|7890123)$.
  • Abuse: regex que faz over-match permite que GitHub IDs nĂŁo autorizados passem pelas allowlists.
  1. Other regex filters are weak or missing
  • HEAD_REF
    • Bad: refs/heads/.*
    • Better: ^refs/heads/main$ (ou uma lista explĂ­cita de branches confiĂĄveis)
  • BASE_REF
    • Bad: .*
    • Better: ^refs/heads/main$
  • FILE_PATH
    • Bad: sem restriçÔes de path
    • Better: excluir arquivos arriscados como ^buildspec\\.yml$, ^\\.github/workflows/.*, (^|/)package(-lock)?\\.json$
  • COMMIT_MESSAGE
    • Bad: marcador de confiança com correspondĂȘncia frouxa como trusted
    • Better: nĂŁo use mensagem de commit como boundary de confiança para execução de PR
  • REPOSITORY_NAME / ORGANIZATION_NAME
    • Bad: .* em webhooks de org/global
    • Better: corresponder apenas a repo/org exatos
  • WORKFLOW_NAME
    • Bad: .*
    • Better: corresponder ao nome exato do workflow (ou evitar isso como controle de confiança)
  • Abuse: atacante cria ref/path/message/repo contexto para satisfazer regex permissivas e acionar builds.
  1. excludeMatchedPattern is misused
  • Configurar essa flag incorretamente pode inverter a lĂłgica pretendida.
  • Bad: FILE_PATH '^buildspec\\.yml$' com excludeMatchedPattern=false quando a intenção era bloquear ediçÔes de buildspec.
  • Better: mesmo padrĂŁo com excludeMatchedPattern=true para negar builds que mexem em buildspec.yml.
  • Abuse: defensores acham que negam eventos/paths/atores arriscados, mas na verdade os permitem.
  1. Multiple filterGroups create accidental bypasses
  • CodeBuild avalia grupos como OR (um grupo passando Ă© suficiente).
  • Bad: um grupo estrito + um grupo permissivo de fallback (ex.: apenas EVENT=PULL_REQUEST_UPDATED).
  • Better: remova grupos de fallback que nĂŁo apliquem restriçÔes de actor/ref/path.
  • Abuse: atacante sĂł precisa satisfazer o grupo mais fraco.
  1. Comment approval gate disabled or too permissive
  • pullRequestBuildPolicy.requiresCommentApproval=DISABLED Ă© o menos seguro.
  • PapĂ©is de aprovadores excessivamente amplos reduzem o controle.
  • Bad: requiresCommentApproval=DISABLED.
  • Better: ALL_PULL_REQUESTS ou FORK_PULL_REQUESTS com papĂ©is de aprovador mĂ­nimos.
  • Abuse: PRs de forks/drive-by rodam automaticamente sem aprovação de mantenedor confiĂĄvel.
  1. No restrictive branch/path strategy for PR builds
  • Falta de defesa em profundidade com HEAD_REF + BASE_REF + FILE_PATH.
  • Bad: somente EVENT + ACTOR_ACCOUNT_ID, sem controles de ref/path.
  • Better: combine ACTOR_ACCOUNT_ID exato + BASE_REF + HEAD_REF + restriçÔes de FILE_PATH.
  • Abuse: atacante modifica inputs do build (buildspec/CI/dependencies) e obtĂ©m execução arbitrĂĄria de comandos.
  1. Public visibility + status URL exposure
  • URLs de build/check pĂșblicos melhoram o reconhecimento e testes iterativos do atacante.
  • Bad: projectVisibility=PUBLIC_READ com logs/config sensĂ­veis em builds pĂșblicos.
  • Better: mantenha projetos privados a menos que haja forte necessidade de negĂłcio e sanitize logs/artifacts.
  • Abuse: atacante descobre padrĂ”es/comportamento do projeto e afina payloads e tentativas de bypass.

Token leakage from memory

O write-up da Wiz explica que source-provider credentials estĂŁo presentes no contexto de runtime do build e podem ser roubadas apĂłs o comprometimento do build (por exemplo, via memory dumping), permitindo takeover do repositĂłrio se os escopos forem amplos.

A AWS introduziu hardening após a divulgação, mas a lição central permanece: never execute untrusted PR code in privileged build contexts e presuma que código controlado pelo atacante no build tentarå credential theft.

For additional credential theft techniques in CodeBuild, also check:

AWS Codebuild - Token Leakage

Encontrando CodeBuild URLs em PRs do GitHub

Se o CodeBuild reporta status de commit de volta para o GitHub, a URL do build do CodeBuild geralmente aparece em:

  1. PR page -> Checks tab (or the status line in Conversation/Commits).
  2. Commit page -> status/checks section -> Details link.
  3. PR commits list -> click the check context attached to a commit.

Para projetos pĂșblicos, esse link pode expor metadata/configuração do build para usuĂĄrios nĂŁo autenticados.

Script: detect CodeBuild URLs in a PR and test if they look public ```bash #!/usr/bin/env bash set -euo pipefail

Usage:

./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”

Testado e funcionando com:
```bash
bash /tmp/check_pr_codebuild_urls.sh carlospolop codebuild-codebreach-ctf-lab 1

Lista råpida de verificação de auditoria

# 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

Revise cada projeto para:

  • webhook.filterGroups contendo eventos de PR.
  • PadrĂ”es de ACTOR_ACCOUNT_ID que nĂŁo sĂŁo ancorados com ^...$.
  • pullRequestBuildPolicy.requiresCommentApproval igual a DISABLED.
  • RestriçÔes de branch/path ausentes.
  • serviceRole de privilĂ©gio elevado.
  • Escopo arriscado e reuso de credenciais de origem.

OrientaçÔes de hardening

  1. Exigir aprovação por comentårio para builds de PR (ALL_PULL_REQUESTS ou FORK_PULL_REQUESTS).
  2. Se estiver usando allowlists de actor, ancore as regexes e mantenha-as exatas.
  3. Adicione restriçÔes FILE_PATH para evitar ediçÔes não confiåveis em buildspec.yml e scripts de CI.
  4. Separe builds de release confiåveis dos builds de PR não confiåveis em projetos/funçÔes diferentes.
  5. Use tokens de source-provider com granularidade fina e menor privilégio (prefira identidades dedicadas de baixo privilégio).
  6. Audite continuamente os filtros de webhook e o uso de credenciais de origem.

References

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks