Outils·6 min de lecture·Par Solingo

Slither — Analyse Statique pour la Sécurité des Smart Contracts

Slither est l'outil d'analyse statique de référence pour Solidity. Apprenez à installer, exécuter et interpréter les résultats Slither pour détecter les vulnérabilités avant le déploiement.

# Slither — Analyse Statique pour la Sécurité des Smart Contracts

La sécurité est primordiale dans le développement de smart contracts. Contrairement aux logiciels traditionnels, les contrats déployés sont immuables et gèrent souvent des millions de dollars. Slither, développé par Trail of Bits, est le framework d'analyse statique open-source le plus puissant pour Solidity. Il détecte automatiquement les vulnérabilités, les code smells et les opportunités d'optimisation avant le déploiement.

Qu'est-ce que Slither ?

Slither est un outil d'analyse statique qui examine votre code Solidity sans l'exécuter. Il utilise une représentation intermédiaire personnalisée (SlithIR) pour effectuer une analyse approfondie et détecter plus de 90 patterns de vulnérabilités différents.

Fonctionnalités clés

  • Plus de 90 détecteurs de vulnérabilités couvrant les problèmes de sécurité communs et avancés
  • Zéro faux positif sur la plupart des vulnérabilités critiques
  • Exécution rapide — analysez un projet entier en quelques secondes
  • Sortie détaillée avec numéros de ligne et suggestions de correctifs
  • Support de détecteurs personnalisés pour des règles spécifiques au projet
  • Intégration CI/CD pour des vérifications de sécurité automatisées
  • Multiples formats de sortie (texte, JSON, GitHub Actions)

Ce que Slither détecte

Vulnérabilités critiques :

  • Attaques de réentrance
  • Self-destruct non protégé
  • Écritures arbitraires dans le storage
  • Delegatecall vers des contrats non fiables

Problèmes de haute sévérité :

  • Dépassement d'entiers (overflow/underflow) (pré-0.8.0)
  • Variables de storage non initialisées
  • Contrôles d'accès incorrects
  • Masquage de variables d'état

Problèmes de sévérité moyenne :

  • Manipulation du timestamp de bloc
  • Paramètres d'événements incorrects
  • Valeurs de retour manquantes
  • Égalités strictes dangereuses

Optimisations de gas :

  • Variables d'état qui pourraient être constant/immutable
  • Boucles qui peuvent être optimisées
  • Lectures redondantes du storage
  • Opérations coûteuses dans les boucles

Qualité du code :

  • Violations des conventions de nommage
  • Détection de code mort
  • Variables non utilisées
  • Documentation NatSpec manquante

Installation

Prérequis

Slither nécessite Python 3.8+ et solc (compilateur Solidity).

Installer Python (si pas déjà installé) :

# macOS

brew install python3

# Ubuntu/Debian

sudo apt install python3 python3-pip

# Windows

# Téléchargez depuis python.org

Installer solc :

# Utiliser solc-select (recommandé pour gérer les versions)

pip3 install solc-select

solc-select install 0.8.26

solc-select use 0.8.26

Installer Slither

pip3 install slither-analyzer

Vérifier l'installation :

slither --version

# Sortie : 0.10.4 (ou ultérieur)

Exécuter votre première analyse

Utilisation de base

Analyser un seul contrat :

slither MyContract.sol

Analyser un projet Hardhat/Foundry entier :

slither .

Slither détecte automatiquement la structure et la configuration de votre projet.

Exemple de sortie

Analysons un contrat vulnérable :

// VulnerableBank.sol

pragma solidity ^0.8.26;

contract VulnerableBank {

mapping(address => uint256) public balances;

function deposit() public payable {

balances[msg.sender] += msg.value;

}

// VULNÉRABLE : Attaque de réentrance

function withdraw(uint256 amount) public {

require(balances[msg.sender] >= amount);

(bool success, ) = msg.sender.call{value: amount}("");

require(success);

balances[msg.sender] -= amount;

}

}

Exécutez Slither :

slither VulnerableBank.sol

Sortie :

Reentrancy in VulnerableBank.withdraw(uint256) (VulnerableBank.sol#10-15):

External calls:

- (success) = msg.sender.call{value: amount}() (VulnerableBank.sol#12)

State variables written after the call(s):

- balances[msg.sender] -= amount (VulnerableBank.sol#14)

Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities

Slither identifie la vulnérabilité de réentrance et pointe vers la ligne exacte où l'état est modifié après l'appel externe.

Comprendre les résultats Slither

Niveaux de sévérité

Slither catégorise les résultats par impact et confiance :

Impact :

  • High : Vulnérabilités critiques pouvant mener à une perte de fonds
  • Medium : Problèmes qui pourraient être exploités sous certaines conditions
  • Low : Problèmes de qualité du code ou optimisations mineures
  • Informational : Recommandations de bonnes pratiques

Confiance :

  • High : Très probablement un vrai problème (peu de faux positifs)
  • Medium : Problème probable mais nécessite une vérification manuelle
  • Low : Problème possible mais peut être intentionnel

Lire un rapport Slither

Chaque résultat inclut :

  • Nom du détecteur : ex. "reentrancy-eth"
  • Localisation : Fichier, numéro de ligne et fonction
  • Description : Ce qu'est le problème
  • Référence : Lien vers la documentation détaillée
  • Correctif recommandé : Comment le résoudre
  • Filtrer les résultats

    Afficher uniquement haute/moyenne sévérité :

    slither . --exclude-informational --exclude-low

    Exclure des détecteurs spécifiques :

    slither . --exclude naming-convention,solc-version

    Inclure uniquement des détecteurs spécifiques :

    slither . --detect reentrancy-eth,arbitrary-send-eth

    Sortie JSON pour parsing :

    slither . --json results.json

    Corriger les vulnérabilités courantes

    Réentrance (Critique)

    Mauvais :

    function withdraw(uint256 amount) public {
    

    require(balances[msg.sender] >= amount);

    (bool success, ) = msg.sender.call{value: amount}("");

    require(success);

    balances[msg.sender] -= amount; // Changement d'état après l'appel externe

    }

    Bon (pattern Checks-Effects-Interactions) :

    function withdraw(uint256 amount) public {
    

    require(balances[msg.sender] >= amount);

    balances[msg.sender] -= amount; // Changement d'état AVANT l'appel externe

    (bool success, ) = msg.sender.call{value: amount}("");

    require(success);

    }

    Meilleur (ReentrancyGuard) :

    import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
    
    

    contract Bank is ReentrancyGuard {

    function withdraw(uint256 amount) public nonReentrant {

    require(balances[msg.sender] >= amount);

    balances[msg.sender] -= amount;

    (bool success, ) = msg.sender.call{value: amount}("");

    require(success);

    }

    }

    Variables de storage non initialisées (Élevé)

    Mauvais :

    function processData() internal {
    

    Data storage data; // Non initialisé, pointe vers le slot 0 !

    data.value = 100; // Écrase l'état du contrat

    }

    Bon :

    function processData() internal {
    

    Data memory data; // Utiliser memory

    data.value = 100;

    }

    Égalités strictes dangereuses (Moyen)

    Mauvais :

    require(address(this).balance == 10 ether); // Peut être contourné avec selfdestruct

    Bon :

    require(address(this).balance >= 10 ether);

    Détecteurs personnalisés

    Slither vous permet d'écrire des détecteurs personnalisés pour des exigences spécifiques au projet.

    Exemple : Détecter les événements manquants

    from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
    
    

    class MissingEvent(AbstractDetector):

    ARGUMENT = 'missing-event'

    HELP = 'State-changing functions should emit events'

    IMPACT = DetectorClassification.LOW

    CONFIDENCE = DetectorClassification.MEDIUM

    def _detect(self):

    results = []

    for contract in self.contracts:

    for function in contract.functions:

    if function.is_public and function.can_send_eth():

    if not function.events_called:

    results.append(self.generate_result([

    function, " should emit an event\n"

    ]))

    return results

    Exécutez votre détecteur personnalisé :

    slither . --detect missing-event

    Intégration CI/CD

    GitHub Actions

    Créez .github/workflows/slither.yml :

    name: Slither Analysis
    
    

    on: [push, pull_request]

    jobs:

    analyze:

    runs-on: ubuntu-latest

    steps:

    - uses: actions/checkout@v3

    - name: Set up Python

    uses: actions/setup-python@v4

    with:

    python-version: '3.11'

    - name: Install Slither

    run: pip3 install slither-analyzer

    - name: Install dependencies

    run: npm install

    - name: Run Slither

    run: slither . --exclude-informational --exclude-low --json slither-report.json

    - name: Upload results

    uses: actions/upload-artifact@v3

    with:

    name: slither-report

    path: slither-report.json

    Hook Pre-commit

    Ajoutez à .git/hooks/pre-commit :

    #!/bin/bash
    

    echo "Running Slither analysis..."

    slither . --exclude-informational --exclude-low

    if [ $? -ne 0 ]; then

    echo "Slither found issues. Commit aborted."

    exit 1

    fi

    Rendre exécutable :

    chmod +x .git/hooks/pre-commit

    Configuration de Slither

    Créez slither.config.json à la racine de votre projet :

    {
    

    "detectors_to_exclude": "naming-convention,solc-version",

    "exclude_informational": true,

    "exclude_low": true,

    "exclude_medium": false,

    "exclude_high": false,

    "solc": "solc",

    "solc_args": "--optimize --optimize-runs 200"

    }

    Exécutez avec la config :

    slither . --config-file slither.config.json

    Bonnes pratiques

    1. Exécuter Slither tôt et souvent

    • Exécutez sur chaque commit via des hooks pre-commit
    • Intégrez dans le pipeline CI/CD
    • Analysez avant chaque déploiement

    2. Corriger d'abord les problèmes haute confiance

    Commencez par les résultats Haute impact + Haute confiance. Ce sont presque toujours de vraies vulnérabilités.

    3. Comprendre les faux positifs

    Certains détecteurs peuvent signaler des patterns intentionnels. Documentez pourquoi ils sont sûrs en utilisant slither-disable-next-line :

    // slither-disable-next-line reentrancy-eth
    

    function withdraw() public {

    // Pattern intentionnel, protégé par mutex

    }

    4. Combiner avec d'autres outils

    Slither est puissant mais pas exhaustif. Utilisez-le avec :

    • MythX pour une analyse symbolique plus profonde
    • Echidna pour le fuzzing
    • Manticore pour l'exécution symbolique
    • Audits manuels pour la logique métier

    5. Garder Slither à jour

    pip3 install --upgrade slither-analyzer

    De nouveaux détecteurs sont ajoutés régulièrement.

    Conclusion

    Slither est un outil essentiel pour la sécurité des smart contracts. Son analyse rapide et précise détecte les vulnérabilités qui pourraient mener à des exploits et des pertes de fonds. En intégrant Slither dans votre workflow de développement, vous réduisez significativement le risque de déployer des contrats vulnérables.

    Commencez à sécuriser vos contrats aujourd'hui — installez Slither et exécutez votre première analyse. Puis pratiquez les patterns de codage sécurisé avec les défis axés sécurité de Solingo pour construire des smart contracts à toute épreuve.

    Prochaines étapes :

    • Exécutez Slither sur vos projets existants
    • Configurez GitHub Actions pour une analyse automatisée
    • Apprenez les détecteurs personnalisés pour des règles spécifiques au projet
    • Combinez Slither avec des outils de fuzzing comme Echidna

    Prêt à mettre en pratique ?

    Applique ces concepts avec des exercices interactifs sur Solingo.

    Commencer gratuitement