StaticCodeAudit
par CodeFixture
Outil autonome d'audit de conformité, de sécurité et de qualité de code pour les projets web (Python, JavaScript/TypeScript, HTML, Java, C#, PHP, YAML).
Sommaire
- Installation
- Démarrage rapide
- Options CLI
- Gestion des projets
- Configuration
- Catégories d'audit
- Rapports
- Intégration CI/CD
- Self-test
- Internationalisation (i18n)
- Règles personnalisées
Installation
Téléchargez le binaire correspondant à votre plateforme depuis votre espace client :
- macOS :
staticcodeaudit-macos.tar.gz(ou.dmg) - Linux :
staticcodeaudit-linux.tar.gz - Windows :
staticcodeaudit-windows.zip
Décompressez l'archive puis rendez le binaire exécutable :
# macOS / Linux
tar -xzf staticcodeaudit-macos.tar.gz
chmod +x staticcodeaudit
./staticcodeaudit --help
Aucune dépendance externe requise. Le binaire est entièrement autonome (zéro installation, zéro accès réseau).
Note : dans la suite de ce document,
staticcodeauditdésigne la commande binaire téléchargée. Vous pouvez l'ajouter à votre$PATHou l'invoquer par chemin absolu.
Démarrage rapide
# Première exécution : génère automatiquement audit.config.json et enregistre le projet
./staticcodeaudit /chemin/vers/mon-projet --init
# Lancer l'audit
./staticcodeaudit /chemin/vers/mon-projet
L'option --init crée interactivement audit.config.json en détectant :
- Les langages du projet (Python, JavaScript/TypeScript, HTML, Java, C#, PHP)
- Les répertoires de code source (
app/,src/, etc.)
Important : à l'exécution, le script utilise uniquement le fichier de configuration
audit.config.json— aucune auto-détection.
Options CLI
| Option | Description |
|---|---|
project_path |
Chemin vers le projet à auditer (par défaut : .) |
--init |
Crée audit.config.json interactivement |
--quick, -q |
Mode rapide (sécurité uniquement) |
--fail-on-high |
Code de sortie 1 si des vulnérabilités HIGH sont trouvées (CI/CD) |
--sarif |
Génère un export SARIF 2.1.0 (GitHub Code Scanning, GitLab SAST) |
--lang |
Langue du rapport et de la console (fr, en, es, de, par défaut : en) |
--debug |
Journalisation de débogage (stderr + fichier de log) |
--create-rule |
Crée ou édite une règle personnalisée (assistant interactif unifié) |
--init-rule |
Alias de --create-rule (rétrocompatibilité) |
--custom-rules-match |
Vérifie la couverture règles personnalisées ↔ fixtures personnalisées |
--with-tests |
Détecte automatiquement et exécute les tests unitaires du projet |
--with-deps |
Lance une analyse de vulnérabilités des dépendances (pip-audit, npm audit) |
--rules-match |
Vérifie que chaque règle builtin a des fixtures correspondantes |
--benchmark |
Lance un benchmark (précision, rappel, F1 sur les fixtures) |
Exemples :
# Audit complet
./staticcodeaudit-linux-x64 /chemin/vers/projet
# Mode rapide (sécurité uniquement)
./staticcodeaudit-linux-x64 /chemin/vers/projet --quick
# Mode CI/CD (export SARIF + code de sortie 1 sur HIGH)
./staticcodeaudit-linux-x64 /chemin/vers/projet --sarif --fail-on-high
./staticcodeaudit-linux-x64 /chemin/vers/projet --with-tests
# Avec analyse de vulnérabilités des dépendances
./staticcodeaudit-linux-x64 /chemin/vers/projet --with-deps
# Rapport en français
./staticcodeaudit-linux-x64 /chemin/vers/projet --lang=fr
# Créer une règle personnalisée (assistant taint interactif)
./staticcodeaudit-linux-x64 /chemin/vers/projet --init-rule
# Vérifier la couverture règles/fixtures
./staticcodeaudit-linux-x64 --rules-match
# Benchmark (précision, rappel, F1)
./staticcodeaudit-linux-x64 --benchmark
# Mode debug
./staticcodeaudit-linux-x64 /chemin/vers/projet --debug
La sortie de débogage est envoyée vers stderr et un fichier de log ({output}/SCA-DEBUG-YYYY-MM-DD-HH-MM.log).
Chaque ligne contient : niveau, module, fichier source:ligne, fonction, thread et PID.
Les messages de débogage sont traduits selon --script-lang (comme les messages console).
# stderr (--script-lang=en, par défaut)
[SCA-DBG] INFO sca.runner | runner.py:42 run() [MainThread:12345] | Config loaded: ...
# stderr (--script-lang=fr)
[SCA-DBG] INFO sca.runner | runner.py:42 run() [MainThread:12345] | Config chargée : ...
# fichier de log (même format avec horodatage)
2026-03-03 14:30:15 INFO sca.runner | runner.py:42 run() [MainThread:12345] | Config loaded: ...
# Gestion des projets
./staticcodeaudit-linux-x64 --list-projects # Liste tous les projets
./staticcodeaudit-linux-x64 /chemin/vers/projet --project-info # Informations sur le projet
./staticcodeaudit-linux-x64 /chemin/vers/projet --init-fixtures # Crée le répertoire de fixtures
./staticcodeaudit-linux-x64 /chemin/vers/projet --unregister # Désenregistre le projet
# Liste les catégories d'audit
./staticcodeaudit-linux-x64 --list-categories
./staticcodeaudit-linux-x64 --list-categories --script-lang=fr
# Liste toutes les règles par catégorie
./staticcodeaudit-linux-x64 --list-rules
./staticcodeaudit-linux-x64 /chemin/vers/projet --list-rules --script-lang=fr # avec les fixtures du projet
# Validation des fixtures
./staticcodeaudit-linux-x64 /chemin/vers/projet --self-test
Formats de sortie
Chaque exécution d'audit génère HTML + JSON par défaut. Des formats supplémentaires sont disponibles à la demande :
| Format | Contenu | Public | Comment l'activer |
|---|---|---|---|
| HTML | Rapport visuel complet avec graphiques, sidebar, glossaire | Humains (managers, développeurs) | Par défaut |
| JSON | Données brutes de l'audit (findings, scores, métadonnées) | Automatisation, dashboards, CI/CD | Par défaut |
| Demo HTML | Rapport anonymisé (chemins, code, solutions masqués) | Prospects, démos publiques | --demo |
| SARIF | Findings au format standard OASIS | IDE, GitHub Code Scanning, GitLab SAST | --sarif |
| SBOM | Inventaire des dépendances CycloneDX 1.5 | Conformité, sécurité supply chain | --sbom |
# Génère HTML + JSON + rapport démo anonymisé
./staticcodeaudit-linux-x64 /chemin/vers/projet --demo
# Génère HTML + JSON + SARIF
./staticcodeaudit-linux-x64 /chemin/vers/projet --sarif
# Génère HTML + JSON + SBOM
./staticcodeaudit-linux-x64 /chemin/vers/projet --sbom
# Génère tous les formats
./staticcodeaudit-linux-x64 /chemin/vers/projet --sarif --sbom --demo
Mode démo : l'option
--demogénère un rapport anonymisé supplémentaire (*-demo.html) à côté du rapport complet. Les chemins de fichiers sont remplacés parpath_to/{filename}:##, le code source est masqué et les solutions sont tronquées. Idéal pour partager avec des prospects ou publier en exemple.
Gestion des projets
Chaque projet audité est identifié par un UUID unique généré automatiquement lors du premier audit (--init). Ce système vous permet de :
- Distinguer des projets portant le même nom de répertoire mais situés à des emplacements différents
- Isoler les fixtures spécifiques à un projet
- Suivre l'historique d'audit par projet
- Détecter si un projet a été déplacé
Premier audit d'un projet
# Le script détecte automatiquement le projet et génère un UUID
./staticcodeaudit-linux-x64 /chemin/vers/mon-projet --init
# Sortie :
# Auto-détection du projet « mon-projet »...
# Type : Python + JavaScript
# Chemins : app/, src/
# Identifiant unique généré : a1b2c3d4
# Configuration générée : /chemin/vers/mon-projet/audit.config.json
# Projet enregistré : projects/a1b2c3d4/
Lister les projets enregistrés
./staticcodeaudit-linux-x64 --list-projects
# Sortie :
# Projets enregistrés (2) :
#
# [a1b2c3d4] MyProject
# Chemin : /chemin/vers/mon-projet
# Description : Application web d'exemple
# Dernier audit : 2026-02-25 10:30
# Audits : 15 | Fixtures : 12 spécifiques
#
# [b5c6d7e8] My-API
# Chemin : /Users/dev/my-api
# Dernier audit : Jamais
# Audits : 0 | Fixtures : génériques uniquement
Informations détaillées du projet
./staticcodeaudit-linux-x64 /chemin/vers/projet --project-info
# Sortie :
# Informations du projet
#
# ID : a1b2c3d4-e5f6-7890-abcd-ef1234567890
# Nom : MyProject
# Description : Application web d'exemple
# Version : 3.0
# Chemin : /chemin/vers/mon-projet
#
# Enregistré : 2026-01-15 14:30
# Dernier audit : 2026-02-25 10:30
# Total audits : 15
#
# Fixtures :
# Spécifiques : 12 (projects/a1b2c3d4/fixtures/)
# Génériques : 42 (include_generic: true)
# Total : 54
Ajouter des fixtures spécifiques au projet
# Crée le répertoire de fixtures pour un projet
./staticcodeaudit-linux-x64 /chemin/vers/projet --init-fixtures
# Ajoutez des fichiers dans :
# Audit/projects/{uuid}/fixtures/vulnerable/ # Fichiers qui doivent être détectés
# Audit/projects/{uuid}/fixtures/clean/ # Fichiers sans vulnérabilités
Détection de projet déplacé
Si un projet est déplacé vers un autre emplacement, le script détecte automatiquement le changement et met à jour le chemin enregistré :
Avertissement : le chemin a changé pour ce projet
Précédent : /Users/dev/ancien-chemin/mon-projet
Nouveau : /Users/dev/nouveau-chemin/mon-projet
project.json mis à jour
Désenregistrer un projet
./staticcodeaudit-linux-x64 /chemin/vers/projet --unregister
# Le fichier project.json est supprimé
# Les fixtures sont préservées (si présentes)
# Le fichier audit.config.json du projet n'est pas modifié
Configuration
Le fichier audit.config.json est généré automatiquement à la racine du projet cible lors du premier audit. Il est basé sur le modèle templates/audit.config.template.json.
brand
Configuration de l'identité visuelle. Permet de personnaliser l'identité de l'outil par projet (par exemple pour des rapports destinés aux clients).
| Champ | Type | Description |
|---|---|---|
tool_name |
string | Nom de l'outil affiché dans le rapport (par défaut : StaticCodeAudit) |
company_name |
string | Nom de la société affichée dans le pied de page du rapport (par défaut : CodeFixture) |
prefix |
string | Préfixe pour les fichiers de rapport et de données (par défaut : SCA) |
logo |
string|null | Chemin vers un logo client (SVG, PNG, JPG). Remplace le favicon et l'icône d'en-tête dans le rapport. Relatif à la racine du projet ou absolu. |
{
"brand": {
"tool_name": "Acme Code Audit",
"company_name": "Acme Corp",
"prefix": "ACM",
"logo": "assets/acme-logo.svg"
}
}
Note : si
brand.logopointe vers un fichier manquant ou un format non pris en charge, l'outil retombe sur ses icônes par défaut avec un avertissement console. Le logo est intégré en base64 dans le rapport HTML pour qu'il reste autonome.
project
Informations du projet affichées dans le rapport.
| Champ | Type | Description |
|---|---|---|
id |
string | UUID unique généré automatiquement à --init (ne pas modifier) |
name |
string | Nom du projet (auto-détecté depuis le nom du répertoire) |
version |
string | Version du projet (auto-détectée depuis package.json ou pyproject.toml) |
description |
string | Description optionnelle |
{
"project": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Mon Projet",
"version": "1.0.0",
"description": "Application web FastAPI + Vue.js"
}
}
Important : l'UUID (
id) est généré automatiquement et ne doit pas être modifié manuellement. Il est utilisé pour identifier le projet de manière unique et associer les fixtures spécifiques au projet.
languages
REQUIS — Déclare les langages du projet. Contrôle quelles règles d'audit sont exécutées.
| Valeur | Extensions analysées | Règles activées |
|---|---|---|
python |
.py |
SQL Injection, secrets, mode debug, eval, désérialisation, crypto, exceptions, etc. |
javascript |
.js, .jsx, .ts, .tsx, .mjs |
XSS, console.log, RNG non sécurisé, auth côté client, DOM, style inline, etc. |
html |
.html, .htm, .xhtml, .shtml, .vue, .svelte, .ejs, .hbs, .njk, .jinja, .jinja2, .twig, .liquid, .mustache, .phtml, .erb, .jsp, .asp, .aspx, .cshtml |
SVG inline, ARIA, boutons sans label, etc. |
java |
.java |
SQL Injection, désérialisation, XXE, crypto, CSRF, CORS, injection de commande, etc. |
csharp |
.cs |
SQL Injection, désérialisation, XXE, crypto, LDAP, injection de commande, etc. |
php |
.php |
SQL Injection, injection de commande, inclusion de fichier, XSS, désérialisation, etc. |
yaml |
.yml, .yaml |
Sécurité CI/CD (GitHub Actions, GitLab CI) |
{
"languages": ["python", "javascript", "html", "java", "csharp", "php", "yaml"]
}
Important : si un langage n'est pas déclaré, les règles correspondantes ne s'exécuteront pas. Les fichiers TypeScript (
.ts,.tsx) et JSX (.jsx,.mjs) sont traités comme du JavaScript — les mêmes règles s'appliquent. Aucun langage"typescript"séparé n'est nécessaire.
paths
Configuration des chemins d'analyse.
| Champ | Type | Description |
|---|---|---|
include |
array | REQUIS - Répertoires à analyser (relatifs à la racine du projet) |
exclude |
array | Motifs à ignorer — supporte 3 formats : glob (**/node_modules/**), nom de répertoire (alembic/), extension (*.min.js) |
Note :
paths.includeest utilisé pour tous les langages déclarés. Le filtrage par type de fichier se fait par extension. Lors de--init, la configuration est générée automatiquement avec les chemins détectés.
{
"paths": {
"include": [
"app/",
"src/",
"UI-FRONT/js/",
"UI-ADMIN/js/"
],
"exclude": [
"**/node_modules/**",
"**/vendor/**",
"**/__pycache__/**",
"*.min.js",
"*.bundle.js"
]
}
}
reports
Configuration de la génération des rapports.
| Champ | Type | Description |
|---|---|---|
output_dir |
string | Répertoire de sortie du rapport HTML |
history_dir |
string | Répertoire de stockage des données JSON (historique) |
max_history |
integer | Nombre maximum de rapports conservés |
language |
string | Langue du rapport HTML (fr, en, es, de, par défaut : fr) |
{
"reports": {
"output_dir": "docs/audit-reports",
"history_dir": "docs/audit-reports/audit-datas",
"max_history": 10,
"language": "en"
}
}
categories
Activation et pondération des catégories d'audit.
| Champ | Type | Description |
|---|---|---|
enabled |
boolean | Active/désactive la catégorie |
weight |
integer | Poids de la catégorie (1-5) — utilisé pour la priorisation des findings |
{
"categories": {
"security": { "enabled": true, "weight": 3 },
"architecture": { "enabled": true, "weight": 2 },
"ui": { "enabled": true, "weight": 1 },
"ux": { "enabled": true, "weight": 1 },
"maintenance": { "enabled": true, "weight": 1 }
}
}
Poids recommandés :
security: 3 (critique)architecture: 2 (important)ui,ux,maintenance: 1 (standard)
rules
Configuration des règles de détection.
| Champ | Type | Description |
|---|---|---|
disabled |
array | Liste des règles à ignorer |
custom_patterns |
object | Chemins personnalisés pour des règles spécifiques |
{
"rules": {
"disabled": [
"TODO/FIXME",
"console.log"
],
"custom_patterns": {
"admin_routes": "app/features/admin",
"services": "app/features",
"templates": "src/templates"
}
}
}
Règles disponibles (324 règles) :
Security :
SQL Injection: Requêtes SQL non paramétrées (f-string, concaténation)XSS:innerHTMLsans sanitisationHardcoded Secrets: Mots de passe et clés API codés en durDebug mode:debug=Trueen productionHTTP without TLS: URL HTTP non sécuriséesEval/Exec: Usage dangereux deeval()/exec()Secret logged: Secrets exposés dans les logsDeserialization:pickle.loads(),yaml.load()non sécurisésWeak crypto:hashlib.md5,hashlib.sha1OS Injection:subprocessavecshell=TrueVerbose exception: Stack traces exposéesCatch-all:except:sans type spécifiqueInsecure RNG:Math.random()pour des valeurs sensiblesClient-side auth: Contrôle d'accès vialocalStorageHomebrew auth: Comparaison de mot de passe maison au lieu d'un hachage appropriéPredictable session: RNG faible pour les tokens/sessionsDynamic import: Chargement dynamique de modules sans restrictionRace condition: Patrons d'accès fichier TOCTOUJNDI Injection: Lookup JNDI avec entrée utilisateur (Log4Shell, Java)XPath Injection: Requêtes XPath par concaténation de chaînes (Java, C#, PHP, Python)SSTI: Server-Side Template Injection (Jinja2, Pug, EJS, Nunjucks)CSV Injection: Sortie CSV sans sanitisation des caractères de formuleSMTP Injection: En-têtes email avec entrée utilisateur non sanitisée (Python, PHP)ReDoS: Expressions régulières avec quantificateurs imbriquésFormat String: Entrée utilisateur dans des chaînes de format (.format(), String.format())Missing HSTS: Framework HTTP sans Strict-Transport-SecurityMissing X-Content-Type-Options: Réponse sans en-tête nosniffMissing Referrer-Policy: Framework sans en-tête Referrer-PolicyMissing Frame Protection: Sans frame-ancestors CSP ni X-Frame-OptionsPostMessage No Origin Check: addEventListener("message") sans validation d'origineMissing SRI: Scripts externes sans Subresource IntegritySVG Scriptable Content: Éléments SVG avec scripts ou gestionnaires d'événements intégrésGraphQL Introspection: Introspection activée en productionGraphQL No Depth Limit: GraphQL sans limiteur de profondeur/coût de requêteWebSocket No TLS: Connexions ws:// au lieu de wss://File Upload No Validation: Upload sans vérification de type MIME ni d'extensionWeak Password Policy: Longueur minimale de mot de passe inférieure à 8 caractèresDefault Credentials: Mots de passe admin/root/test codés en durSecurity Questions: Patrons d'authentification basés sur la connaissanceJWT None Algorithm: JWT acceptant l'algorithme "none"JWT Hardcoded Secret: Clé de signature JWT codée en dur dans le sourceInsufficient Key Size: Clé RSA inférieure à 2048 bitsLog Injection: Entrée utilisateur non sanitisée dans les messages de log (CRLF)
Architecture :
File too long: Fichiers dépassant le seuil de lignesN+1 Query: Requêtes base de données dans une boucle
UI :
Inline style: Manipulation directe de.stylecreateElement: Création manuelle d'éléments DOMInline SVG: SVG directement dans le HTMLEvent listeners: Listeners sans nettoyageDOM in loop: Manipulation DOM dans une boucle
UX :
Untranslated toast: Texte codé en dur dans les toastsEphemeral toast: Toast d'erreur sans persistanceconsole.log: Logs de débogage résiduelsARIA: Boutons sansaria-label
Maintenance :
TODO/FIXME: Commentaires TODO, FIXME, HACK, XXXDeprecated API: Usage de fonctions stdlib dépréciées
GDPR :
PII logged: Données personnelles dans les instructions de log (5 langages)Missing data retention: Pas de gestion du cycle de vie des données
Dockerfile :
Root user: Conteneur s'exécutant en tant que rootUnpinned base: FROM sans tag de versionCOPY all: COPY . . exposant des fichiers sensibles
Java (18 règles) :
- SQL Injection, désérialisation, XXE, injection de commande, Spring CSRF/CORS, crypto/RNG faible, contournement SSL, redirection ouverte, injection SpEL, exception verbeuse, secret loggé
C# (17 règles) :
- SQL Injection, désérialisation, XXE, injection de commande, crypto/RNG faible, contournement SSL, XSS raw HTML, CORS, redirection ouverte, exception verbeuse, secret loggé, injection LDAP, validation de requête désactivée
PHP (22 règles) :
- SQL Injection, injection de commande, eval, désérialisation, inclusion de fichier, XXE, XSS echo/Blade, crypto/RNG faible, redirection ouverte, extract, jonglerie de types, mass assignment, exception verbeuse, secret loggé
CI/CD (18 règles) :
- pull_request_target_checkout, injection d'expression GHA, permissions excessives/manquantes, déclencheur de commentaire non protégé, version d'action non épinglée, variables non sécurisées GitLab, workflow absent de CODEOWNERS
- gha_secret_in_log, gha_deprecated_commands, gha_artifact_poisoning, gha_self_hosted_runner
- ci_curl_pipe_bash, ci_insecure_download, hardcoded_secret_cicd, docker_latest_tag
- gitlab_allow_failure_security, gitlab_script_secrets_echo
Frontend XSS (4 règles) :
- React dangerous innerHTML setter, contournement DomSanitizer Angular, Vue v-html, Svelte @html
ORM/SQL Injection (12 règles) :
- Django raw, SQLAlchemy text, JPA native, MyBatis, Dapper, PHP whereRaw/wpdb/Doctrine, Sequelize, Mongoose NoSQL, Prisma, TypeORM
MFA Detection (5 règles) :
- MFA manquant en Python, Java, C#, JavaScript, PHP
SSRF (5 règles) :
- Server-Side Request Forgery en Python (requests/urllib/httpx), Java (URL), C# (HttpClient), PHP (file_get_contents/curl), JavaScript (fetch/axios)
Path Traversal (4 règles) :
- Path traversal en Python (open/Path), Java (File/Paths), C# (File.ReadAllText/Path.Combine), JavaScript (fs.readFile)
Framework Security (7 règles) :
- Django : @csrf_exempt, DEBUG=True, SECRET_KEY codé en dur
- Flask : debug=True, secret_key codé en dur
- Express : Helmet manquant, CORS permissif
Cookie & LDAP (3 règles) :
- Cookie non sécurisé (HttpOnly/Secure manquant) en Python, Java, C#, JavaScript, PHP
- Injection LDAP en Python, Java
ISO 27001 A.8 Coverage (6 règles) :
- Stockage local non sécurisé (tokens/secrets dans localStorage)
- En-tête CSP manquant (Flask, Django, Express sans Content-Security-Policy)
- IP interne codée en dur (adresses privées RFC 1918)
- Endpoint de test exposé (routes /test, /debug non protégées)
- Destructif sans sauvegarde (DROP/TRUNCATE en dehors des migrations)
- Usage de l'heure locale (datetime.now() sans fuseau horaire)
tests
Configuration des tests unitaires (optionnel).
| Champ | Type | Description |
|---|---|---|
enabled |
boolean | Active l'exécution des tests |
tests_dir |
string | Répertoire des tests |
command |
string | Commande d'exécution ({tests_dir} sera remplacé) |
{
"tests": {
"enabled": true,
"tests_dir": "tests/",
}
}
fixtures
Configuration des fixtures pour la validation des règles (mode --self-test).
| Champ | Type | Description |
|---|---|---|
include_generic |
boolean | Si true, inclut aussi les fixtures génériques en fallback |
parallel |
boolean | Active l'exécution parallèle des fixtures |
parallel_workers |
integer | Nombre de workers parallèles |
fixture_timeout |
integer | Timeout par fixture (secondes) |
{
"fixtures": {
"include_generic": true,
"parallel": true,
"parallel_workers": 4,
"fixture_timeout": 30
}
}
Organisation des fixtures :
Les fixtures sont organisées par UUID de projet :
Audit/
├── projects/
│ └── {uuid}/ # Répertoire du projet (8 premiers caractères)
│ └── fixtures/ # Fixtures spécifiques au projet
│ ├── vulnerable/ # Fichiers qui doivent être détectés
│ └── clean/ # Fichiers sans vulnérabilités
│
└── generic/ # Fixtures génériques (fallback)
├── vulnerable/
└── clean/
Priorité de chargement :
1. Fixtures spécifiques au projet (projects/{uuid}/fixtures/)
Créer les répertoires de fixtures pour un projet :
./staticcodeaudit-linux-x64 /chemin/vers/projet --init-fixtures
thresholds
Seuils pour le score de santé et l'intégration CI/CD.
| Champ | Type | Description |
|---|---|---|
max_high |
integer | Vulnérabilités HIGH maximales tolérées (0 = aucune) |
max_medium |
integer | Vulnérabilités MEDIUM maximales tolérées |
min_health |
integer | Score de santé minimal requis (0-100) |
health_good |
integer | Seuil pour un « bon » score (vert) |
health_warning |
integer | Seuil pour un score « avertissement » (orange) |
{
"thresholds": {
"max_high": 0,
"max_medium": 10,
"min_health": 80,
"health_good": 90,
"health_warning": 70
}
}
Codes de sortie :
0: Audit réussi, seuils respectés1: Seuils dépassés (vulnérabilités HIGH ou score insuffisant)2: Erreur de validation des fixtures (mode--self-test)
sla
Configuration SLA par sévérité (optionnel).
| Champ | Type | Description |
|---|---|---|
enabled |
boolean | Active la section SLA dans le rapport (par défaut : false) |
rules |
object | Règles SLA par niveau de sévérité |
{
"sla": {
"enabled": true,
"rules": {
"CRITICAL": { "delay": "4h", "escalation": "CTO" },
"HIGH": { "delay": "24h", "escalation": "Tech Lead" },
"MEDIUM": { "delay": "1 sprint", "escalation": "Team Lead" },
"LOW": { "delay": "Backlog", "escalation": "Developer" }
}
}
}
retention
Configuration de la rétention des rapports (optionnel). Contrôle le nettoyage automatique des anciens rapports.
| Champ | Type | Description |
|---|---|---|
mode |
string|null | Mode de nettoyage : "count", "days", "both", ou null (par défaut : null = pas de nettoyage) |
max_count |
integer | Nombre maximum de rapports à conserver (par défaut : 10, utilisé en mode count ou both) |
max_days |
integer | Âge maximum en jours (par défaut : 90, utilisé en mode days ou both) |
{
"retention": {
"mode": "both",
"max_count": 10,
"max_days": 90
}
}
Modes :
"count": conserver uniquement les N rapports les plus récents (max_count)"days": supprimer les rapports plus anciens que N jours (max_days)"both": appliquer les deux règles (le rapport doit satisfaire les deux pour être conservé)null: aucun nettoyage automatique (par défaut)
Sécurité : au moins un rapport est toujours conservé. Les rapports sont supprimés par paires HTML+JSON. Utilisez --retention-dry-run pour prévisualiser les fichiers qui seraient supprimés sans les supprimer réellement.
Note : le paramètre existant
reports.max_historyne contrôle que les limites d'affichage des graphiques — il ne supprime pas de fichiers. Utilisezretentionpour le nettoyage effectif des fichiers.
Catégories d'audit
| Catégorie | Description | Exemples de règles |
|---|---|---|
| SECURITY | Vulnérabilités de sécurité | XSS, SQL Injection, secrets, désérialisation, crypto faible, RNG, auth côté client |
| ARCHITECTURE | Violations d'architecture | Fichiers trop longs, requêtes N+1 |
| UI | Problèmes d'interface | Accessibilité (ARIA), SVG inline, styles inline |
| UX | Expérience utilisateur | Toasts non traduits, erreurs non persistantes |
| MAINTENANCE | Maintenabilité du code | TODO/FIXME, console.log, code mort, API dépréciées |
| CICD | Sécurité des pipelines CI/CD | 18 règles : injection GHA, actions non épinglées, secrets dans les logs, curl|bash, identifiants codés en dur, docker :latest, allow_failure GitLab sur SAST |
| DEPENDENCIES | Vulnérabilités des dépendances | Analyse CVE, versions non épinglées, licences non conformes |
Rapports
Les rapports sont générés dans <projet>/docs/audit-reports/ :
docs/audit-reports/
SCA-REPORT-2026-02-22-15-30.html # Rapport HTML interactif
audit-datas/
SCA-DATA-2026-02-22-15-30.json # Données JSON (historique)
Chaque rapport est un fichier HTML autonome — tous les CSS, JavaScript, graphiques et favicons sont intégrés en inline (aucune dépendance externe). Ouvrez-le dans n'importe quel navigateur, partagez-le ou archivez-le.
Le rapport HTML inclut :
- Informations du projet (nom, version, description, UUID, chemin)
- Paramètres d'audit : langages, extensions analysées par langage, chemins include/exclude, catégories
- Score de santé global (logarithmique, pondéré par la sécurité, normalisé par LOC) avec indicateur visuel
- Répartition par sévérité (CRITICAL, HIGH, MEDIUM, LOW, INFO)
- Répartition par catégorie
- Liste détaillée des findings avec code source
- Attribution Git du committer par finding (quand
--git-blameest activé) - Comparaison avec l'audit précédent (nouveau/résolu)
- Heatmap des fichiers les plus problématiques
- Validation des fixtures avec résultats détaillés
Intégration CI/CD
# GitHub Actions
- name: Run Audit
run: |
# GitLab CI
audit:
script:
allow_failure: false
Le script renvoie un code de sortie non nul si :
- Des vulnérabilités HIGH sont détectées (
--fail-on-highoumax_high: 0) - Le score de santé est inférieur au seuil (
min_health)
Self-test
Le mode self-test valide que les règles de détection fonctionnent correctement :
# Valide les fixtures du projet (spécifiques + génériques si include_generic: true)
./staticcodeaudit-linux-x64 /chemin/vers/projet --self-test
Ce mode :
1. Charge les fixtures spécifiques au projet (projects/{uuid}/fixtures/)
2. Ajoute les fixtures génériques si include_generic: true
3. Exécute chaque fixture vulnérable et vérifie qu'elle est détectée
4. Exécute chaque fixture clean et vérifie qu'elle ne génère pas de faux positifs
5. Renvoie le code de sortie 2 si des anomalies sont détectées
Exécution parallèle : les fixtures sont exécutées en parallèle (ThreadPoolExecutor) avec un affichage dynamique de la progression :
[0/6] Validation des fixtures (a1b2c3d4 + génériques)...
Fixtures : 25/42 OK | 4 en cours | 13 en attente
- OK = terminé
- en cours = en cours
- en attente = en attente
Ajouter des fixtures spécifiques au projet :
# Crée le répertoire de fixtures
./staticcodeaudit-linux-x64 /chemin/vers/projet --init-fixtures
# Ajoutez des fichiers dans :
# Audit/projects/{uuid}/fixtures/vulnerable/ # Fichiers qui doivent être détectés
# Audit/projects/{uuid}/fixtures/clean/ # Fichiers sans vulnérabilités
Internationalisation (i18n)
L'outil d'audit prend en charge quatre langues : français (fr), anglais (en), espagnol (es) et allemand (de).
Deux configurations indépendantes :
| Configuration | Description | Par défaut |
|---|---|---|
| Langue du script | Messages console (Security Scan..., Report generated...) |
en |
| Langue du rapport | Contenu HTML (titres, libellés, légendes) | en |
Langue du script (CLI)
La langue des messages console et des logs de débogage se configure via l'option --script-lang :
# Messages en anglais (par défaut)
./staticcodeaudit-linux-x64 /chemin/vers/projet
# Messages en français
./staticcodeaudit-linux-x64 /chemin/vers/projet --script-lang=fr
# Messages en espagnol
./staticcodeaudit-linux-x64 /chemin/vers/projet --script-lang=es
# Messages en allemand
./staticcodeaudit-linux-x64 /chemin/vers/projet --script-lang=de
Langue du rapport (audit.config.json)
La langue du rapport HTML généré se configure dans le fichier audit.config.json du projet :
{
"reports": {
"output_dir": "docs/audit-reports",
"history_dir": "docs/audit-reports/audit-datas",
"max_history": 10,
"language": "es"
}
}
Valeurs supportées : fr (français), en (anglais), es (espagnol), de (allemand)
Le rapport affiche un badge de langue dans l'en-tête (par exemple Francais, English, Espanol, Deutsch).
Fichiers de traduction
Les fichiers de traduction sont stockés dans le répertoire locales/ de l'outil d'audit :
Audit/
locales/
script/
fr.json # Messages console en français
en.json # Messages console en anglais
es.json # Messages console en espagnol
de.json # Messages console en allemand
report/
fr.json # Rapport HTML en français
en.json # Rapport HTML en anglais
es.json # Rapport HTML en espagnol
de.json # Rapport HTML en allemand
Fallback : si une langue non prise en charge est spécifiée, le script bascule automatiquement vers l'anglais (en).
Exemples de combinaison
# Script EN + Rapport EN (par défaut)
./staticcodeaudit-linux-x64 /chemin/vers/projet
# Script FR + Rapport EN
./staticcodeaudit-linux-x64 /chemin/vers/projet --script-lang=fr
# Script EN + Rapport FR (définir "language": "fr" dans audit.config.json)
./staticcodeaudit-linux-x64 /chemin/vers/projet
# Script FR + Rapport FR
./staticcodeaudit-linux-x64 /chemin/vers/projet --script-lang=fr
# (avec audit.config.json contenant "language": "fr")
Contribution : ajouter des règles personnalisées
Deux types de règles personnalisées : builtin (contribuées à SCA) et client (spécifiques à un projet).
Règles personnalisées client — Assistant (recommandé)
Le moyen le plus rapide de créer une règle pour votre projet :
./staticcodeaudit-linux-x64 . --create-rule # Crée ou édite une règle personnalisée
./staticcodeaudit-linux-x64 . --custom-rules-match # Vérifie la couverture (règles ↔ fixtures)
L'assistant interactif vous guide à travers 7 étapes :
1. Nom, langage, catégorie, sévérité — avec vérification des doublons (nom + pattern)
2. Pattern à détecter (texte ou regex) + ce qui le neutralise (optionnel)
3. Description du risque — EN requis, FR/ES/DE optionnels
4. Solution — EN requis, FR/ES/DE optionnels
5. Bénéfice — optionnel
6. Exemple de code avant/après (fix_before + fix_after) — optionnel
7. Aperçu → validation → écriture dans custom-rules/{lang}/{cat}/{rule_id}.sca
Si une règle du même nom existe déjà, l'assistant propose de l'éditer (pré-remplie avec les valeurs actuelles).
Règles builtin — Manuel
L'ajout d'une nouvelle règle builtin nécessite des modifications à 6 endroits. Suivez ce guide étape par étape.
Vue d'ensemble
| Étape | Fichier(s) | Action |
|---|---|---|
| 1 | sca/rules/builtin/{lang}/{cat}/ |
Créer le fichier de règle .sca |
| 2 | locales/report/{fr,en,es,de}.json |
Ajouter les traductions de la règle (les 4 langues) |
Étape 1 : logique de détection
Patron complet :
# Dans _audit_security() (ou autre méthode _audit_*())
py_files = self._find_files(self._py_exts, self._py_paths) # ou self._js_exts, self._html_exts
for filepath in py_files:
for line_num, line in self._read_file(filepath):
if re.search(r'your_detection_pattern', line):
r = self._rule("your_rule_key")
self._add_finding(
"SECURITY", # categorie : SECURITY, ARCH, UI, UX, MAINTENANCE
r["name"], # nom de regle localise
filepath, # chemin du fichier
line_num, # numero de ligne
line, # extrait de code
"HIGH", # severite : CRITICAL, HIGH, MEDIUM, LOW, INFO
r["risk"], # description du risque localisee
r["solution"], # solution localisee
r["benefit"], # benefice localise
confidence=90, # 0-100, probabilite que ce soit un vrai probleme
rule_key="your_rule_key"
)
Note : quand
--git-blameest activé, chaque objetFindingest enrichi d'un champcommitter(string) contenant le nom de la dernière personne ayant modifié la ligne, résolu viagit blame. Ce champ vautNonepar défaut.
Helpers de chemins de fichiers :
self._find_files(self._py_exts, self._py_paths)— fichiers Python (.py)self._find_files(self._js_exts, self._js_paths)— fichiers JavaScript/TypeScript (.js,.jsx,.ts,.tsx,.mjs)self._find_files(self._html_exts, self._html_paths)— fichiers HTML/templates (.html,.htm,.xhtml,.vue,.svelte,.ejs,.hbs,.njk,.jinja2,.twig,.liquid, etc.)self._find_files(self._java_exts, self._java_paths)— fichiers Java (.java)self._find_files(self._csharp_exts, self._csharp_paths)— fichiers C# (.cs)self._find_files(self._php_exts, self._php_paths)— fichiers PHP (.php)self._find_files(self._yaml_exts, self._yaml_paths)— fichiers YAML (.yml,.yaml)
Note :
_find_files()exclut automatiquement les fichiers correspondant aux motifspaths.exclude(glob, nom de répertoire, extension). Aucun filtrage manuel nécessaire.
Étape 2 : traductions (4 langues)
Ajoutez la clé de la règle dans les 4 fichiers sous "rules" :
locales/report/fr.json :
"your_rule_key": {
"name": "Nom de la règle",
"risk": "Description du risque en français.",
"solution": "Comment corriger le problème.",
"benefit": "Bénéfice après correction (ex: CWE-XXX)."
}
locales/report/en.json :
"your_rule_key": {
"name": "Rule Name",
"risk": "Risk description in English.",
"solution": "How to fix the issue.",
"benefit": "Benefit after fix (e.g., CWE-XXX)."
}
Répétez pour es.json (espagnol) et de.json (allemand) avec la même structure.
Étape 3 : fixtures
# VULNERABLE: Description de la vulnerabilite
# Expected: Doit declencher la detection de your_rule_key (severite HIGH)
def vulnerable_function():
# Code minimal qui declenche la detection
dangerous_call(user_input)
# CLEAN: Description du patron sur
# Expected: NE doit PAS declencher la detection de your_rule_key
def safe_function():
# Implementation correcte
safe_call(sanitized_input)
Conventions de nommage :
- Vulnérable : utilisez la clé de règle comme nom de fichier (ex.
sql_injection_fstring.py) - Clean : utilisez un nom descriptif sûr (ex.
sql_parameterized.py) - L'extension correspond au langage (
.py,.js,.html)
Étape 4 : enregistrer les fixtures
VULNERABLE_FIXTURES = {
# ...entrees existantes...
"your_rule_key": ("your_rule_key.py", "app/target_path.py", "Rule Name"),
}
CLEAN_FIXTURES = {
# ...entrees existantes...
"safe_alternative": ("safe_alternative.py", "app/target_path.py", "Rule Name"),
}
Format du tuple : (fixture_filename, target_path_in_temp_project, rule_name_for_docs)
Le target_path doit correspondre à un répertoire dans la configuration paths.include (ex. app/, UI-FRONT/).
Étape 5 : tests
class TestYourRule:
"""Tests pour la detection de your_rule_key."""
def test_detects_vulnerability(self, temp_project, audit_runner):
"""Doit detecter le patron vulnerable."""
fixture = VULNERABLE_FIXTURES["your_rule_key"]
use_vulnerable_fixture(temp_project, fixture[0], fixture[1])
audit_runner._audit_security() # ou _audit_architecture(), etc.
findings = get_findings_by_rule_key(audit_runner, "your_rule_key")
assert len(findings) >= 1
def test_ignores_safe_code(self, temp_project, audit_runner):
"""Ne doit PAS detecter le patron sur."""
fixture = CLEAN_FIXTURES["safe_alternative"]
use_clean_fixture(temp_project, fixture[0], fixture[1])
audit_runner._audit_security()
findings = get_findings_by_rule_key(audit_runner, "your_rule_key")
assert len(findings) == 0
Exécuter vos tests : ```bash
Executer uniquement vos nouveaux tests
Executer tous les tests (verifier les regressions)
Checklist
Avant de soumettre, vérifiez :
- [ ] Règle définie dans les 4 fichiers de locale (
fr.json,en.json,es.json,de.json) - [ ] Fixture vulnérable créée et déclenche la détection
- [ ] Fixture clean créée et NE déclenche PAS la détection
- [ ] Classe de test avec au moins 2 tests (détecter + ignorer)
Licence
MIT