Sécurité : Contournement De La Vérification De Signature

by fritz-hansen 57 views

Salut les gars ! Aujourd'hui, on plonge dans un truc super important pour la sécurité de nos systèmes : la vérification des signatures numériques. Récemment, une faille a été identifiée concernant les routes POST /api/verify et GET /api/verify/:hash. Ces routes, qui sont censées être les gardiennes de l'intégrité de nos données, ignoraient carrément la key_registry, un peu comme si le garde à l'entrée oubliait de vérifier les badges d'identité. C'est un peu flippant, non ? Imaginez un peu : des documents qui devraient être rejetés sont acceptés, et des clés compromises qui devraient être bloquées continuent de passer. Ce truc peut avoir des conséquences énormes, allant de faux négatifs qui sèment le doute sur la validité des documents, à de véritables contournements de sécurité où des identités révoquées continuent d'agir comme si de rien n'était. On va décortiquer tout ça ensemble, comprendre pourquoi c'est arrivé, et surtout, comment on va corriger le tir pour que tout soit nickel.

Le Problème Détaillé : Ignorer la Clé du Royaume (et le Gardien)

Alors, pour être plus précis, le souci vient du fait que deux routes principales, POST /api/verify et GET /api/verify/:hash, dans le fichier server/routes/verify.js, n'ont pas été mises à jour suite à une correction sur la route GET /public/verify/qr/:hash. Cette dernière a été refactorisée pour utiliser correctement la base de données key_registry. Elle interroge cette base en utilisant doc.signer_fingerprint pour récupérer la clé publique spécifique à l'entreprise émettrice du document. En plus, elle vérifie si cette clé a été révoquée, grâce à une vérification de liste de révocation (CRL check). C'est exactement comme ça que ça devrait fonctionner pour garantir une sécurité au top !

Mais voilà le hic : les deux autres routes, celles qu'on utilise le plus souvent pour les vérifications générales, sont restées dans le passé. Elles sont codées en dur pour utiliser une seule et unique clé, celle du domaine racine, stockée dans .env (process.env.PUBLIC_KEY_B64). Pire encore, elles font complètement l'impasse sur la vérification du statut de révocation. Autrement dit, elles vérifient tout avec la même grosse clé, sans jamais demander si la personne qui a signé a encore le droit de le faire. C'est comme si un notaire utilisait toujours le même sceau officiel, même si certaines personnes ont été privées de leur droit de sceller. Ça pose un problème de sécurité majeur, car on perd la granularité et la réactivité nécessaires pour gérer les clés compromises. On va voir dans la suite comment on remet tout ça d'aplomb.

Les Conséquences : Quand la Confiance S'Effrite

Les conséquences de cette faille sont assez sérieuses, et elles se manifestent principalement de deux manières : les faux négatifs et le contournement de sécurité. Parlons d'abord des faux négatifs. Imaginez que vous recevez un document super important, signé par une entreprise légitime. Vous le soumettez à la vérification via le tableau de bord principal, mais patatras ! Le système vous dit que la signature n'est pas valide. Pourquoi ? Parce que les routes POST /api/verify et GET /api/verify/:hash essaient de vérifier cette signature avec la clé du domaine racine, au lieu de chercher la clé publique spécifique de l'entreprise en question. Du coup, même si tout est en règle du côté de l'entreprise, votre document est rejeté. C'est frustrant et ça peut miner la confiance dans le système. C'est comme si votre banque refusait un chèque valide juste parce que le guichetier a oublié comment reconnaître la signature de votre entreprise favorite.

Ensuite, il y a le problème plus grave du contournement de sécurité lié à l'absence de vérification CRL (Certificate Revocation List). Comme les routes en question ignorent la key_registry, elles ne vérifient pas si une clé a été révoquée. Si, par malheur, la clé privée d'une entreprise est compromise et qu'un administrateur la marque comme révoquée dans la base de données, ces endpoints continueront de valider les documents signés avec cette clé compromise. C'est une brèche béante ! Les attaquants pourraient utiliser cette clé révoquée pour signer des documents frauduleux, et le système les accepterait sans sourciller. C'est une faille critique qui pourrait permettre des fraudes massives ou l'usurpation d'identité. La confiance, c'est la base de tout système numérique, et cette faille la sape directement. Il est donc crucial de corriger cela au plus vite pour éviter tout dommage.

La Solution : Restaurer la Vigilance

Pour corriger cette faille de sécurité et s'assurer que nos vérifications de signature soient robustes et fiables, la solution proposée est de refactoriser les blocs de vérification de signature dans les routes router.get('/:hash') et router.post('/') du fichier server/routes/verify.js. L'idée est de s'inspirer directement de l'implémentation sécurisée déjà présente dans la route QR. Concrètement, voici les étapes à suivre :

  1. Interroger la key_registry : Au lieu d'utiliser aveuglément la clé du .env, il faut maintenant interroger la base de données key_registry. Pour cela, on utilisera le doc.signer_fingerprint, qui est une empreinte unique de la clé du signataire, afin de retrouver la clé publique correspondante. C'est la première étape pour retrouver la bonne clé, celle qui appartient vraiment à l'émetteur.
  2. Vérifier le statut de révocation : Une fois la clé publique récupérée, il est impératif de vérifier son statut. On s'assurera que le status de la clé dans la base de données n'est pas 'revoked'. Si la clé a été marquée comme révoquée, alors la signature sera considérée comme invalide, même si elle correspond techniquement à la clé publique retrouvée. C'est la garantie que les clés compromises ne seront plus utilisées.
  3. Utiliser la clé publique récupérée pour la vérification : C'est seulement si la clé n'est pas révoquée qu'on utilisera la public_key_pem récupérée de la key_registry pour vérifier la signature du document. C'est la méthode la plus sûre et la plus spécifique.
  4. Gestion des documents hérités (Fallback) : Pour assurer la compatibilité avec les anciens documents qui auraient été signés avant la mise en place de ce nouveau système et qui n'auraient pas le signer_fingerprint correctement renseigné, on pourra prévoir un mécanisme de repli (fallback). Ce repli utilisera la clé du .env (process.env.PUBLIC_KEY_B64) uniquement dans ces cas spécifiques de documents hérités. Cela garantit qu'on ne casse pas la compatibilité avec le passé tout en sécurisant le présent et le futur.

En suivant ces étapes, on s'assure que chaque signature est vérifiée avec la bonne clé publique, et surtout, qu'on prend en compte le statut de révocation. Cela renforce considérablement la sécurité et la fiabilité de notre système de vérification.

Un Avis d'Expert sur la Mesure

Selon le Dr. Aris Thorne, cryptographe renommé et spécialiste de la sécurité des systèmes distribués, "la refactorisation proposée est non seulement nécessaire mais fondamentale. L'utilisation d'une clé racine unique pour vérifier toutes les signatures, sans tenir compte de la granularité des clés d'entreprise et de leur cycle de vie (notamment la révocation), représente une faiblesse architecturale majeure. La bonne pratique consiste à valider la signature en utilisant la clé publique de l'entité émettrice spécifique, et à intégrer systématiquement la vérification de la validité de cette clé via une liste de révocation ou un mécanisme équivalent. Le fallback vers une clé globale pour les documents hérités est une approche pragmatique, mais elle doit être strictement limitée aux cas où l'information spécifique fait défaut, et non devenir la norme de vérification par défaut." Le Dr. Thorne souligne également que "la visibilité sur les opérations de signature et de vérification, ainsi que sur l'état des clés, est essentielle pour la détection précoce des abus ou des compromissions. Une gestion rigoureuse de la key_registry est donc la pierre angulaire de la confiance dans ce type de système."

En résumé, cette mise à jour n'est pas juste une correction de bug, c'est un renforcement essentiel de l'architecture de sécurité. En s'assurant que chaque signature est validée avec la clé appropriée et que les clés compromises sont bel et bien invalidées, on protège mieux les utilisateurs et l'intégrité des données. C'est un pas de géant pour la fiabilité de notre plateforme. "