Aller au contenu principal

PHP · SAST

SAST PHP qui tourne entièrement hors-ligne

Auditez Laravel, Symfony, WordPress et PHP legacy contre l'injection SQL, XSS, file inclusion et dérive de config — sans téléverser de code vers un cloud tiers.

Frameworks & bibliothèques scannés

Nous testons la couverture sur ces frameworks via fixtures. De nouveaux patterns sont ajoutés à chaque release de règles builtin.

Laravel Symfony WordPress Drupal CodeIgniter Yii CakePHP Slim Phalcon Doctrine Eloquent PDO mysqli Composer PHPMailer Twig Blade

Principales classes CWE détectées

Ces classes CWE apparaissent le plus souvent dans les codebases modernes de ce langage. StaticCodeAudit livre des règles dédiées pour chacune, mappées à OWASP Top 10 / ISO 27001 / ASVS quand pertinent.

CWE-89

Injection SQL

mysql_query("... " . $_GET['id']), $pdo->query() avec concat, Laravel DB::raw() avec entrée user, WordPress $wpdb->query avec vars non échappées.

Détecté par la règle SCA : sql_injection_concat

CWE-79

Cross-Site Scripting (XSS)

echo $_GET['name'] sans htmlspecialchars, Twig {{ var|raw }}, WordPress esc_attr manquant sur données user.

Détecté par la règle SCA : xss_raw_html

CWE-78

Injection de commande OS

system($cmd), exec(), shell_exec(), passthru() avec entrée user. Les fonctions shell PHP interprètent les métacaractères par défaut.

Détecté par la règle SCA : command_injection_php

CWE-98

File Inclusion (RFI/LFI)

include $_GET['page'] ou require avec chemins contrôlés par l'utilisateur. Permet lecture arbitraire de fichiers, parfois exécution de code.

Détecté par la règle SCA : path_traversal_os_join

CWE-502

Désérialisation non sécurisée

unserialize($_GET['data']) sur entrée user. La sérialisation native PHP est un vecteur de gadget connu (phpggc).

Détecté par la règle SCA : unsafe_deserialization

CWE-798

Identifiants en dur

Identifiants DB dans config.php committé, WordPress wp-config.php en repo public, clés API en constantes.

Détecté par la règle SCA : hardcoded_secret

Vulnérable vs. sain — trois exemples rapides

CWE-89 Détecté par la règle SCA : sql_injection_concat
❌ Vulnérable
// Vulnérable — concaténation directe
$sql = "SELECT * FROM users WHERE id = " . $_GET['id'];
$result = $mysqli->query($sql);
✅ Sain
// Sain — requête préparée
$stmt = $mysqli->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param("i", $_GET['id']);
$stmt->execute();
CWE-79 Détecté par la règle SCA : xss_raw_html
❌ Vulnérable
// Vulnérable — echo brut
echo "<p>Hello, " . $_GET['name'] . "</p>";
✅ Sain
// Sain — htmlspecialchars avec ENT_QUOTES + UTF-8
echo "<p>Hello, " . htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8') . "</p>";
CWE-78 Détecté par la règle SCA : command_injection_php
❌ Vulnérable
// Vulnérable — abus métacaractères shell
system("convert " . $_FILES['img']['tmp_name'] . " /var/thumb.jpg");
✅ Sain
// Sain — escapeshellarg + forme 2-arg
$src = escapeshellarg($_FILES['img']['tmp_name']);
system("convert {$src} /var/thumb.jpg");

Ce que StaticCodeAudit détecte (ce langage)

  • Injection SQL en PDO concat, mysqli sans prepared statements, Laravel DB::raw, WordPress $wpdb concat
  • XSS via echo brut, Twig |raw, htmlspecialchars / esc_attr manquants
  • Injection de commande dans system, exec, shell_exec, passthru, popen
  • File inclusion (LFI/RFI) via include, require sur chemins contrôlés user
  • Désérialisation non sécurisée via unserialize sur données user
  • Identifiants en dur dans config.php, wp-config.php, .env committé
  • Config session non sécurisée (session.cookie_secure, session.cookie_httponly off)
  • Open redirect via header("Location: " . $_GET['url'])
  • Path traversal dans file_get_contents, fopen avec chemins user
  • Crypto non sécurisée (MD5/SHA1, mcrypt déprécié, clés/IV en dur)
  • Token CSRF manquant sur endpoints POST
  • Affichage erreurs PHP activé en production (display_errors=On)
  • APIs dépréciées (mysql_*, ereg, split, php-fpm pm.user=root)
  • Misconfigurations CI/CD (.gitlab-ci, GitHub Actions, scripts Composer)

Envie de savoir comment la qualité de détection est réellement mesurée ? Consultez la méthodologie complète des benchmarks multi-langages (OWASP Benchmark, NIST Juliet, précision/recall/F1 par langage) →

CVE Test Suite — Laravel et la stdlib PHP

StaticCodeAudit a été mesuré sur un CVE Test Suite réel : 45 cas reconstitués à partir de CVE publiées et historiques, sur 8 frameworks et 5 langages. Laravel et la bibliothèque standard PHP en font partie.

80,0 %
Meilleur F1 (Laravel)
100 %
Meilleur rappel
45
CVE Test Suite (total, tous langages)

Par framework, reconstitué depuis CVE

80,0 %
Laravel (reconstitué depuis CVE)
72,7 %
stdlib PHP (reconstitué depuis CVE)

Laravel obtient 100 % de précision pour 66,7 % de rappel ; la stdlib PHP obtient 80,0 % de précision pour 66,7 % de rappel — solide, pas parfait : certaines vraies CVE historiques des deux passent encore entre les mailles. Détail complet cross-langage (y compris où ASP.NET et Express obtiennent un score plus bas) sur la <a href="/fr/language-benchmarks.php" class="text-primary font-semibold hover:underline">page des benchmarks par langage</a>.

Les vraies failles tiennent rarement dans un seul fichier

Les applications Laravel répartissent la logique en couches : un contrôleur reçoit la requête, un modèle ou query builder construit la requête SQL. Un scanner limité à un seul fichier à la fois ne fait jamais le lien — il voit la donnée utilisateur dans OrderController.php et l'appel base de données dans Order.php, mais jamais la connexion entre les deux. StaticCodeAudit suit la donnée à travers les fichiers.

OrderController.php
public function show(Request $request)
{
    $id = $request->query('id');
    return Order::find($id);
}
Order.php
public static function find($id)
{
    return DB::select(
        "SELECT * FROM orders WHERE id = $id"
    );
}

id provient de la query string dans le contrôleur, et atteint la requête SQL brute un fichier plus loin, sans modification — StaticCodeAudit le signale à la ligne exacte où la requête s'exécute.

Comment ça se compare à Psalm ou Semgrep ?

Le mode d'analyse de taint de Psalm et Semgrep sont les deux outils qui reviennent en premier quand une équipe PHP cherche un scanner de sécurité gratuit. Les deux sont légitimes, et beaucoup d'équipes en utilisent déjà un — voici un comparatif honnête, pas un dénigrement.

Psalm (mode taint)

Gratuit, open source

Analyseur statique conçu d'abord pour le typage, avec un mode d'analyse de taint optionnel qui suit l'entrée utilisateur jusqu'aux sinks dangereux (SQLi, XSS, injection de commande). Moteur solide, mais le mode sécurité nécessite une configuration explicite et des annotations de type pour être efficace, et les findings ne sont pas mappés CWE/ISO 27001/ASVS par défaut.

Semgrep (Community)

Gratuit, moteur open source

Moteur de pattern-matching couvrant de nombreux langages, dont PHP, avec un large registre de règles ouvertes. Le tier gratuit couvre l'essentiel du quotidien ; le suivi de taint inter-fichiers, le reporting de conformité et certaines intégrations entreprise sont réservés aux tiers payants de Semgrep.

Comparatif complet StaticCodeAudit vs Semgrep →

Aucun des deux n'est remplacé par l'installation de StaticCodeAudit — si Psalm couvre déjà ce dont votre équipe a besoin, continuez à l'utiliser. Ce que StaticCodeAudit ajoute : des findings déjà mappés CWE/OWASP/ISO 27001/ASVS/NIST CSF (un finding prêt pour un dossier d'audit, pas juste un identifiant de règle), un suivi de taint qui fonctionne dès l'installation sans travail préalable d'annotation de type, et 7 autres langages couverts par le même binaire — pas de scanner séparé à configurer par langage. Beaucoup d'équipes utilisent les deux.

Auditez votre code

Auditez Laravel, Symfony, WordPress et PHP legacy contre l'injection SQL, XSS, file inclusion et dérive de config — sans téléverser de code vers un cloud tiers.

Télécharger le binaire démo Réserver une démo guidée