Les failles de sécurité dans le code PHP ne se trouvent pas avec PHPStan ou les tests unitaires. Il faut des outils spécialisés : les SAST (Static Application Security Testing). Deux outils complémentaires dominent l'écosystème PHP : Progpilot pour la détection par AST et Psalm pour la taint analysis. Voici comment les configurer et les intégrer dans ta CI en 15 minutes.
Progpilot : détection de vulnérabilités par analyse AST
Progpilot analyse l'arbre syntaxique abstrait (AST) de ton code PHP pour détecter les patterns de vulnérabilité connus. Il identifie les SQL injections, XSS, inclusions de fichiers (LFI/RFI), injections de commandes et désérialisations dangereuses.
# Installation
composer require --dev designsecurity/progpilot
# Lancer le scan
vendor/bin/progpilot src/Progpilot fonctionne par pattern matching sur l'AST. Il suit le flux de données depuis les sources (entrées utilisateur : $_GET, $_POST, $request->get()) vers les sinks (fonctions dangereuses : query(), echo, exec()). Si une donnée utilisateur atteint un sink sans sanitisation, c'est une vulnérabilité.
<?php
// Progpilot détecte cette SQL injection
$id = $_GET['id'];
$query = "SELECT * FROM users WHERE id = $id";
$pdo->query($query); // VULNÉRABLE : injection SQL
// Correction : requête préparée
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(['id' => $_GET['id']]); // SÉCURISÉ
// Progpilot détecte aussi le XSS
echo $_GET['name']; // VULNÉRABLE : XSS réfléchi
// Correction : échappement
echo htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8'); // SÉCURISÉPsalm taint analysis : le suivi de flux à grande échelle
Psalm est connu comme analyseur de types, mais sa fonctionnalité de taint analysis est son arme secrète pour la sécurité. Contrairement à Progpilot qui analyse fichier par fichier, Psalm suit le flux de données à travers toute la codebase — à travers les appels de méthodes, les injections de dépendances, les event listeners.
# Installation
composer require --dev vimeo/psalm
# Initialiser la configuration
vendor/bin/psalm --init
# Lancer la taint analysis
vendor/bin/psalm --taint-analysisLe système de taint de Psalm utilise des annotations pour marquer les sources et les sinks. Symfony est déjà supporté nativement : Request::get() est automatiquement marqué comme source tainted, et les méthodes Doctrine de requête comme sinks.
<?php
declare(strict_types=1);
namespace App\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Doctrine\DBAL\Connection;
final class SearchController
{
public function __construct(
private readonly Connection $connection,
) {}
public function search(Request $request): Response
{
$term = $request->query->get('q');
// Psalm taint analysis détecte cette chaîne :
// $request->query->get() -> $term -> $sql -> $connection->executeQuery()
$sql = "SELECT * FROM products WHERE name LIKE '%" . $term . "%'";
$results = $this->connection->executeQuery($sql);
// ^^^ TaintedSql détecté par Psalm
// Correction : paramètre bindé
$results = $this->connection->executeQuery(
"SELECT * FROM products WHERE name LIKE :term",
['term' => '%' . $term . '%']
);
return new Response('OK');
}
}Pourquoi utiliser les DEUX outils
Envie d'aller plus loin ?
Réserver un appel découverte →Progpilot et Psalm utilisent des approches différentes qui se complètent :
- Progpilot excelle dans la détection de patterns locaux : XSS dans les vues, inclusions de fichiers, injections de commandes. Il a une base de signatures riche et détecte des vulnérabilités que Psalm rate.
- Psalm taint analysis excelle dans le suivi de flux à travers les couches : une entrée utilisateur qui traverse 3 services avant d'atteindre une requête SQL. Il a une compréhension du typage que Progpilot n'a pas.
- Les faux positifs divergent : ce que l'un signale à tort, l'autre le confirme ou l'infirme. Utiliser les deux réduit les faux positifs globaux.
Intégration dans la CI
Ajoute les deux outils dans ta pipeline CI pour scanner automatiquement chaque PR :
# .github/workflows/security.yml
name: Security Scan
on: [push, pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with: { php-version: 8.3 }
- run: composer install --no-progress
- name: Progpilot SAST
run: vendor/bin/progpilot src/
- name: Psalm Taint Analysis
run: vendor/bin/psalm --taint-analysis --no-progress
- name: Dependency Audit
run: composer auditNote l'ajout de composer audit qui vérifie les CVE connues sur tes dépendances. C'est le troisième pilier de la sécurité : même si ton code est propre, une dépendance vulnérable compromet l'application.
Les types de vulnérabilités détectées
- SQL Injection : concaténation de données utilisateur dans des requêtes SQL (Progpilot + Psalm)
- XSS (Cross-Site Scripting) : affichage de données utilisateur sans échappement (Progpilot)
- LFI/RFI (File Inclusion) : inclusion de fichiers basée sur une entrée utilisateur (Progpilot)
- Command Injection : exécution de commandes système avec des données non filtrées (Progpilot)
- Unsafe Deserialization :
unserialize()sur des données non fiables (Progpilot + Psalm) - SSRF (Server-Side Request Forgery) : requêtes HTTP vers des URLs contrôlées par l'utilisateur (Psalm taint)
Audit de sécurité complet
Progpilot et Psalm forment la base du SAST pour PHP. Un audit de sécurité complet couvre également les CVE des dépendances (composer audit), la configuration du serveur, les headers HTTP, le CSRF, et les secrets exposés dans le code. Bear Scan intègre Progpilot, Psalm taint analysis, et composer audit dans son score de sécurité (pondéré à 20% du score global). Chaque vulnérabilité détectée est classée par sévérité avec un chiffrage de l'effort de correction. Réserve un appel découverte pour scanner la sécurité de ta codebase.
Envie d'aller plus loin ?
Discutons de votre projet et voyons comment je peux vous aider.