Conception de la sécurité des mises à jour automatiques - Pourquoi HTTPS seul ne suffit pas
· Mis à jour le: · Go Komura · Développement Windows, Sécurité, Updater, Mise à jour automatique, Signature, MSIX, ClickOnce
Table des matières
- D’abord, la conclusion
- Pourquoi la mise à jour automatique est une zone à risque
- Anti-patterns
- Bonnes pratiques
- Configuration minimale sûre
- Comment aborder cela dans un projet Windows
- Liste de contrôle minimale
- Résumé
- Références
1. D’abord, la conclusion
Commençons par où les choses atterrissent généralement en pratique.
- Si les exigences le permettent, privilégier d’abord une infrastructure de mise à jour existante comme MSIX App Installer ou ClickOnce
- Si un updater maison est nécessaire, ce qu’il faut mettre en place en premier n’est pas l’interface utilisateur, mais la vérification de signature et la reprise après échec
- Traiter une information de mise à jour comme
latest.jsoncomme des métadonnées signées, et non comme un simple fichier de configuration non signé - TLS est nécessaire, mais ce n’est pas suffisant
- Fonder la décision de mise à jour non pas sur « parce que le serveur le dit », mais sur « parce que le client a vérifié et a pu juger que c’était correct »
- Séparer les clés de signature de développement et de production, et les protéger avec un HSM ou un service de signature
- En cas d’échec de mise à jour, adopter fail-closed, pas fail-open
- Un updater sans protection contre le rollback doit être considéré comme pouvant être ramené à une version vulnérable
- Si la vérification de signature ne peut pas encore être mise en place, distribuer manuellement des installateurs signés est plus sûr qu’une mise à jour automatique
En résumé, le cœur de la mise à jour automatique n’est pas « comment télécharger », mais « en qui faire confiance, où le vérifier, et comment revenir en arrière quand ça casse ».
2. Pourquoi la mise à jour automatique est une zone à risque
Une fonctionnalité ordinaire reste confinée à l’intérieur de l’application. Un updater, lui, réunit d’un coup les trois éléments suivants.
- Il va chercher des fichiers depuis l’extérieur
- Il fait confiance à ces fichiers
- Il remplace les exécutables existants
Autrement dit, un chemin d’exécution de code arbitraire est intégré au produit dès le départ.
Une idée reçue fréquente ici est : « c’est en HTTPS, donc c’est sûr ». Bien sûr, TLS est nécessaire. Mais ce qu’il protège, c’est principalement le canal de communication et la légitimité du serveur contacté. Cela ne suffit pas face au cas où le serveur de mise à jour lui-même est compromis, où un artefact erroné est déposé sur un CDN légitime, ou où un manifeste non signé est substitué.
En réalité, rien qu’en regardant les menaces recensées par TUF, les systèmes de mise à jour en comptent déjà autant que cela.
- Faire installer un logiciel malveillant arbitraire
- Le rollback, qui fait revenir à une ancienne version vulnérable
- Le freeze, qui empêche de voir les nouvelles versions
- Le mix-and-match, qui mélange des métadonnées et des artefacts mutuellement incohérents
Autrement dit, la mise à jour automatique n’est pas un « transfert de fichier », mais une « distribution de confiance ». Ce n’est qu’en concevant cet aspect que la mise à jour automatique commence à fonctionner de façon sûre.
3. Anti-patterns
Commençons par résumer les formes dangereuses fréquemment observées sur le terrain.
| Anti-pattern | Ce qui pose problème | Correction minimale |
|---|---|---|
Récupérer version.json en HTTPS et exécuter tel quel le zip / exe de l’URL |
Vulnérable à la compromission de l’origine, à la substitution de configuration, à une mauvaise livraison | Passer à une vérification côté client des métadonnées signées et des artefacts |
| Seul le binaire est signé, le manifeste ne l’est pas | L’URL, la version, le canal et l’indicateur de mise à jour obligatoire peuvent être falsifiés | Utiliser un manifeste signé incluant version / hachage / taille / canal / expiration |
| La clé de signature est placée sur un PC de développement ou dans les fichiers du CI | En cas de compromission, un malware légitimement signé peut être distribué | HSM / service de signature + flux d’approbation + journal d’audit |
| En cas d’échec de mise à jour, « ignorer l’erreur de vérification et continuer » | Le chemin le plus faible s’ouvre justement au moment d’un incident | Adopter fail-closed |
| Mise à jour par écrasement, sans conserver l’ancienne version | Une coupure de courant, un manque d’espace disque ou un échec en cours de mise à jour rend l’application incapable de démarrer | Staging + activation atomique + rollback |
| Autoriser une ancienne version sur la seule base de la comparaison de version | Le rollback vers une version vulnérable passe | Une version de release strictement croissante et la conservation de la plus haute version connue |
| Faire fonctionner l’updater entier avec les privilèges administrateur | Le rayon des dégâts est large en cas de compromission | Téléchargement/vérification à faibles privilèges, seul le remplacement délégué à un helper minimal |
| Commencer par les mises à jour différentielles | L’implémentation est complexe et les trous de vérification se multiplient | Commencer d’abord par des mises à jour en paquet complet |
Regardons cela d’un peu plus près.
3.1 S’arrêter à « c’est en HTTPS, donc ça va »
C’est le cas le plus fréquent.
- Lire
latest.jsonau démarrage - En extraire
downloadUrl - Télécharger le zip / exe
- L’extraire et le remplacer
- Terminé
Cela a l’air plausible, mais la racine de la confiance repose bien trop sur la réponse du serveur. Si le serveur de mise à jour ou la configuration de distribution est compromis, une mise à jour malveillante peut être distribuée par-dessus un HTTPS parfaitement valide.
TLS est nécessaire. Mais TLS seul ne termine pas la conception d’un updater.
3.2 C’est signé, mais le client ne vérifie pas
Même si les fichiers sont signés au moment de la release, cela ne sert à rien si le client ne regarde jamais la signature.
Un schéma fréquent est celui-ci :
- Le CI signe bien les fichiers
- Mais l’updater ne vérifie que le hachage
- Et ce hachage lui-même provient d’un manifeste non signé
Dans ce cas, au moment où le manifeste est substitué, le hachage est substitué avec lui. « On vérifie le hachage, donc c’est sûr » n’est vrai que si la provenance du hachage elle-même est protégée.
3.3 Le manifeste n’est pas signé
Ce qu’un système de mise à jour doit vraiment protéger ne se limite pas à l’exécutable lui-même. Au minimum, les informations suivantes sont dangereuses si elles sont altérées.
- version / release id
- l’URL ou le nom de fichier de la cible du téléchargement
- hachage / taille
- canal (stable / beta, etc.)
- si la mise à jour est obligatoire
- le système d’exploitation / l’architecture applicables
- la date d’expiration des métadonnées
- la version minimale requise de l’updater
Autrement dit, une bonne approche consiste à considérer que tout ce qui sert à la décision de mise à jour doit entrer dans des métadonnées signées.
3.4 Une gestion négligée de la clé de signature
La sécurité d’une fonctionnalité de mise à jour est, dans une large mesure, la sécurité de la gestion de ses clés.
Si la clé de signature de production est stockée de l’une des façons suivantes, c’est plutôt dangereux.
- Laissée dans le magasin de certificats d’un PC de développement
- Un
.pfxtéléversé comme secret du CI - La même clé privée distribuée localement à plusieurs personnes
- La signature de développement et la signature de production partagent la même chaîne de confiance
Dans ce cas, même si l’updater lui-même est correct, on ne peut pas empêcher une « mise à jour malveillante légitimement signée ».
3.5 Mise à jour par écrasement sans conserver l’ancienne version
Pour une mise à jour, la conception du cas d’échec compte davantage que celle du cas de succès.
- Le téléchargement a été interrompu en cours de route
- L’extraction a échoué
- Une coupure de courant est survenue en cours de remplacement
- La nouvelle version a démarré, mais a planté lors de sa première migration
Si l’ancienne version a disparu à ce moment-là, la récupération devient lourde. En pratique, « l’application ne démarre plus sur le terrain » pose un problème plus grave que le simple fait que « la mise à jour a échoué ».
3.6 Ne pas penser au rollback
Même une version légitime et signée peut arranger un attaquant si c’est une ancienne version vulnérable.
Par exemple :
- La version 1.8 comporte une vulnérabilité connue
- Le terrain est déjà passé à la version 2.3
- Un attaquant redistribue la version 1.8
Si cela passe, c’est dangereux, alors même que la signature elle-même est correcte.
Il ne suffit pas de vérifier « est-ce signé » ; il faut aussi vérifier « est-il acceptable d’installer cette version maintenant ».
3.7 Fail-open
C’est la chose à ne surtout jamais faire en production.
- En cas d’échec de la vérification de signature, afficher juste un avertissement et continuer
- Un indicateur caché qui permet d’ignorer les erreurs d’expiration de certificat
- Un
skipVerify=truede débogage qui subsiste en production
C’est justement lors d’un incident ou d’une attaque que ce genre d’échappatoire devient la voie principale.
4. Bonnes pratiques
4.1 D’abord, s’appuyer sur une infrastructure de mise à jour existante
Il est plus sûr de commencer par se demander si un updater maison est vraiment nécessaire.
Sous Windows, tant que les exigences le permettent, voici les options à envisager en priorité.
- MSIX + App Installer
- ClickOnce
- Store / MDM / infrastructure de distribution interne à l’entreprise
- MSI + gestion de distribution côté entreprise
La raison est simple : cela permet de reporter une bonne part de la responsabilité de la mise à jour elle-même sur la plateforme. Bien sûr, la liberté s’en trouve réduite, mais l’interface de mise à jour, le manifeste de distribution, la signature du paquet et la cohérence avec l’exploitation deviennent plus faciles à maintenir alignés.
Un updater maison devient nécessaire, par exemple, dans les cas suivants.
- Vouloir contrôler strictement plusieurs canaux : stable / beta / preview
- Vouloir un déploiement progressif ou un taux de rollout
- Vouloir contrôler finement le moment de la mise à jour pour des raisons métier propres
- Il existe une configuration qui ne s’intègre pas à MSIX / ClickOnce
Même dans ce cas, on reste plus stable en comprenant cela non pas comme « on veut de la liberté », mais comme « on assume soi-même la responsabilité de la mise à jour ».
4.2 Placer la racine de confiance du côté client
Un updater sûr ne fait pas confiance à la réponse du serveur telle quelle. Le côté client a besoin d’au moins ces deux éléments.
- Une clé publique de confiance, ou une chaîne de certificats de confiance
- Un mécanisme pour vérifier des métadonnées signées avec cette clé
Autrement dit, il faut créer une situation où le client peut confirmer non pas « le serveur dit que c’est la dernière version », mais « ces métadonnées sont bien la dernière version émise par un signataire de confiance ».
4.3 Concevoir autour des métadonnées signées
Au minimum, incluez ce qui suit dans les métadonnées de mise à jour et faites-en partie des éléments signés.
| Élément | Pourquoi l’inclure |
|---|---|
| release version / release id | Prévention du rollback, audit |
| nom de l’artefact, URL, package type | Déterminer précisément quel fichier récupérer |
| hachage, taille | Détection d’altération, détection d’une distribution corrompue |
| canal | Ne pas mélanger le beta dans le stable |
| OS / architecture cible | Empêcher une mauvaise livraison |
| minimum updater version | Arrêter les anciens updaters lors d’un changement de protocole |
| expires_at | Protection contre le freeze |
| published_at | Audit, tri des incidents |
| mandatory / optional | Protéger même la bifurcation de l’UX de mise à jour contre toute altération |
Ce qui compte ici, c’est de regrouper l’ensemble des éléments de décision de la mise à jour dans des métadonnées signées. Les incidents diminuent lorsqu’on converge vers une forme où la logique réside côté client, tandis que l’authenticité de l’information est protégée par la signature.
4.4 Vérifier aussi l’artefact lui-même
Après avoir vérifié les métadonnées, vérifiez également les points suivants sur l’artefact téléchargé.
- taille
- hachage
- signature de paquet / signature de code
- l’éditeur ou l’identifiant attendu
Si vous manipulez des PE / MSI / MSIX Windows, il est plus sûr de partir du principe que la vérification Authenticode ou de la signature du paquet se fait côté client. Pour macOS, il est plus cohérent de partir du principe que Developer ID et la notarization s’appliquent aussi sur le chemin de mise à jour.
4.5 Protéger les clés par l’exploitation, pas seulement par la fonctionnalité
La gestion des clés se distingue davantage par l’exploitation que par l’implémentation.
Au minimum, il vaut mieux séparer les éléments suivants.
- Clé de signature de développement
- Clé de signature de staging
- Clé de signature de production
Et pour la production, on souhaite concevoir jusqu’à inclure :
- un HSM
- un service de signature dans le cloud
- un système de signature avec flux d’approbation
- des journaux d’audit
- une procédure de rotation des clés
- des signatures horodatées
« Le CI signe automatiquement dès qu’un build de production passe » est pratique, mais le rayon des dégâts en cas de compromission grandit d’autant. Au minimum, il faut pouvoir tracer qui a signé quoi et quand.
Une fois l’exploitation mature, il est encore plus sûr de séparer la racine de confiance (root trust), rarement modifiée, des clés utilisées pour les métadonnées de mise à jour, resignées fréquemment. Garder la racine plutôt hors ligne et utiliser une clé distincte pour les métadonnées de mise à jour permet de réduire plus facilement le rayon des dégâts en cas de compromission d’une clé.
4.6 Fail-closed et mise à jour par étapes (staged update)
Le flux de mise à jour suit fondamentalement cet ordre.
- Récupérer les métadonnées
- Vérifier la signature, l’expiration et la version
- Télécharger l’artefact dans une zone de staging
- Vérifier le hachage / la taille / la signature
- Préparer l’activation en conservant l’ancienne version
- Basculer au redémarrage ou via un helper dédié
- Vérifier la bonne santé au premier lancement
- Effectuer un rollback en cas de problème
Ce qui compte ici, ce sont ces deux points : ne rien remplacer avant que la vérification ne soit terminée ne pas continuer en cas d’échec
4.7 Restreindre les privilèges de l’updater
Il vaut mieux éviter de faire fonctionner l’updater entier avec les privilèges administrateur.
La séparation idéale est la suivante.
- Téléchargement et vérification : privilèges faibles
- Uniquement le remplacement effectif des fichiers : un helper aux privilèges minimaux
- Le helper ne fait rien de plus que « placer un package vérifié à l’emplacement prévu »
Plus une conception nécessite une élévation de privilèges, plus elle devient dangereuse si l’on ne sépare pas clairement ce qui a été vérifié avant cette élévation.
4.8 Éliminer dès le départ le rollback, le freeze et le mix-and-match
C’est pénible à ajouter après coup, donc il vaut mieux les intégrer dès le début.
-
Protection contre le rollback Le client conserve « la plus haute metadata version / release version vue jusqu’ici » et rejette tout ce qui est plus ancien
-
Protection contre le freeze Donner une date d’expiration aux métadonnées, et rejeter des métadonnées trop anciennes
-
Protection contre le mix-and-match Maintenir la cohérence entre les éléments de métadonnées. Au minimum, fixer dans le manifeste lui-même le hachage / la taille / la version des artefacts ciblés
En complément, si vous pouvez distribuer, via des métadonnées signées, une blocklist de builds spécifiques ou une version minimale autorisée, l’endiguement en cas d’incident devient beaucoup plus rapide.
Même sans adopter TUF tel quel, ces trois propriétés restent très importantes.
4.9 Commencer d’abord par une mise à jour complète
Les mises à jour différentielles sont efficaces en bande passante, mais elles sont complexes pour une première implémentation.
- De quelle ancienne version vers quelle nouvelle version applique-t-on le différentiel
- Le hachage préalable requis avant l’application du différentiel
- Le hachage final après l’application du différentiel
- La récupération en cas d’échec en cours d’application
- Le nettoyage des applications partielles et des anciens différentiels
Tout cela s’accumule d’un coup. Pour la version initiale, remplacer en toute sécurité un paquet complet signé suffit largement.
5. Configuration minimale sûre
Même sans aller jusqu’à un TUF complet, la configuration minimale sûre d’un updater maison ressemble globalement à ceci.
5.1 Ce que détient le client
- Une clé publique root de confiance, ou une chaîne de certificats fixée
- La version actuellement en cours d’exécution
- La plus haute metadata version / release version vue par le passé
- Le canal autorisé
- La version précédente, conservée pour le rollback
5.2 Ce que renvoie le serveur
- Des métadonnées de mise à jour signées
- Des artefacts signés, ou signés par la plateforme
- Si nécessaire, des informations de blocklist / de version minimale autorisée
5.3 Flux typique
Récupérer les métadonnées
↓
Vérifier signature, expiration, version, canal
↓
Télécharger l'artefact dans le staging
↓
Vérifier taille / hachage / signature du package
↓
Activer en conservant l'ancienne version
↓
Rollback si le premier lancement échoue
Ce qui compte ici, c’est que rien ne s’établit avec la seule réponse du serveur de mise à jour. Ce qui l’établit, c’est l’ancre de confiance détenue par le client et la logique de vérification.
6. Comment aborder cela dans un projet Windows
Pour les applications Windows, il est plus simple de partir de la méthode de distribution et de raisonner à rebours.
- Si les exigences le permettent, MSIX App Installer
- Pour une application interne .NET où le per-user convient, ClickOnce
- S’il faut des services, des drivers, des shell extensions ou un contrôle de canal propriétaire, MSI + updater maison est aussi à comparer
Cependant, même en choisissant un updater maison, le travail ne diminue pas. Il augmente plutôt.
- Vérification Authenticode / signature de paquet
- Manifeste signé
- Protection contre le rollback
- Séparation des privilèges du helper de mise à jour
- Une stratégie de mise à jour pour l’updater lui-même
La forme dangereuse classique sous Windows est la ligne droite DownloadFile -> unzip -> kill process -> overwrite -> restart.
Cela peut fonctionner, mais c’est faible à la fois en sécurité et en capacité de récupération.
Faire passer les avertissements SmartScreen ou UAC via « Informations complémentaires → Exécuter quand même » n’est pas une conception de mise à jour : c’est de l’accoutumance aux avertissements. Pour bâtir un vrai chemin de mise à jour, il faut converger vers une configuration de distribution et de vérification qui déclenche peu d’avertissements, plutôt que d’habituer les utilisateurs à les ignorer.
Nous avons également organisé la comparaison des méthodes de distribution elles-mêmes dans cet article : Comment choisir une méthode de distribution pour une application Windows - Tableau de décision MSI / MSIX / ClickOnce / xcopy / updater personnalisé
7. Liste de contrôle minimale
Avant de publier un updater maison, voici au minimum ce qu’il faut vérifier.
- Les métadonnées de mise à jour sont signées
- Les métadonnées contiennent version / hachage / taille / canal / expiration
- Le client vérifie la signature et la version
- Le hachage de l’artefact et la signature de la plateforme sont vérifiés
- La clé de signature de production est séparée de l’environnement de développement
- Les journaux d’utilisation des clés et les enregistrements d’approbation sont conservés
- Des signatures horodatées sont utilisées
- La mise à jour par staging bascule en conservant l’ancienne version
- Il existe des conditions et une procédure de rollback
- En cas d’échec de vérification, l’arrêt se fait en fail-closed
- L’updater lui-même dispose d’une politique de mise à jour
- Une blocklist / une version minimale autorisée peut être distribuée
- Il existe un kill switch pour arrêter un déploiement progressif
- Le taux d’échec, le taux de rollback et les échecs de vérification de signature sont observables
Si de nombreuses cases restent vides dans cette liste, il vaut mieux d’abord consolider le modèle de confiance de la distribution plutôt que de construire l’interface de l’updater.
8. Résumé
En matière de sécurité pour une fonctionnalité de mise à jour automatique, tout se résume finalement à ceci.
Ne concevez pas la commodité de la mise à jour, mais à qui vous faites confiance, et comment le client vérifie cette confiance.
Sur cette base, voici, en gros, le jugement pratique à retenir.
- Si une infrastructure existante suffit, s’appuyer d’abord dessus
- En construisant un updater maison, mettre en place des métadonnées signées et une gestion des clés avant de se préoccuper de HTTPS
- Un updater sans récupération après échec ni rollback conçus fera souffrir en production
- L’updater n’est pas une fonctionnalité de distribution, mais la frontière de sécurité du produit lui-même
Si votre configuration actuelle ressemble à latest.json + remplacement de zip, ce qu’il faut corriger en premier n’est pas le traitement de téléchargement, mais où vous placez votre confiance.
Corriger seulement ce point change déjà considérablement le niveau de risque.
9. Références
- CISA Secure by Design Pledge
- NIST : Security Considerations for Code Signing
- NIST Secure Software Development Framework (SSDF)
- The Update Framework Specification
- TUF : Roles and metadata
- TUF : Security
- Microsoft Learn : Authenticode Digital Signatures
- Microsoft Learn : Auto-update and repair apps - MSIX
- Microsoft Learn : ClickOnce Deployment and Security
- Apple Developer : Developer ID
- CA/Browser Forum : Baseline Requirements for the Issuance and Management of Publicly-Trusted Code Signing Certificates
Sujets connexes
Voici des pages de sujets proches de cette thématique. À partir de cet article, vous pouvez accéder aux services et aux autres articles associés.
Sujets techniques Windows
Un point d’entrée qui regroupe les sujets techniques liés au développement Windows, à l’investigation de bugs et à la valorisation des ressources existantes.
Services liés à cette thématique
Développement d’applications Windows
La mise à jour automatique n’est pas une simple question d’interface utilisateur ; c’est une conception qui englobe la méthode de distribution, les privilèges, la récupération et l’exploitation. Pour un nouveau développement d’application Windows ou la révision d’un logiciel existant, nous pouvons intervenir dès l’organisation de la méthode de mise à jour.
Conseil technique et revue de conception
Vous pouvez nous consulter dès la phase de réflexion : « avons-nous vraiment besoin d’un updater maison ? », « MSIX / ClickOnce suffisent-ils ? », « où notre conception actuelle de la mise à jour est-elle risquée ? ».
Profil de l’auteur
Go Komura
Représentant, KomuraSoft LLC
Spécialisé dans le développement de logiciels Windows, le conseil technique et l’investigation de bugs, avec une force particulière dans les projets impliquant des ressources existantes et dans l’investigation de défaillances dont les causes sont difficiles à identifier.
Articles associés
Articles récents partageant les mêmes étiquettes, pour approfondir des sujets proches.
Pourquoi Windows affiche « Windows a protégé votre PC »
Pourquoi le message SmartScreen apparaît lors de la distribution d'une application Windows : signature de code, certificats EV/OV, Azure ...
Choisir une méthode de distribution d'application Windows - MSI/MSIX/ClickOnce/xcopy/Updater personnalisé
Le choix d'une méthode de distribution pour une application Windows n'est pas une question de préférence pour tel format d'installateur, ...
CI/CD pratique pour les applications WinForms / WPF — Automatiser du build à la signature et à la distribution avec GitHub Actions
Guide pratique pour mettre en place le CI/CD des applications WinForms / WPF avec GitHub Actions. Couvre un YAML minimal de build+tests s...
Quand votre application Windows maison est signalée comme un virus — gérer les faux positifs de Microsoft Defender et composer avec l'impact sur les performances
Nous détaillons la marche à suivre officielle lorsque Microsoft Defender signale à tort une application Windows développée en interne com...
Pourquoi Windows est devenu ce qu'il est aujourd'hui : l'évolution de Windows vue par un développeur
Un panorama des évolutions de Windows 95 à Windows 11, non pas comme une simple frise visuelle, mais du point de vue d'un développeur d'a...
Sujets associés
Ces pages replacent le sujet dans un contexte plus large de services et de décisions.
Thèmes techniques Windows
Portail des sujets sur le développement Windows, l'analyse des incidents et la valorisation des actifs existants.
Services liés à ce sujet
Cet article est directement lié aux services suivants.
Développement d'applications Windows
La distribution, la mise à jour, la signature, le rollback et le choix entre MSIX et ClickOnce pour une application Windows demandent de réfléchir non seulement à l'implémentation, mais aussi à la méthode de distribution et à la conception opérationnelle.
Conseil technique et revue de conception
La conception de la frontière de confiance de la mise à jour automatique, des métadonnées signées, de la gestion des clés et du comportement fail-closed relève davantage de l'organisation de l'architecture globale que d'une implémentation isolée.
Questions fréquentes
Questions souvent posées lors d’une consultation sur le sujet de cet article.
- Une mise à jour automatique n'est-elle pas sécurisée dès lors qu'elle passe par HTTPS ?
- TLS est nécessaire, mais ce n'est pas une condition suffisante. TLS protège principalement le canal de communication et la légitimité du serveur contacté ; il ne couvre pas les cas où le serveur de mise à jour lui-même est compromis, où un artefact erroné est déposé sur un CDN légitime, ou où un manifeste non signé est substitué. La décision de mise à jour ne doit pas reposer sur « le serveur l'affirme », mais sur « le client a vérifié des métadonnées signées et a pu juger qu'elles étaient correctes ».
- Que faut-il inclure dans les métadonnées de mise à jour, et signer ?
- La base consiste à regrouper l'ensemble des éléments de décision de la mise à jour dans des métadonnées signées. Concrètement : la version de la release, l'URL et le nom du fichier de l'artefact, le hachage et la taille, le canal (stable / beta, etc.), le système d'exploitation et l'architecture ciblés, la version minimale requise de l'updater, la date d'expiration des métadonnées (expires_at), ainsi qu'un indicateur précisant si la mise à jour est obligatoire. Si seul le binaire est signé et que le manifeste reste non signé, l'URL, la version ou l'indicateur de mise à jour obligatoire peuvent encore être falsifiés.
- Qu'est-ce qu'une attaque de rollback, et comment s'en protéger ?
- Il s'agit d'une attaque où un attaquant redistribue une ancienne version, pourtant légitimement signée, mais comportant une vulnérabilité connue, pour faire revenir le client à cette version vulnérable. Comme la signature elle-même est valide, la seule vérification de signature ne suffit pas à s'en prémunir. En protection, le client doit conserver la plus haute version de release qu'il a déjà vue et rejeter toute version antérieure. Il faut aussi donner une date d'expiration aux métadonnées pour empêcher les attaques de freeze qui masquent les nouvelles versions, et fixer dans le manifeste le hachage, la taille et la version de l'artefact pour éliminer également les attaques de mix-and-match.
- Faut-il développer son propre updater, ou s'appuyer sur un dispositif existant ?
- Si les exigences le permettent, il est plus sûr de privilégier d'abord une infrastructure de mise à jour existante, comme MSIX avec App Installer ou ClickOnce, car cela permet de reporter une bonne part de la responsabilité de la mise à jour sur la plateforme. Un updater maison devient nécessaire lorsqu'il existe des besoins que les infrastructures existantes ne couvrent pas, comme un contrôle strict de plusieurs canaux ou un déploiement progressif. Même dans ce cas, ce qu'il faut mettre en place en premier n'est pas l'interface utilisateur, mais la vérification de signature et la reprise après échec : respecter un comportement fail-closed qui bloque toute progression en cas d'échec de vérification, et pouvoir basculer tout en conservant l'ancienne version, pour permettre un rollback.
Profil de l’auteur
Page de présentation de l’auteur de l’article.
Go Komura
Représentant de KomuraSoft LLC
Spécialisé dans le développement de logiciels Windows, le conseil technique et l’analyse de pannes, notamment pour les systèmes existants et les incidents difficiles à reproduire.
Liens publics