- En 2015, deux chercheurs ont pris le contrôle d'une Jeep Cherokee à 110 km/h depuis un ordinateur portable, via un port D-Bus exposé sans authentification sur le réseau cellulaire.
- La chaîne d'exploitation combinait D-Bus non authentifié, firmware non signé et absence de cloisonnement entre infotainment et CAN bus.
- Le CAN bus des années 80 n'a aucun mécanisme d'authentification entre calculateurs embarqués.
- Chrysler a rappelé 1,4 million de véhicules, premier rappel automobile déclenché par une faille cybersécurité.
- En Python : pydantic pour valider les entrées réseau, HMAC pour vérifier les firmwares, matrice de permissions pour le cloisonnement des systèmes.
Lecture complète : 13 min
L’été 2015. Charlie Miller et Chris Valasek sont assis devant un ordinateur portable, à des kilomètres de distance. Un journaliste de Wired roule sur une autoroute du Missouri dans une Jeep Cherokee à 110km/h.
Depuis leur ordinateur, Miller et Valasek allument la climatisation à fond. Changent la radio. Activent les essuie-glaces. Puis coupent la transmission.
Le journaliste n’a aucun contrôle sur la voiture.
Chrysler a rappelé 1,4 million de véhicules dix jours plus tard. C’était la première fois qu’un rappel automobile était déclenché directement par une faille de cybersécurité.
Comment le hack a fonctionné
La Jeep Cherokee 2015 était équipée du système Uconnect, un système d’infodivertissement connecté à internet via le réseau cellulaire Sprint. Ce système avait une adresse IP publique accessible depuis internet.
Miller et Valasek avaient passé plusieurs années à analyser ce système. Leur découverte principale : Uconnect exposait un port D-Bus sur le réseau cellulaire sans authentification. D-Bus est un système de communication inter-processus utilisé sur Linux. Sur Uconnect, il permettait de communiquer avec d’autres systèmes embarqués du véhicule, dont le système CAN bus qui contrôle les fonctions physiques.
La chaîne d’exploitation :
- Connexion au port D-Bus exposé sur internet via le réseau cellulaire Sprint.
- Accès au processus de mise à jour du firmware d’Uconnect, qui ne vérifiait pas la signature du firmware entrant.
- Injection d’un firmware modifié dans le module de contrôle de l’infodivertissement.
- Depuis ce module compromis, envoi de commandes sur le CAN bus vers les autres modules de contrôle du véhicule (transmission, freins, direction).
Le CAN bus est le réseau interne qui permet aux différents calculateurs d’un véhicule de communiquer. Il n’a pas été conçu avec la cybersécurité en tête : c’est un système des années 80, conçu pour un environnement fermé et physiquement isolé. Quand un module compromis peut envoyer des messages sur ce bus, il peut contrôler les fonctions physiques du véhicule.
Le rapport technique de Miller et Valasek, publié après leur présentation à DEF CON 2015, détaille l’ensemble de la chaîne d’exploitation.

La faille technique : une entrée réseau non validée
La faille fondamentale du hack Chrysler n’était pas la sophistication de l’attaque. C’était l’absence de validation des entrées réseau à plusieurs niveaux : le port D-Bus exposé sans authentification, le processus de mise à jour firmware sans vérification de signature, et l’absence de cloisonnement entre le système d’infodivertissement et le CAN bus.
Trois règles de sécurité élémentaires violées simultanément :
- Toute interface réseau exposée doit être authentifiée.
- Tout firmware reçu doit être signé cryptographiquement et la signature vérifiée avant installation.
- Les systèmes de divertissement et les systèmes de contrôle de sécurité doivent être physiquement ou logiquement séparés.
Aucune de ces règles ne requiert une expertise de cybersécurité avancée. Ce sont des principes de base de la conception de systèmes embarqués. Chrysler les a ignorés parce que l’infodivertissement connecté était une fonctionnalité marketing, pas un composant de sécurité critique.
Introduction à la sécurité IoT Python
Si tu construis n’importe quel appareil ou service qui reçoit des données depuis un réseau, les principes qui suivent s’appliquent directement.
Le principe de base : ne jamais faire confiance à une entrée réseau.
import socket
import json
import logging
from typing import Any
logging.basicConfig(level=logging.WARNING)
class RecepteurReseau:
"""Récepteur de données réseau avec validation systématique."""
def __init__(self, port: int, schema_attendu: dict):
self.port = port
self.schema = schema_attendu
def recevoir_et_valider(self, donnees_brutes: bytes) -> dict | None:
"""
Toute donnée réseau est traitée comme hostile jusqu'à validation.
Retourne None si la validation échoue.
"""
# Etape 1 : vérification de la taille
if len(donnees_brutes) > 65536:
logging.warning(f"Payload trop large : {len(donnees_brutes)} octets")
return None
# Etape 2 : décodage avec gestion d'erreur explicite
try:
donnees_texte = donnees_brutes.decode('utf-8', errors='strict')
except UnicodeDecodeError:
logging.warning("Données non-UTF-8 reçues : possible tentative d'injection")
return None
# Etape 3 : parsing JSON
try:
donnees = json.loads(donnees_texte)
except json.JSONDecodeError as e:
logging.warning(f"JSON invalide : {e}")
return None
# Etape 4 : validation du schéma
return self._valider_schema(donnees)
def _valider_schema(self, donnees: Any) -> dict | None:
if not isinstance(donnees, dict):
logging.warning(f"Type inattendu : {type(donnees)}")
return None
for champ, type_attendu in self.schema.items():
if champ not in donnees:
logging.warning(f"Champ manquant : {champ}")
return None
types = type_attendu if isinstance(type_attendu, tuple) else (type_attendu,)
if not isinstance(donnees[champ], types):
logging.warning(f"Type incorrect pour '{champ}'")
return None
return donnees
Valider les entrées réseau en Python
La bibliothèque pydantic est la solution standard pour la validation de données en Python. Elle remplace le code de validation manuel par des classes déclaratives.
from pydantic import BaseModel, Field, validator
from typing import Literal
import re
class CommandeIoT(BaseModel):
"""Modèle de données pour une commande IoT avec validation stricte."""
action: Literal["activer", "desactiver", "configurer"]
valeur: float = Field(ge=0, le=100, description="Valeur entre 0 et 100")
timestamp: int = Field(gt=0)
identifiant_appareil: str = Field(min_length=8, max_length=32)
@validator('identifiant_appareil')
def valider_format_identifiant(cls, v):
if not re.match(r'^[a-zA-Z0-9\-]+$', v):
raise ValueError("Identifiant invalide : caractères non autorisés")
return v
class Config:
extra = 'forbid'
# Test avec injection
try:
commande_malveillante = CommandeIoT(
action="activer",
valeur=999, # Hors limites
timestamp=1714901234,
identifiant_appareil="'; DROP TABLE vehicules; --"
)
except Exception as e:
print(f"Injection rejetée : {e}")
Vérification de signature pour les mises à jour firmware
Le hack Chrysler exploitait l’absence de vérification de signature sur le firmware. En Python, voici l’équivalent :
import hashlib
import hmac
import os
def verifier_signature_firmware(
firmware: bytes,
signature_recue: bytes,
cle_publique: bytes
) -> bool:
"""
Vérifie qu'un firmware reçu provient d'une source de confiance.
"""
signature_attendue = hmac.new(
cle_publique,
firmware,
hashlib.sha256
).digest()
return hmac.compare_digest(signature_attendue, signature_recue)
# Simulation
cle_secrete = os.urandom(32)
firmware_legitime = b"firmware v2.1.0 contenu..."
firmware_malveillant = b"firmware malveillant..."
signature_legitime = hmac.new(cle_secrete, firmware_legitime, hashlib.sha256).digest()
print(f"Firmware légitime : {verifier_signature_firmware(firmware_legitime, signature_legitime, cle_secrete)}")
print(f"Firmware malveillant : {verifier_signature_firmware(firmware_malveillant, signature_legitime, cle_secrete)}")
Chrysler n’avait pas ce mécanisme. N’importe quel firmware pouvait être injecté dans Uconnect depuis internet.
Défense en profondeur : plusieurs couches de validation
Le principe de défense en profondeur : ne jamais compter sur une seule couche de sécurité. Chaque couche compense les failles potentielles des autres.
from dataclasses import dataclass
from enum import Enum
import logging
class NiveauAcces(Enum):
DIVERTISSEMENT = "divertissement"
CONFORT = "confort"
SECURITE = "securite"
@dataclass
class CommandeVehicule:
action: str
systeme_cible: NiveauAcces
valeur: float
source: str
class ControleurAcces:
"""
Implémente la séparation que Chrysler n'avait pas :
le système d'infodivertissement ne peut PAS envoyer de commandes
aux systèmes de sécurité critiques.
"""
MATRICE_PERMISSIONS = {
"infodivertissement": [NiveauAcces.DIVERTISSEMENT],
"ecu_climatisation": [NiveauAcces.DIVERTISSEMENT, NiveauAcces.CONFORT],
"ecu_moteur": [NiveauAcces.CONFORT, NiveauAcces.SECURITE],
"conducteur": [NiveauAcces.DIVERTISSEMENT, NiveauAcces.CONFORT, NiveauAcces.SECURITE],
}
def autoriser_commande(self, commande: CommandeVehicule) -> bool:
permissions = self.MATRICE_PERMISSIONS.get(commande.source, [])
if commande.systeme_cible not in permissions:
logging.critical(
f"TENTATIVE D'ESCALADE : {commande.source} tente d'accéder à "
f"{commande.systeme_cible.value}. Commande bloquée."
)
return False
return True
controleur = ControleurAcces()
# Commande légitime
print(controleur.autoriser_commande(
CommandeVehicule("changer_station", NiveauAcces.DIVERTISSEMENT, 101.5, "infodivertissement")
)) # True
# Tentative d'escalade comme dans le hack Chrysler
print(controleur.autoriser_commande(
CommandeVehicule("couper_transmission", NiveauAcces.SECURITE, 0, "infodivertissement")
)) # False + log critique

Si Uconnect avait eu ce cloisonnement, même un firmware compromis n’aurait pas pu envoyer des commandes aux systèmes de sécurité du véhicule.
J’utilise ce principe de séparation des responsabilités sur Copyboost : le module d’analyse n’a pas accès direct à la base de données Supabase. Il passe par une couche API intermédiaire qui valide et filtre toutes les requêtes. J’en parle dans mon article sur ma stack no-code pour un SaaS solo en 2026.
Questions fréquentes
Comment le hack de la Jeep Cherokee de 2015 a-t-il fonctionné ?
Charlie Miller et Chris Valasek ont exploité une chaîne de trois vulnérabilités : un port D-Bus exposé sur internet sans authentification sur le système Uconnect, un processus de mise à jour firmware sans vérification de signature, et l’absence de cloisonnement entre le système d’infodivertissement et le CAN bus qui contrôle les fonctions physiques du véhicule. En injectant un firmware malveillant dans Uconnect, ils ont pu envoyer des commandes au CAN bus et contrôler la transmission, les freins et d’autres systèmes.
Qu’est-ce que le CAN bus et pourquoi est-il vulnérable ?
Le CAN (Controller Area Network) bus est le réseau interne qui permet aux calculateurs d’un véhicule de communiquer entre eux. Conçu dans les années 80 pour un environnement physiquement isolé, il ne dispose pas de mécanismes d’authentification : tout module connecté au bus peut envoyer des messages à tous les autres. Quand un module compromis comme Uconnect accède au CAN bus, il peut usurper des commandes provenant de n’importe quel autre calculateur.
Comment valider les entrées réseau en Python pour un projet IoT ?
Trois niveaux de validation : taille du payload (rejeter tout ce qui dépasse une limite raisonnable), validation du format et de l’encodage (UTF-8, JSON valide), et validation du schéma (pydantic avec des modèles stricts, extra='forbid' pour rejeter les champs inconnus). Ajouter une vérification de signature HMAC ou RSA pour tout firmware ou configuration reçu depuis un réseau.
Qu’est-ce que le principe de défense en profondeur en sécurité IoT ?
La défense en profondeur consiste à mettre en place plusieurs couches de sécurité indépendantes, de sorte qu’une attaque doit contourner chaque couche successivement. Pour un appareil IoT : authentification au niveau réseau, validation des données reçues, cloisonnement entre systèmes de divertissement et systèmes critiques, signature cryptographique des mises à jour, et monitoring des comportements anormaux.
Chrysler a-t-il été poursuivi en justice suite à ce hack ?
Deux recours collectifs ont été intentés contre Chrysler à la suite de la divulgation. Le Sénat américain a utilisé la démonstration pour soutenir un projet de loi sur la cybersécurité automobile, le SPY Car Act. Chrysler a rappelé 1,4 million de véhicules et distribué des mises à jour de sécurité sur clé USB. L’incident a accéléré l’adoption de standards de cybersécurité dans l’industrie automobile.
Chaque appareil connecté est une surface d’attaque
Le hack Chrysler n’était pas une attaque sophistiquée de nation-state. C’était deux chercheurs avec un ordinateur portable et plusieurs mois d’analyse d’un système qui n’avait jamais été pensé comme une cible de sécurité.
L’infodivertissement connecté était une fonctionnalité. Personne n’avait demandé : “Et si quelqu’un s’y connectait depuis internet ?”
Chaque fois que tu connectes quelque chose à un réseau, tu crées une surface d’attaque. La question n’est pas si cette surface sera testée. C’est quand, et par qui.
Trois règles à mémoriser :
- Toute entrée réseau est hostile jusqu’à validation explicite.
- Tout firmware ou configuration reçu doit être signé et la signature vérifiée.
- Les systèmes critiques et les systèmes non critiques ne doivent jamais partager la même surface d’accès.
Ces règles ne requièrent pas d’être expert en sécurité. Elles requièrent de se poser la question à chaque fois que tu ouvres un port ou que tu traites une donnée externe.
Lance un diagnostic gratuit sur copyboost.io : tes textes convertissent-ils aussi bien que ton code est sécurisé ?
Dernière mise à jour : mai 2026
Cet article fait partie de la série 10 bugs informatiques qui ont tué, crashé et coûté des milliards.
Discussion