AWS CodeBuild - Contournement de webhook PR non fiable (CodeBreach-style)
Tip
Apprenez & pratiquez AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Soutenez HackTricks
- Consultez les subscription plans!
- Rejoignez le đŹ Discord group ou le telegram group ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des hacking tricks en soumettant des PRs aux HackTricks et HackTricks Cloud github repos.
Ce vecteur dâattaque apparaĂźt lorsquâun workflow PR public est connectĂ© Ă un projet CodeBuild privilĂ©giĂ© avec des contrĂŽles de webhook faibles.
Si un attaquant externe peut faire exĂ©cuter sa pull request par CodeBuild, il peut gĂ©nĂ©ralement obtenir une exĂ©cution de code arbitraire Ă lâintĂ©rieur du build (scripts de build, hooks de dĂ©pendances, scripts de test, etc.), puis pivoter vers des secrets, des credentials IAM, ou des credentials du fournisseur de source.
Pourquoi câest dangereux
Les filtres de webhook CodeBuild sont Ă©valuĂ©s avec des patterns regex (pour les filtres non EVENT). Dans le filtre ACTOR_ACCOUNT_ID, cela signifie quâun pattern faible peut correspondre Ă plus dâutilisateurs que prĂ©vu.
Si des PR non fiables sont bĂąties dans un projet qui dispose de permissions de rĂŽle AWS privilĂ©giĂ©es ou dâidentifiants GitHub, cela peut devenir une compromission complĂšte de la chaĂźne dâapprovisionnement.
Wiz a montrĂ© une chaĂźne pratique oĂč :
- Une allowlist dâacteurs du webhook utilisait une regex non ancrĂ©e.
- Un attaquant a enregistrĂ© un ID GitHub qui correspondait comme un superstring dâun ID de confiance.
- Une PR malveillante a déclenché CodeBuild.
- LâexĂ©cution du code du build a Ă©tĂ© utilisĂ©e pour dumper la mĂ©moire et rĂ©cupĂ©rer des credentials/tokens du fournisseur de source.
Mauvaises configurations permettant lâexĂ©cution de code de PR externes
Les erreurs à haut risque suivantes et la façon dont les attaquants les abusent :
EVENTfilters allow untrusted triggers
- ĂvĂ©nements risquĂ©s courants :
PULL_REQUEST_CREATED,PULL_REQUEST_UPDATED,PULL_REQUEST_REOPENED. - Autres événements pouvant devenir dangereux si liés à des builds privilégiés :
PUSH,PULL_REQUEST_CLOSED,PULL_REQUEST_MERGED,RELEASED,PRERELEASED,WORKFLOW_JOB_QUEUED. - Bad:
EVENT="PUSH, PULL_REQUEST_CREATED, PULL_REQUEST_UPDATED"dans un projet privilégié. - Better: utiliser une approbation par commentaire pour les PR et minimiser les événements déclencheurs pour les projets privilégiés.
- Abuse: lâattaquant ouvre/met Ă jour une PR ou pousse sur une branche quâil contrĂŽle, et son code sâexĂ©cute dans CodeBuild.
ACTOR_ACCOUNT_IDregex is weak
- Bad: patterns non ancrés comme
123456|7890123. - Better: ancrage exact
^(123456|7890123)$. - Abuse: un over-match de la regex permet à des IDs GitHub non autorisés de passer les allowlists.
- Other regex filters are weak or missing
HEAD_REF- Bad:
refs/heads/.* - Better:
^refs/heads/main$(ou une liste explicite de branches de confiance) BASE_REF- Bad:
.* - Better:
^refs/heads/main$ FILE_PATH- Bad: pas de restrictions de chemin
- Better: exclure les fichiers Ă risque comme
^buildspec\\.yml$,^\\.github/workflows/.*,(^|/)package(-lock)?\\.json$ COMMIT_MESSAGE- Bad: marqueur de confiance avec un match lĂąche comme
trusted - Better: ne pas utiliser le message de commit comme frontiĂšre de confiance pour lâexĂ©cution des PR
REPOSITORY_NAME/ORGANIZATION_NAME- Bad:
.*dans les webhooks org/globaux - Better: correspondances exactes repo/org uniquement
WORKFLOW_NAME- Bad:
.* - Better: correspondances exactes du nom du workflow uniquement (ou éviter cela comme contrÎle de confiance)
- Abuse: lâattaquant construit un ref/chemin/message/contexte de repo pour satisfaire une regex permissive et dĂ©clencher des builds.
excludeMatchedPatternis misused
- Définir ce flag incorrectement peut inverser la logique voulue.
- Bad:
FILE_PATH '^buildspec\\.yml$'avecexcludeMatchedPattern=falsealors que lâintention Ă©tait de bloquer les edits de buildspec. - Better: mĂȘme pattern avec
excludeMatchedPattern=truepour refuser les builds touchantbuildspec.yml. - Abuse: les dĂ©fenseurs pensent quâils refusent des Ă©vĂ©nements/chemins/acteurs risquĂ©s, mais en rĂ©alitĂ© ils les autorisent.
- Multiple
filterGroupscreate accidental bypasses
- CodeBuild évalue les groupes comme un OR (un groupe passant suffit).
- Bad: un groupe strict + un groupe fallback permissif (par ex., seulement
EVENT=PULL_REQUEST_UPDATED). - Better: supprimer les groupes fallback qui nâappliquent pas de contraintes actor/ref/path.
- Abuse: lâattaquant nâa besoin que de satisfaire le groupe le plus faible.
- Comment approval gate disabled or too permissive
pullRequestBuildPolicy.requiresCommentApproval=DISABLEDest le moins sĂ»r.- Des rĂŽles dâapprobateur trop larges rĂ©duisent le contrĂŽle.
- Bad:
requiresCommentApproval=DISABLED. - Better:
ALL_PULL_REQUESTSouFORK_PULL_REQUESTSavec des rĂŽles dâapprobateurs minimaux. - Abuse: les PRs fork/drive-by sâexĂ©cutent automatiquement sans approbation dâun mainteneur de confiance.
- No restrictive branch/path strategy for PR builds
- Absence de défense en profondeur avec
HEAD_REF+BASE_REF+FILE_PATH. - Bad: seulement
EVENT+ACTOR_ACCOUNT_ID, pas de contrĂŽles ref/path. - Better: combiner des restrictions exactes
ACTOR_ACCOUNT_ID+BASE_REF+HEAD_REF+FILE_PATH. - Abuse: lâattaquant modifie les entrĂ©es du build (buildspec/CI/dĂ©pendances) et obtient une exĂ©cution de commande arbitraire.
- Public visibility + status URL exposure
- Les URLs publiques des builds/checks facilitent la reconnaissance et les tests itĂ©ratifs de lâattaquant.
- Bad:
projectVisibility=PUBLIC_READavec des logs/config sensibles dans des builds publics. - Better: garder les projets privés sauf besoin business fort, et assainir logs/artifacts.
- Abuse: lâattaquant dĂ©couvre des patterns/comportements du projet, puis affine les payloads et les tentatives de contournement.
Token leakage from memory
Le write-up de Wiz explique que les credentials du fournisseur de source sont prĂ©sents dans le contexte dâexĂ©cution du build et peuvent ĂȘtre volĂ©s aprĂšs compromission du build (par exemple via un dump mĂ©moire), permettant la prise de contrĂŽle du repository si les scopes sont larges.
AWS a introduit des durcissements aprÚs la divulgation, mais la leçon principale reste : ne jamais exécuter du code de PR non fiable dans des contextes de build privilégiés et supposez que le code de build contrÎlé par un attaquant tentera de voler des credentials.
Pour des techniques supplémentaires de vol de credentials dans CodeBuild, voir aussi :
Finding CodeBuild URLs in GitHub PRs
Si CodeBuild rapporte le statut sur GitHub, lâURL du build CodeBuild apparaĂźt gĂ©nĂ©ralement dans :
- PR page -> Checks tab (ou la ligne de statut dans Conversation/Commits).
- Commit page -> section status/checks -> lien Details.
- PR commits list -> cliquer sur le contexte de check attaché à un commit.
Pour les projets publics, ce lien peut exposer des métadonnées/configuration du build à des utilisateurs non authentifiés.
Script : détecter les CodeBuild URLs dans une PR et tester si elles semblent publiques
```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â
Testé avec :
```bash
bash /tmp/check_pr_codebuild_urls.sh carlospolop codebuild-codebreach-ctf-lab 1
Liste de vĂ©rification rapide pour lâaudit
# 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
Examinez chaque projet pour :
webhook.filterGroupscontenant des événements PR.- des patterns
ACTOR_ACCOUNT_IDqui ne sont pas ancrĂ©s avec^...$. pullRequestBuildPolicy.requiresCommentApprovalĂ©gal ĂDISABLED.- absence de restrictions de branche/chemin.
serviceRoleà privilÚges élevés.- portée et réutilisation risquées des identifiants source.
Conseils de durcissement
- Exiger lâapprobation par commentaire pour les builds PR (
ALL_PULL_REQUESTSouFORK_PULL_REQUESTS). - Si vous utilisez des allowlists dâacteurs, ancrez les regex et gardez-les exactes.
- Ajoutez des restrictions
FILE_PATHpour éviter des modifications non fiables debuildspec.ymlet des scripts CI. - Séparez les builds de release de confiance des builds PR non fiables en projets/rÎles différents.
- Utilisez des tokens de fournisseur source à granularité fine et au moindre privilÚge (préférez des identités dédiées à faibles privilÚges).
- Auditez en continu les filtres webhook et lâutilisation des identifiants source.
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
Apprenez & pratiquez AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Soutenez HackTricks
- Consultez les subscription plans!
- Rejoignez le đŹ Discord group ou le telegram group ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des hacking tricks en soumettant des PRs aux HackTricks et HackTricks Cloud github repos.
HackTricks Cloud

