Contexte de la vulnérabilité
Le 6 mars 2023, l’équipe de sécurité de Ruby on Rails a publié le correctif du CVE-2023-28840. Cette faille, classée critical, permettait l’exécution de code à distance via la désérialisation de paramètres JSON dans Action Pack. Le correctif modifie la méthode ActionDispatch::Http::Parameters#parse_formatted_parameters afin de rejeter les objets non sécurisés. La plupart des applications Rails, y compris les portails publics, ont été invitées à mettre à jour immédiatement vers la version 7.0.5 ou 6.1.7.2.
Chronologie de l’incident
Selon le rapport de Rietta, un site gouvernemental français, construit sur Rails 6.1, a appliqué le correctif à 14 h 00. Moins de trois heures plus tard, à 16 h 45, les équipes de surveillance ont détecté une activité anormale : création de comptes administrateur et exfiltration de données de connexion. L’enquête a confirmé que l’exploitation s’est produite entre 2 et 3 heures après le déploiement du correctif, avant que le serveur ne soit redémarré.
Analyse technique de l’exploitation
L’attaque s’appuie sur un vecteur de « time‑of‑check‑time‑of‑use » (TOCTOU). Le correctif du CVE‑28840 bloque la désérialisation uniquement lors du premier appel de la méthode, mais le code du site chargeait dynamiquement des modules via require_dependency après le hot‑reload. Un acteur malveillant a injecté un payload JSON contenant un objet ActiveSupport::HashWithIndifferentAccess spécialement façonné. Le serveur, avant le redémarrage, a exécuté le code malveillant dans le contexte de l’application, contournant la validation du correctif. Cette chaîne d’événements montre que le simple déploiement du patch, sans redémarrage complet, ne suffit pas à garantir la neutralisation de la vulnérabilité.
Leçons et mesures d’atténuation
Premièrement, toute mise à jour de sécurité critique doit être suivie d’un redémarrage complet du processus Rails afin de réinitialiser la mémoire et d’effacer les modules déjà chargés. Deuxièmement, les environnements de production devraient activer la protection config.eager_load = true en production pour éviter le chargement à la volée de code non vérifié. Troisièmement, la surveillance des logs doit inclure des alertes sur les requêtes contenant des structures JSON inhabituelles, notamment les clés _rails ou _method qui ont servi de porte d’entrée dans les attaques précédentes. Enfin, la communication interne doit préciser que le délai entre le déploiement d’un correctif et le redémarrage doit être minimisé, idéalement inférieur à 30 minutes, pour réduire la fenêtre d’exposition.