DevOpsFacile
AccueilParcours de formationCertificationsModulesCheat SheetÀ Propos
DevOpsFacile

Une plateforme d'apprentissage complète pour maîtriser les pratiques DevOps modernes, du débutant à l'expert.

contact@devopsfacile.fr

Formation

  • Parcours de formation
  • Modules

Informations

  • À Propos
  • Conditions d'utilisation
  • Confidentialité
  • Mentions légales

© 2026 DevOps Facile. Tous droits réservés.

Fait avec pour la communauté DevOps

ModulesSécuriser ses pipelines et applications (DevSecOps)04 - Intégrer l'analyse de code statique (SAST) dans le pipeline

Détails

  • 25 minutes
  • Intermédiaire

Objectifs

  • Configurer Semgrep dans GitHub Actions
  • Scanner du code Python avec Bandit
  • Détecter et corriger une injection SQL dans le code
Module Sécuriser ses pipelines et applications (DevSecOps)

Exercice 04 : Intégrer l'analyse de code statique (SAST) dans le pipeline

🎯 Objectifs

À la fin de cet exercice, vous serez capable de :

  • ✅ Configurer GitHub Actions avec Semgrep pour le SAST
  • ✅ Utiliser Bandit pour scanner du code Python
  • ✅ Utiliser ESLint avec le plugin sécurité pour JavaScript
  • ✅ Trouver et corriger une vulnérabilité d'injection SQL
  • ✅ Publier un rapport de sécurité comme artefact CI

Durée estimée : 25 minutes

Difficulté : ⭐⭐⭐☆☆ (Intermédiaire)

Prérequis : Notions de GitHub Actions, Python ou JavaScript


📖 Contexte

Le SAST (Static Application Security Testing) analyse le code source sans l'exécuter pour détecter des vulnérabilités comme les injections SQL, XSS, ou l'utilisation de fonctions dangereuses. L'intégrer dans la CI garantit que chaque pull request est analysée avant fusion.


📋 Énoncé

Créez un projet Python vulnérable, configurez des outils SAST pour détecter les problèmes, et corrigez les vulnérabilités trouvées.


🧭 Déroulement de l'exercice

Tâche 1 : Créer un code Python vulnérable

Créez app.py avec une injection SQL et une exécution de commande système non sécurisée :

python
import sqlite3
import subprocess

def get_user(username):
    conn = sqlite3.connect("users.db")
    cursor = conn.cursor()
    # VULNÉRABILITÉ : injection SQL
    query = f"SELECT * FROM users WHERE username = '{username}'"
    cursor.execute(query)
    return cursor.fetchall()

def run_command(cmd):
    # VULNÉRABILITÉ : injection de commande
    result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
    return result.stdout

Indice : L'injection SQL permet à un attaquant de passer ' OR '1'='1 comme username pour récupérer tous les utilisateurs. L'injection de commande avec shell=True permet d'exécuter des commandes arbitraires si cmd vient d'une entrée utilisateur.

Vérification : Le code est syntaxiquement valide (python -c "import app"). Vous comprenez comment chaque vulnérabilité pourrait être exploitée.


Tâche 2 : Scanner avec Bandit

Installez Bandit et scannez app.py :

bash
pip install bandit
bandit -r app.py -f json -o bandit-report.json
bandit -r app.py  # Affichage lisible

Indice : Bandit identifie les problèmes par sévérité (HIGH/MEDIUM/LOW) et confiance (HIGH/MEDIUM/LOW). Les codes B608 (SQL injection) et B602/B603 (subprocess) sont des HIGH à corriger en priorité.

Vérification : Bandit détecte au moins 2 problèmes HIGH dans app.py. Le rapport JSON est généré dans bandit-report.json.


Tâche 3 : Corriger les vulnérabilités

Réécrivez les fonctions vulnérables en appliquant les bonnes pratiques :

Indice :

`python

import sqlite3

import subprocess

import shlex

>

def get_user(username):

conn = sqlite3.connect("users.db")

cursor = conn.cursor()

# CORRECTION : requête paramétrée (prepared statement)

query = "SELECT * FROM users WHERE username = ?"

cursor.execute(query, (username,))

return cursor.fetchall()

>

def run_command(cmd_parts):

# CORRECTION : liste de commandes, pas shell=True

# cmd_parts doit être une liste : ["ls", "-la", "/tmp"]

result = subprocess.run(cmd_parts, shell=False,

capture_output=True, text=True)

return result.stdout

`

Vérification : bandit -r app.py ne retourne plus de vulnérabilités HIGH. Les requêtes paramétrées empêchent toute injection SQL.


Tâche 4 : Configurer Semgrep dans GitHub Actions

Créez .github/workflows/sast.yml avec Semgrep :

Indice :

`yaml

name: SAST - Analyse de sécurité

>

on:

push:

branches: [main]

pull_request:

branches: [main]

>

jobs:

semgrep:

name: Semgrep SAST

runs-on: ubuntu-latest

steps:

- uses: actions/checkout@v4

>

- name: Run Semgrep

uses: returntocorp/semgrep-action@v1

with:

config: >-

p/python

p/owasp-top-ten

p/sql-injection

env:

SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}

>

- name: Upload rapport Semgrep

if: always()

uses: actions/upload-artifact@v4

with:

name: semgrep-report

path: semgrep.sarif

`

Vérification : Le workflow apparaît dans l'onglet Actions de GitHub. Il s'exécute sur chaque PR et bloque si des HIGH sont détectés.


Tâche 5 : Ajouter Bandit dans le pipeline CI

Ajoutez un job Bandit dans le même workflow :

Indice :

`yaml

bandit:

name: Bandit - Python Security

runs-on: ubuntu-latest

steps:

- uses: actions/checkout@v4

>

- uses: actions/setup-python@v5

with:

python-version: "3.12"

>

- run: pip install bandit[toml]

>

- name: Run Bandit

run: bandit -r src/ -f json -o bandit-report.json -ll

continue-on-error: false

>

- name: Upload rapport Bandit

if: always()

uses: actions/upload-artifact@v4

with:

name: bandit-report

path: bandit-report.json

`

Vérification : Le job Bandit échoue si des vulnérabilités HIGH existent (-ll = niveau minimum LOW, ou -lll pour HIGH uniquement). Le rapport JSON est disponible en artefact.


🗂️ Mini-Projet

Configurez Bandit via pyproject.toml pour personnaliser les règles :

toml
[tool.bandit]
exclude_dirs = ["tests", "venv"]
skips = ["B101"]  # Ignorer les assert en test
tests = ["B201", "B301", "B602", "B608"]

Puis intégrez un badge de sécurité dans le README :

markdown
![Bandit](https://github.com/mon-org/mon-repo/actions/workflows/sast.yml/badge.svg)

Checkpoints :

  • bandit -r app.py détecte l'injection SQL dans le code original
  • Le code corrigé passe Bandit sans HIGH
  • Le workflow GitHub Actions s'exécute sur les PR
  • Le rapport Bandit est disponible comme artefact
  • Semgrep est configuré avec les règles OWASP Top 10

Retour au module

Sur cette page

  • 🎯 Objectifs
  • 📖 Contexte
  • 📋 Énoncé
  • 🧭 Déroulement de l'exercice
  • Tâche 1 : Créer un code Python vulnérable
  • Tâche 2 : Scanner avec Bandit
  • Tâche 3 : Corriger les vulnérabilités
  • Tâche 4 : Configurer Semgrep dans GitHub Actions
  • Tâche 5 : Ajouter Bandit dans le pipeline CI
  • 🗂️ Mini-Projet