detection_violation.py — intégrité, réaction progressive, suppression en dernier recours

Bienvenue sur CFTPfr.fr Forums detection_violation.py — intégrité, réaction progressive, suppression en dernier recours

  • Ce sujet est vide.
Affichage de 1 message (sur 1 au total)
  • Auteur
    Messages
  • #298
    Mario Da Conceicao
    Maître des clés

    Nouveau composant du 01/08/2026 — détection de violation, complète limiteur.py. Surveille l’intégrité des fichiers protégés et l’environnement (liaison matérielle), réagit de façon progressive : avertir, puis verrouiller, puis supprimer les fichiers protégés de MIRA en dernier recours — jamais les autres fichiers du client, jamais immédiat sans avertissement.

    Principe

    1. Avertir : première anomalie détectée → message d’avertissement, MIRA continue de fonctionner mais signale le problème
    2. Verrouiller : anomalie confirmée ou répétée → MIRA cesse de répondre (comme un abonnement expiré), mais rien n’est supprimé — récupérable si c’était une fausse alerte
    3. Supprimer (dernier recours, désactivé par défaut) : uniquement si toi, créateur, actives ce niveau ET que la violation est confirmée et grave → supprime UNIQUEMENT les fichiers propres à MIRA (modèle, spécialités, licence) — ne touche JAMAIS aux autres fichiers du client
    import hashlib
    import json
    import logging
    from pathlib import Path
    from datetime import datetime
    
    from limiteur import Limiteur
    
    BASE_DIR = Path(__file__).resolve().parent
    EMPREINTES_FILE = BASE_DIR / "config" / "empreintes_integrite.json"
    JOURNAL_VIOLATIONS = BASE_DIR / "logs" / "violations.log"
    
    FICHIERS_PROTEGES = [
        "moteur_ia.py",
        "gestionnaire_specialites.py",
        "limiteur.py",
        "licence.json",
    ]
    
    class DetectionViolation:
        """
        Surveille l'intégrité de MIRA et réagit de façon progressive à une
        tentative de violation (modification non autorisée, contournement du
        limiteur, environnement suspect).
    
        IMPORTANT : ne supprime JAMAIS rien d'autre que les fichiers propres à
        MIRA elle-même. Aucun fichier du client (documents, autres logiciels)
        n'est jamais concerné, à aucun niveau.
        """
    
        def __init__(self, niveau_reaction_max="verrouiller"):
            """
            niveau_reaction_max : "avertir", "verrouiller", ou "suppression"
            — plafond du niveau de réaction autorisé. "suppression" doit être
            activé explicitement par le créateur, jamais par défaut.
            """
            self.niveau_reaction_max = niveau_reaction_max
            self.limiteur = Limiteur()
            JOURNAL_VIOLATIONS.parent.mkdir(parents=True, exist_ok=True)
    
        def _calculer_empreinte(self, fichier):
            try:
                contenu = Path(fichier).read_bytes()
                return hashlib.sha256(contenu).hexdigest()
            except Exception:
                return None
    
        def verifier_integrite(self):
            """
            Compare les empreintes actuelles des fichiers protégés à celles
            enregistrées comme valides. Retourne la liste des fichiers modifiés.
            """
            if self.limiteur.est_createur():
                return []  # Aucune vérification en mode créateur
    
            if not EMPREINTES_FILE.exists():
                return []  # Pas encore de référence enregistrée
    
            with open(EMPREINTES_FILE, "r", encoding="utf-8") as f:
                empreintes_attendues = json.load(f)
    
            fichiers_modifies = []
            for nom_fichier in FICHIERS_PROTEGES:
                empreinte_actuelle = self._calculer_empreinte(BASE_DIR / nom_fichier)
                empreinte_attendue = empreintes_attendues.get(nom_fichier)
                if empreinte_attendue and empreinte_actuelle != empreinte_attendue:
                    fichiers_modifies.append(nom_fichier)
            return fichiers_modifies
    
        def enregistrer_empreintes_valides(self):
            """RÉSERVÉ AU CRÉATEUR : à appeler après une mise à jour légitime."""
            empreintes = {}
            for nom_fichier in FICHIERS_PROTEGES:
                empreinte = self._calculer_empreinte(BASE_DIR / nom_fichier)
                if empreinte:
                    empreintes[nom_fichier] = empreinte
            EMPREINTES_FILE.parent.mkdir(parents=True, exist_ok=True)
            with open(EMPREINTES_FILE, "w", encoding="utf-8") as f:
                json.dump(empreintes, f, indent=4)
    
        def _journaliser_violation(self, details):
            with open(JOURNAL_VIOLATIONS, "a", encoding="utf-8") as f:
                f.write(f"{datetime.now().isoformat(timespec='seconds')} - {details}\n")
            logging.warning(f"Violation détectée : {details}")
    
        def reagir(self, fichiers_modifies):
            """
            Réagit selon le niveau de gravité, sans jamais dépasser
            niveau_reaction_max, quelle que soit la gravité détectée.
            """
            if not fichiers_modifies:
                return {"statut": "ok", "message": "Aucune anomalie détectée."}
    
            self._journaliser_violation(f"Fichiers modifiés : {', '.join(fichiers_modifies)}")
    
            if self.niveau_reaction_max == "avertir":
                return {
                    "statut": "avertissement",
                    "message": f"Anomalie détectée sur : {', '.join(fichiers_modifies)}. MIRA continue de fonctionner."
                }
    
            if self.niveau_reaction_max in ("verrouiller", "suppression"):
                # Verrouille toujours en premier, même si "suppression" est
                # le plafond autorisé — jamais de suppression directe sans
                # être passé par un verrouillage d'abord.
                return {
                    "statut": "verrouille",
                    "message": "MIRA verrouillée suite à une anomalie d'intégrité. Contact du créateur nécessaire pour rétablir l'accès."
                }
    
            return {"statut": "inconnu"}
    
        def supprimer_fichiers_proteges(self, confirmation_explicite=False):
            """
            DERNIER RECOURS. Supprime UNIQUEMENT les fichiers listés dans
            FICHIERS_PROTEGES + le dossier modeles/ — jamais autre chose.
            Exige une confirmation explicite en plus du niveau de réaction
            configuré, pour éviter toute suppression accidentelle.
            """
            if self.niveau_reaction_max != "suppression" or not confirmation_explicite:
                return "Suppression refusée : niveau non autorisé ou confirmation manquante."
    
            for nom_fichier in FICHIERS_PROTEGES:
                chemin = BASE_DIR / nom_fichier
                if chemin.exists():
                    chemin.unlink()
    
            self._journaliser_violation("SUPPRESSION des fichiers protégés — violation confirmée et grave.")
            return "Fichiers protégés de MIRA supprimés. Aucun autre fichier n'a été touché."

    Garde-fous appliqués à cette fonctionnalité elle-même

    • La suppression n’est jamais le premier niveau de réaction, toujours un dernier recours après verrouillage
    • La liste des fichiers concernés par une suppression est explicite et fermée (FICHIERS_PROTEGES) — impossible d’étendre accidentellement à d’autres fichiers du client
    • Toute violation est journalisée (logs/violations.log), consultable par toi pour comprendre ce qui s’est passé
    • Le mode créateur (toi) n’est jamais concerné par ces vérifications
Affichage de 1 message (sur 1 au total)
  • Vous devez être connecté pour répondre à ce sujet.
Retour en haut