Ce qu'est le registre
Chaque classe récurrente de bogue dans l'historique de FlareWatch a été distillée en un garde-fou numéroté : une règle d'un paragraphe, une justification, et un pointeur vers le lieu dans le code qui l'applique. De nouveaux garde-fous sont ajoutés lorsqu'une classe de bogue ou un motif émerge et doit être empêché de se reproduire.
Le registre est un document de travail, non du contenu marketing. Son objectif est de garder l'équipe — et la boucle d'examen axée sur l'audit que l'équipe utilise — honnête quant aux règles qui s'appliquent où. Le registre est référencé à partir des commentaires du code en ligne (par exemple, // Safeguard 24) afin qu'un lecteur de n'importe quel fichier puisse trouver la règle qui régit les lignes environnantes.
Cette page est le résumé public. Le registre complet réside dans le référentiel source aux côtés du code qu'il régit. L'objectif ici est de donner à un chercheur en sécurité, un examinateur de subventions ou un contributeur potentiel une idée des catégories que le registre couvre et du type de discipline qu'il applique.
Pourquoi un registre
Un registre de garde-fou ne justifie son existence que s'il prévient le même bogue deux fois. L'historique du registre est la réponse :
- Chaque garde-fou nomme le bogue qu'il prévient. Une règle sans incident mémorisé derrière elle n'est pas un garde-fou, c'est une préférence de style. Les préférences de style appartiennent aux règles de lint, pas au registre.
- Les garde-fous sont référencés à partir du code, pas seulement à partir de la documentation. Un changement de code qui viole un garde-fou se lit comme un drapeau au moment de l'examen, car le numéro du garde-fou se trouve dans les commentaires environnants.
- Certains garde-fous sont appliqués automatiquement. Un sous-ensemble est appliqué via des règles ESLint ou des scripts shell qui s'exécutent en CI. Les autres s'appuient sur la discipline de l'auteur plus le motif d'examen axé sur l'audit, qui s'est avéré solide en pratique.
- Le registre est validé par les tests. Plusieurs garde-fous sont épinglés par des tests de régression qui lisent les fichiers source sous forme de chaînes et affirment que les anti-motifs n'apparaissent pas. La fragilité est la fonctionnalité : une refonte future qui revient à un anti-motif échoue le test avant que la régression ne reach la production.
Catégories
Le registre est organisé par domaine. Les catégories ci-dessous sont stables ; les garde-fous spécifiques au sein de chacune sont ajoutés à mesure que de nouveaux modes de défaillance sont découverts.
| Catégorie | Ce qu'il couvre |
|---|---|
| Authentification et autorisation | Point unique de contrôle pour la validation de session, vérifications de propriété par portefeuille sur chaque route, rejet croisé entre jetons d'accès et jetons d'actualisation, contrôle d'accès aux routes administrateur. |
| Intégrité des données | Normalisation des adresses, contrats de conversion d'unités aux limites producteur/consommateur, discipline du générateur de clés et règles contre la coalescence silencieuse des défaillances en valeurs zéro. |
| Lectures on-chain | Règles d'implémentation unique pour toute valeur lue à partir d'un contrat intelligent, résolution de l'adresse du contrat à partir du registre on-chain, et règles contre la duplication de la logique de récompense. |
| Exactitude de l'affichage | Formatage centralisé des nombres, devises et dates; sécurité nulle sur chaque affichage numérique; discipline d'étiquetage APR vs. APY; discipline de taux fiscal en tant qu'effectif. |
| Alertes et notifications | Source unique de vérité pour l'évaluation des alertes entre client et serveur; listes blanches explicites pour les alertes qui se propagent aux portefeuilles observés; règles de supersession pour qu'une alerte « récompenses reçues » annule une alerte obsolète « récompenses disponibles »; synchronisation de rejet inter-appareils. |
| Persistance et cache | Règles pour déterminer si le magasin canonique est le backend clé-valeur ou localStorage; discipline de migration; cache du service worker délimité par le déploiement; exclusion dynamique explicite pour les routes qui lisent l'état actif. |
| Interface utilisateur et cycle de vie | Portails de préparation de page, planchers monotoniques qui empêchent les zéros transitoires de déplacer les soldes connus, et règles de rendu squelettique pendant les fenêtres de récupération à froid. |
| Processus et outils | Règles pour le consentement explicite au lancement de fonctionnalités, exécutions de suite complète de tests sur les modifications de surface d'alerte, enregistrement structuré dans le code côté serveur, et discipline d'examen contre les corrections de type raccourci. |
Une poignée de règles représentatives
Ce sont des résumés publics-sûrs de safeguards qui illustrent le caractère du registre. Ils sont paraphrasés et abrégés ; le texte canonique se trouve à côté du code.
Source unique de vérité pour les lectures on-chain
Toute valeur lue à partir d'un contrat intelligent — récompenses réclamables, soldes, état de stake, données d'époque, prix — est calculée par exactement une fonction dans la couche de services. Chaque fonctionnalité qui a besoin de cette valeur importe la même fonction. Si deux fonctions calculent la même valeur, l'une d'elles est incorrecte ; la règle est de la supprimer, pas d'en ajouter une troisième.
Point d'étranglement unique pour la validation de session
Chaque route authentifiée dans FlareWatch valide les cookies de session via un seul helper. Aucun gestionnaire de route ne vérifie les jetons de session indépendamment. Cet invariant est ce qui rend la révocation côté serveur universelle — il n'y a pas de portes dérobées qui contournent la vérification.
Portail de propriété par portefeuille, les deux côtés
Les routes par portefeuille vérifient la propriété côté serveur, pas côté client. L'audit initial a établi la règle parce que les travaux antérieurs avaient fermé les portails côté client mais laissé les points de terminaison côté serveur complètement sans portail. Les deux moitiés sont maintenant suivies en tant que livrables explicites distincts — fermés côté client, fermés côté serveur — pour empêcher ce mode de défaillance de se reproduire.
Utiliser des formateurs centralisés, jamais en ligne
Tous les formatages de nombres, de devises et de dates passent par un petit ensemble de helpers centralisés. Aucun composant ne formate en ligne. La règle n'a rien à voir avec le style : lorsqu'une définition de locale ou de devise unique change, chaque surface de l'application se met à jour avec elle. La dérive entre les surfaces est silencieuse et difficile à détecter jusqu'à ce qu'un utilisateur le remarque.
Les conversions d'unités sont documentées aux deux extrémités
Lorsque deux parties du système échangent des valeurs dont l'unité pourrait être ambiguë (secondes vs. millisecondes, décimal vs. pourcentage, adresses minuscules vs. checksummed), la convention est documentée à la fois chez le producteur et chez le consommateur. Un commentaire sur une seule extrémité se détériore ; seul un contrat limite qui est asserré aux deux extrémités survit à une refonte.
Une implémentation par action utilisateur
Chaque action initiée par l'utilisateur — ajouter un portefeuille surveillé, modifier un taux fiscal, rejeter une alerte, se déconnecter — a exactement une implémentation. La règle existe parce que les actions déclenchées à partir de différentes parties de l'interface utilisateur avaient l'habitude de dériver de manière subtile : un point d'entrée effacerait un cache, un autre non, et une classe de bugs « valeur obsolète après opération X » en résulterait.
Modes de défaillance qui doivent être bruyants
Certains modes de défaillance sont silencieux par nature — une récompense mal classifiée, une incompatibilité d'unités qui transforme une notification en sans effet, un enregistrement d'abandon qui ne parvient jamais au magasin clé-valeur. Autant que possible, le registre exige que les producteurs de ces valeurs déclarent leur contrat assez explicitement pour qu'un changement futur qui le violerait échoue bruyamment, dans les tests, avant d'atteindre la production.
Comment le registre évolue
- Nouvelles protections. Ajoutées lorsqu'une classe de bug réapparaît ou qu'un seul bug a coûté assez cher pour justifier une règle permanente.
- Protections supplantées. Conservées dans le registre avec un marqueur « supplantée » et un pointeur vers le remplacement, de sorte que les références historiques dans le code restent interprétables.
- Promues à partir de notes de travail. Certaines protections commencent comme des règles informelles dans un document de transmission de session et sont promues au registre une fois qu'elles ont fait leurs preuves.
- Révision trimestrielle. Les exceptions de lint temporaires et les marqueurs « à faire d'ici le prochain trimestre » sont vérifiés chaque trimestre. Tout ce qui a atteint sa fin est soit résolu, soit explicitement prorogé.
Pourquoi ceci est publié
FlareWatch publie cet aperçu, plutôt que le registre interne complet, pour deux raisons.
- Le registre interne contient des détails au niveau du code (chemins de fichiers, noms de schémas clé-valeur, horodatages d'incidents) qui sont utiles à l'équipe et à un examinateur de sécurité ayant accès au code, mais qu'il n'est pas approprié de publier sans cet accès.
- Les catégories et la discipline sont l'histoire réelle. Un examinateur de subvention ou un chercheur en sécurité évaluant FlareWatch veut savoir quel type de projet c'est, la sérieux avec lequel il aborde la justesse et à quoi ressemble sa boucle de travail — pas quel fichier contient la règle n°91.
Les chercheurs qui aimeraient discuter d'une protection spécifique, en proposer une nouvelle ou signaler une lacune sont les bienvenus pour nous contacter à [email protected].
Lectures complémentaires
- Architecture — comment FlareWatch est construit.
- Fonctionnalités de sécurité — authentification, autorisation, en-têtes, historique d'audit.