---
name: linter-temps-constant
description: Détecteur de comparaisons non temps-constant (==/!=) sur des données qui ressemblent à des secrets cryptographiques dans du code source Rust. Bibliothèque standard uniquement, zéro dépendance, zéro appel réseau.
theme: securite-souverainete
langages_cibles: rust
---
# linter-temps-constant
## Objectif
Scanner un dossier de code source Rust et détecter les comparaisons `==`/`!=`
directes sur des identifiants qui ressemblent à des secrets cryptographiques
(clé, token, hash, hmac, mot de passe...), là où une comparaison à temps
constant (`subtle::ConstantTimeEq`, `.ct_eq()`) devrait être utilisée à la
place pour éviter une fuite d'information par mesure de timing.
## Pourquoi ce skill existe
Rappel explicite du fichier source de ce projet : *"la sécurité à temps
constant est une propriété de l'ensemble du programme compilé, et non pas
seulement de la crate"*. Cet outil ne remplace pas une revue humaine, mais
donne un premier signal rapide et reproductible sur un point de sécurité
précis et facile à manquer en relecture.
## Pourquoi Rust (et pas un autre langage) ?
- **C'est le langage du code analysé** : contrairement à `audit-souverainete`
(généraliste multi-langages), cet outil est spécifique à la syntaxe Rust —
écrit dans le même langage, pas de portage artificiel.
- **Performance sur de gros codebases** : un binaire compilé scanne un
répertoire `src/` volumineux (des centaines de fichiers, comme
solivram-website) en une fraction de seconde, sans l'overhead d'un
interpréteur.
- **Aucune dépendance externe nécessaire** : la stdlib Rust suffit
entièrement (parcours de fichiers, chaînes de caractères, arguments CLI) —
contrairement à un besoin d'analyse syntaxique réelle qui demanderait
`syn`/`proc-macro2` (tiers), on reste sur une détection texte simple et
volontairement transparente sur ses limites (voir plus bas).
## Garanties de conception (non négociables)
- **Zéro dépendance tierce** : `Cargo.toml` ne déclare aucune dépendance —
uniquement la bibliothèque standard.
- **Zéro appel réseau** : aucune I/O réseau à aucun moment.
- **Contenu scanné traité comme donnée inerte** : le code source lu est
uniquement comparé à des motifs textuels, jamais exécuté ni interprété.
- **`eprintln!` au lieu de `tracing`** : solivram-website utilise `tracing`
pour la journalisation structurée d'un serveur long-running — cet outil est
un CLI ponctuel, `eprintln!` suffit et évite une dépendance externe.
## Conformité aux règles du projet (verify_rules_rust.sh)
Le script `../../outils/verify_rules_rust.sh` (copie exacte de
`scripts/verify_rules_website.sh` de solivram-website, explicitement conçu
"UNIVERSEL : adaptable à tout projet Rust") a été exécuté sur ce code source :
```bash
bash ../../outils/verify_rules_rust.sh --src src
```
**Résultat au 2026-07-26 : 0 violation bloquante.** 2 avertissements résiduels
documentés ci-dessous (faux positifs vérifiés, pas corrigés délibérément).
### 2 avertissements §5 — faux positifs vérifiés, non corrigés
Le scanner générique §5 (`None => valeur brute sans contexte`) signale les 2
lignes `None => false` dans le calcul de `est_rs` (détection d'extension
`.rs`). Vérifié dans le code du scanner lui-même
(fonction `scanner()`, ligne ~266) : l'exemption ne fonctionne QUE si la
ligne entière commence par `//` — un commentaire en fin de ligne ne suffit
pas pour ce §5 générique (contrairement à §9/§27 qui reconnaissent une
étiquette d'exemption dédiée).
La correction suggérée par le scanner lui-même
(`None => { tracing::debug!(...); valeur_defaut }`) a été délibérément
**rejetée après analyse** : "pas d'extension" ou "extension non-UTF8" est le
cas **normal et très fréquent** pour la quasi-totalité des fichiers non-`.rs`
d'un répertoire (`Cargo.toml`, `README`, `.gitignore`...) — y ajouter un log
à chaque occurrence produirait un bruit constant et trompeur pour un cas qui
n'est pas une anomalie. Documenté ici plutôt que de dégrader le code pour
faire taire un faux positif — même principe que les faux positifs déjà
rencontrés sur solivram-website (ex: BUG-SCANNER-VIOLATION-STORE-2081-01).
## Mode d'emploi
**Compiler :**
```bash
cargo build --release
```
**Lancer :**
```bash
./target/release/linter-temps-constant <dossier_cible>
```
**Exemple concret** (validation réelle du 2026-07-26, sur un projet Rust de
taille significative — voir section Limites pour le résultat) :
```bash
./target/release/linter-temps-constant /chemin/vers/mon-projet/src
```
**Tests unitaires** (8 tests, aucun réseau, aucune I/O disque réelle) :
```bash
cargo test
```
**Prérequis :** Rust stable (testé avec rustc 1.93, édition 2024). Aucune
dépendance à installer (`cargo build` ne télécharge rien).
## Limites connues (honnêteté du outil, pas de sur-promesse)
- Détection par **motifs textuels tokenisés**, pas d'analyse syntaxique
réelle (pas d'AST) — une variable nommée `token_counter` (compteur, pas un
secret) sera signalée comme un faux positif plausible.
- Ne détecte que les comparaisons sur la **même ligne** que le mot-clé
sensible — une comparaison sur plusieurs lignes ou via une variable
intermédiaire non explicitement nommée peut échapper à la détection.
- Liste de mots-clés sensibles fixe et non configurable dans cette version
(`secret`, `key`, `token`, `password`, `mdp`, `hash`, `k_pqc`, `hmac`,
`mac`, `tag`, `signature`, `nonce`, `salt`, `empreinte`, `jeton`, `cle`,
`credential`, `auth`) — un token de mot trop court (`cle`) peut matcher un
identifiant non lié à la crypto (`cycle` contient `cle` en sous-chaîne).
- Ne remplace pas une revue de sécurité humaine — outil de dégrossissage
rapide, pas une preuve d'absence de vulnérabilité temps-constant.