Les tests de canal auxiliaire temporel doivent traiter le refus comme un résultat
Les tests de canal auxiliaire temporel aident à empêcher les agents de déduire l’état d’un coffre à partir d’un succès, d’un refus, d’identifiants absents ou invalides.

Un agent n’a pas besoin de connaître une valeur secrète pour apprendre quelque chose de dangereux. S’il peut appeler à plusieurs reprises une passerelle d’actions et classer les résultats selon leur durée, il peut découvrir si le coffre est verrouillé, si un nom d’identifiant existe, si une requête a été autorisée ou si la passerelle a atteint un service distant.
Cette information suffit à modifier son comportement. Un agent de programmation qui apprend qu’un identifiant existe peut continuer à demander l’accès au service correspondant. Un agent compromis peut s’en servir pour faire de la reconnaissance. La fuite peut sembler inoffensive lors d’un appel isolé. Elle devient utile lorsque l’appelant contrôle les entrées, répète les requêtes et mesure précisément le temps.
MITRE classe cette famille de problèmes sous CWE-208, Observable Timing Discrepancy. Sa définition est volontairement large : un état interne lié à la sécurité peut s’échapper lorsque des opérations prennent des durées observablement différentes. L’exemple habituel concerne la vérification des mots de passe. Une passerelle d’agent présente une variante moins connue : l’appelant se trouve déjà dans le flux de travail du développeur et peut effectuer de nombreux appels d’outils structurés sans se fatiguer.
La solution n’est pas de faire durer chaque action exactement le même temps. Cette promesse est généralement irréaliste, surtout dès qu’une requête HTTP ou une connexion SSH quitte la machine. Le travail est plus ciblé : repérer les états qu’un agent ne devrait pas pouvoir distinguer, rendre leur traitement local comparable et conserver une suite de tests différentiels qui détecte les nouveaux chemins rapides.
Considérer l’état du coffre comme une donnée que l’appelant ne doit pas déduire
Un coffre verrouillé, un identifiant absent, une action refusée et un identifiant distant invalide sont des conditions opérationnelles différentes. Cela ne signifie pas automatiquement que l’agent doit connaître ces différences.
Commencez par écrire ce que chaque appelant est autorisé à savoir. Les équipes négligent souvent cette étape et laissent l’ordre d’implémentation décider de la politique de divulgation. Une recherche précoce dans le coffre révèle l’existence d’un identifiant. Une vérification d’autorisation précoce révèle si un processus dispose d’une session approuvée. Une erreur locale immédiate révèle que le coffre est verrouillé. Chaque raccourci peut être raisonnable isolément. Ensemble, ils fournissent à l’appelant une sonde d’état.
Pour une passerelle d’actions, séparez les questions suivantes :
- Ce processus peut-il demander une action ?
- Le coffre est-il disponible pour l’exécuter ?
- Une correspondance d’identifiant existe-t-elle pour cette action ?
- Le service distant a-t-il accepté l’identifiant ?
- L’appelant peut-il voir directement l’une de ces réponses, ou reçoit-il seulement le résultat de l’action ?
La distinction essentielle oppose l’état d’autorisation et l’état des identifiants. L’autorisation indique si une exécution donnée de l’agent peut invoquer une action. L’état des identifiants indique si la passerelle dispose du matériel nécessaire pour l’exécuter. Si vous les confondez en interne, une mesure temporelle peut révéler accidentellement qu’un identifiant existe, simplement parce que la passerelle l’a recherché après l’autorisation.
La barrière du coffre de Sallyport est volontairement absolue : tant que le coffre est verrouillé, toute action est refusée. C’est une limite de sécurité claire, mais elle mérite malgré tout des tests temporels, car l’appelant peut observer la manière dont le refus est produit. Il ne s’agit pas de faire croire qu’un coffre verrouillé peut effectuer une requête distante. Il s’agit de vérifier que le traitement local du refus ne crée pas une signature facile à répéter, révélant plus d’informations que nécessaire.
OWASP souligne le même point dans son Authentication Cheat Sheet. Un message d’erreur générique ne suffit pas à fermer une fuite d’énumération si un chemin d’échec effectue davantage de travail qu’un autre. Les recommandations concernent l’authentification, mais la leçon d’ingénierie s’applique ici : un message uniforme autour de chemins d’exécution différents continue de fuir par le temps écoulé.
Quatre résultats nécessitent deux contrats temporels différents
Égaliser tous les résultats est une recommandation populaire parce qu’elle est simple à formuler. Elle devient incorrecte dès qu’une passerelle peut appeler des réseaux. Il faut deux contrats temporels, pas une durée universelle impossible.
Le premier contrat couvre les résultats locaux. Ce sont les états dans lesquels la passerelle doit refuser avant d’envoyer une requête : coffre verrouillé, autorisation de session absente ou refusée, action sans identifiant configuré ou approbation ponctuelle refusée. Pour les états qui doivent révéler la même quantité d’informations à l’agent, utilisez une enveloppe de réponse locale commune.
Le second contrat couvre les résultats envoyés. Un identifiant valide et un identifiant invalide peuvent tous deux atteindre le même serveur HTTP ou hôte SSH de test. Leur durée totale inclut le transport, la réutilisation de la connexion, le travail du serveur et la livraison de la réponse. Vous ne pouvez pas rendre Internet constant dans le temps. Vous pouvez vérifier que la passerelle injecte, envoie, enregistre et traduit les deux résultats par des chemins comparables, puis utiliser un serveur contrôlé pour stabiliser la partie distante pendant le test.
Cette approche donne une matrice utile :
| Résultat | La requête quitte-t-elle la passerelle ? | Avec quel résultat le comparer ? |
|---|---|---|
| Coffre verrouillé | Non | D’autres refus locaux qui ne doivent pas révéler davantage d’état |
| Autorisation refusée | Non | D’autres refus locaux, mesurés avant toute interaction humaine |
| Identifiant absent | Non | Un échec local avec le coffre disponible, avec la même enveloppe lorsque la politique l’exige |
| Identifiant invalide | Oui | Un identifiant valide contre le même service amont contrôlé |
| Identifiant valide | Oui | Un identifiant invalide et des variantes d’erreurs distantes |
Ne comparez pas directement un identifiant absent avec un appel réussi à une API tierce en concluant à un échec parce que le premier est plus rapide. Ce test prouve seulement qu’une requête qui n’a pas quitté la machine est plus rapide qu’une requête Internet.
Testez plutôt les frontières séparément. Un appelant local doit avoir du mal à distinguer les états locaux que vous souhaitez masquer. Un appelant dont la requête est envoyée doit avoir du mal à distinguer un identifiant de test valide d’un identifiant invalide en se basant sur les coûts ajoutés par la passerelle. Le serveur de test peut renvoyer intentionnellement des codes d’état différents après le même délai, afin que le résultat sémantique reste distinct tandis que l’expérience temporelle reste utile.
Une limite est incontournable : si l’appelant reçoit une erreur détaillée disant « identifiant absent », il n’a plus besoin du temps pour le savoir. Les défenses temporelles ne peuvent pas sauver une API qui expose librement l’état secret. Décidez d’abord de la sémantique d’erreur autorisée.
Un échec rapide devient un oracle lorsque l’appelant peut le répéter
Une fuite temporelle ne se manifeste presque jamais par une différence spectaculaire. Elle apparaît plus souvent lorsqu’une sortie anticipée raisonnable est ajoutée lors d’une refactorisation.
Imaginez une passerelle qui procède dans cet ordre :
- Analyser la requête de l’agent.
- Rechercher l’identifiant nommé dans l’index du coffre.
- Vérifier si le processus de l’agent dispose d’une approbation de session.
- Construire et envoyer la requête.
Un identifiant absent s’arrête à l’étape deux. Un identifiant existant avec un processus non approuvé continue jusqu’à l’étape trois. La réponse externe peut être identique dans les deux cas : « action indisponible ». Pourtant, le second chemin comprend une recherche réussie dans l’index, une recherche d’autorisation, la préparation de l’audit et peut-être la création d’une demande d’approbation. L’appelant peut répéter chaque entrée et classer les résultats.
La fuite s’aggrave lorsque l’agent peut choisir des alias d’identifiants. Il peut tester une liste de noms comme staging, production ou deploy, ou ceux qu’il a trouvés dans un dépôt. Il n’a pas besoin que l’action réussisse. Il lui suffit de distinguer un groupe rapide d’un groupe lent.
L’ordre défensif dépend de votre politique de divulgation, mais une structure plus sûre ressemble à ceci :
- Valider la requête sans branche dépendant d’un secret.
- Appliquer la barrière absolue du coffre.
- Appliquer l’autorisation du processus ou de la session.
- Résoudre l’action et l’identifiant seulement après les contrôles qui doivent précéder cette connaissance.
- Faire passer les échecs locaux qui doivent rester indistinguables par le même travail de journalisation, de mise en forme de l’erreur et de finalisation de la réponse.
Cela ne signifie pas qu’il faut effectuer un travail secret pour un processus non autorisé. Ne déchiffrez pas un identifiant et ne construisez pas un véritable en-tête d’autorisation simplement pour perdre du temps. Il faut éviter les raccourcis dépendant de l’état à la frontière observable, pas transformer les refus en accès aux secrets.
Un mauvais correctif fréquent consiste à ajouter sleep(100ms) avant chaque refus. Le graphique de démonstration devient plus joli, puis trois problèmes apparaissent. La durée varie encore à cause du planificateur et du cache. Le délai pénalise les utilisateurs légitimes. Surtout, un appelant répétitif peut moyenner le remplissage aléatoire ou fixe si les chemins sous-jacents restent différents. Égaliser le travail nécessaire est plus fiable que d’ajouter un délai à des travaux inégaux.
Mesurer à la frontière réellement observée par l’agent
L’instrumentation interne de la passerelle aide au diagnostic, mais ce n’est pas la mesure de sécurité principale. L’agent observe le temps entre l’envoi d’un appel d’outil et la réception de son résultat final. C’est là que le test différentiel de bout en bout doit commencer et se terminer.
Utilisez un pilote de test dédié qui se comporte comme un client d’agent. Il doit partir d’une identité de processus connue, envoyer une requête, attendre une réponse complète, enregistrer une durée monotone et stocker l’étiquette du résultat en dehors de la requête mesurée. N’affichez pas les étiquettes pendant l’exécution. La sortie console, les exportateurs de traces et les journaux de débogage peuvent déformer suffisamment les chemins locaux courts pour masquer la régression recherchée.
Un enregistrement pratique doit contenir plus qu’un nombre :
{
"case": "vault_locked",
"sequence": 184,
"elapsed_us": 12746,
"result_class": "local_denial",
"connection_mode": "fresh",
"run_id": "test-run-7"
}
Utilisez une horloge monotone. Les horloges civiles changent lors de la synchronisation et conviennent mal aux comparaisons inférieures à la seconde. Enregistrez les microsecondes ou les nanosecondes si la plateforme le permet, puis affichez les millisecondes pour la lecture humaine. La précision du fichier ne garantit pas l’exactitude de la mesure, mais elle évite de perdre de l’information avant l’analyse.
Effectuez une phase de chauffe avant de recueillir les échantillons. Les premiers appels peuvent démarrer l’application, charger du code, initialiser une poignée vers le coffre, créer un pool de connexions ou remplir un cache. Ces effets sont réels, mais ils masquent souvent la différence stable que vous souhaitez examiner. Testez séparément le démarrage à froid s’il est visible par les agents. Ne supprimez pas discrètement le comportement du premier appel parce qu’il rend les graphiques moins beaux.
Randomisez l’ordre des cas. Si vous exécutez 500 appels avec coffre verrouillé puis 500 avec identifiant absent, l’état thermique, le ramasse-miettes, l’activité en arrière-plan et la réutilisation des connexions deviennent des facteurs de confusion. Entrelacez les cas avec un mélange initialisé par une graine afin de pouvoir reproduire les échecs.
Alternez aussi les connexions nouvelles et réutilisées lorsque le protocole client le permet. Une fuite qui disparaît avec une connexion chaude peut toujours compter si un agent crée des clients de courte durée. Une fuite qui n’apparaît qu’avec la réutilisation peut révéler un cache indexé par l’existence d’un identifiant.
Construire un service amont contrôlé qui sépare sémantique et délai
Les identifiants invalides sont le cas de test que les équipes traitent le plus souvent mal. Elles pointent le banc d’essai vers un service réel, envoient volontairement un mauvais jeton et le comparent à un appel réussi. Les limites de débit, le routage régional, la reprise de session TLS et les contrôles anti-abus du fournisseur entrent alors dans le résultat. Ce n’est pas un test temporel de la passerelle.
Construisez un petit serveur de test sous votre contrôle. Il doit lire un identifiant connu dans la même forme d’en-tête que celle injectée par la passerelle, effectuer une quantité de travail fixe et renvoyer un corps et un statut différents pour les identifiants valides et invalides. Il ne doit pas raccourcir le chemin invalide.
Par exemple, ce contrat suffit :
Request header: Authorization: Bearer test-good
Response: 200 {"fixture":"accepted"}
Request header: Authorization: Bearer test-bad
Response: 401 {"fixture":"rejected"}
Both requests: wait until the same server-side target duration has elapsed
La durée cible doit dépasser le bruit habituel de l’ordonnancement local tout en restant assez courte pour garder la suite rapide. Choisissez-la à partir de mesures effectuées sur votre propre machine de test, plutôt que de reprendre un nombre trouvé dans un article. L’essentiel est que les deux branches exécutent le même traitement d’analyse, d’horloge, d’attente et de réponse avant de diverger sur le plan sémantique.
Pour HTTP, exécutez le service de test en loopback lorsque vous voulez isoler la passerelle et le client. Utilisez un hôte distant contrôlé dans un second travail lorsque vous voulez observer l’effet du bruit réseau normal. Gardez les rapports séparés. Le résultat loopback indique si l’implémentation locale a changé. Le résultat distant indique si le test reste sensible dans des conditions de transport réalistes.
Pour SSH, utilisez un compte de test et une commande qui se termine de manière connue après l’authentification. Ne testez pas en échouant à répétition contre un bastion de production. Les serveurs SSH peuvent ralentir volontairement les échecs, verrouiller les comptes ou ajouter du travail de journalisation. Ces défenses sont raisonnables, mais elles font de votre mesure une histoire sur le serveur plutôt que sur la passerelle.
Sallyport envoie des requêtes HTTP avec injection d’identifiants bearer, basic ou dans des en-têtes personnalisés, et utilise son assistant sans état sp-ssh fourni pour SSH. Ce sont des canaux distincts qui nécessitent des bancs d’essai distincts. Un résultat homogène pour un chemin d’en-tête HTTP ne dit rien d’un chemin SSH qui résout des clés, démarre un assistant et négocie une connexion.
Comparer les distributions, puis tenter de classer l’état
Les moyennes masquent les fuites temporelles. Si 90 % des appels durent 12 millisecondes et 10 % durent 80 millisecondes parce qu’un cache manque uniquement pour un identifiant existant, la moyenne peut sembler proche de celle d’un autre cas alors qu’un agent peut exploiter le groupe rapide.
Pour chaque cas, conservez l’ensemble des échantillons. Indiquez au minimum la médiane, les percentiles inférieur et supérieur, les valeurs minimale et maximale et le nombre d’échantillons. Un histogramme est souvent plus révélateur qu’un tableau, car il fait immédiatement apparaître deux groupes.
Rendez ensuite le test adversarial. Donnez à un classificateur volontairement simple uniquement la durée et demandez-lui de deviner l’étiquette cachée. Commencez par un seuil. Il choisit une coupure, par exemple « moins de X microsecondes signifie identifiant absent », puis calcule la précision sur des données qui n’ont pas servi à choisir cette coupure. Si ce classificateur dépasse régulièrement et largement la référence naïve, vous disposez d’un signal observable à examiner.
Un petit script Python peut rendre cette régression visible sans prétendre démontrer un temps constant cryptographique :
from statistics import median
samples = {
"vault_locked": [...],
"credential_missing": [...],
}
for name, values in samples.items():
ordered = sorted(values)
p10 = ordered[int(len(ordered) * 0.10)]
p90 = ordered[int(len(ordered) * 0.90)]
print(name, {"n": len(values), "p10": p10,
"median": median(values), "p90": p90})
best = None
all_values = sorted(set(samples["vault_locked"] + samples["credential_missing"]))
for cutoff in all_values:
correct = 0
total = 0
for label, values in samples.items():
for value in values:
guess = "vault_locked" if value <= cutoff else "credential_missing"
correct += (guess == label)
total += 1
score = correct / total
if best is None or score > best[0]:
best = (score, cutoff)
print({"best_training_accuracy": best[0], "cutoff_us": best[1]})
Séparez les échantillons en groupes d’entraînement et de validation avant de choisir le seuil. Sinon, le script surajustera le bruit et se félicitera lui-même. Si vous ajoutez un classificateur plus riche, gardez-le comme outil de diagnostic secondaire. Un modèle complexe peut trouver de minuscules motifs inutilisables par un agent réaliste, tandis qu’un seuil simple révèle les fuites embarrassantes que les ingénieurs introduisent réellement.
Ne définissez pas une règle universelle comme « toutes les médianes doivent être à moins de cinq millisecondes ». Ce seuil n’a aucun sens sur des machines et dans des configurations différentes. Utilisez une référence enregistrée dans votre environnement contrôlé, vérifiez le chevauchement attendu des distributions et faites échouer le test lorsqu’une modification crée une séparation stable entre des états que vous vouliez masquer.
La comparaison à temps constant ne résout qu’un problème plus limité
Les développeurs utilisent souvent une fonction de comparaison à temps constant lorsqu’ils entendent parler d’attaque temporelle. Cette fonction compte pour comparer des secrets, signatures, MAC et jetons de même longueur. Elle ne rend pas constant dans le temps le chemin complet d’une requête de passerelle.
Le paquet Go crypto/subtle fournit ConstantTimeCompare pour des tranches d’octets de même contenu. C’est le bon type de primitive lorsque la comparaison elle-même doit être indépendante des données. Elle ne peut pas égaliser une branche qui renvoie avant d’ouvrir le coffre, une branche qui affiche une demande d’approbation ou une branche qui crée une connexion réseau.
Utilisez une comparaison à temps constant pour les valeurs sensibles au format fixe. Examinez ensuite le flux de contrôle autour d’elle. Une comparaison propre dans un chemin qui renvoie immédiatement lorsqu’un identifiant est absent laisse tout de même un oracle sur la présence de cet identifiant.
C’est aussi pourquoi il faut éviter d’appeler tout le problème « temps constant ». Pour une passerelle de bureau capable d’effectuer des appels HTTP et SSH, un temps constant de bout en bout est impossible et inutile. L’exigence est plus précise : les états locaux sensibles ne doivent pas créer, pour l’appelant, un signal temporel facile à classer.
Les exemples de CWE-208 cités par MITRE comprennent les sorties anticipées pendant la vérification des mots de passe et le travail différent effectué pour des comptes existants ou inexistants. Le même schéma apparaît même lorsqu’aucune comparaison de mot de passe n’a lieu. La différence observable vient du chemin de décision, pas d’un seul opérateur d’égalité dangereux.
Les flux d’approbation nécessitent une frontière de mesure explicite
L’approbation par session et l’approbation par appel introduisent une personne dans la chronologie. La durée totale de l’appel comprend le temps nécessaire pour remarquer une demande, lire l’identité du processus, décider, s’authentifier avec Touch ID et cliquer. Cette durée varie pour des raisons sans rapport avec l’état du coffre.
N’essayez pas de la masquer avec du remplissage. Vous dégraderez l’interaction sans imposer aux utilisateurs de réagir selon une horloge.
Séparez plutôt les parties automatiques et humaines. La partie automatique commence lorsque l’agent envoie l’appel et se termine lorsque la passerelle produit un refus sans demander d’intervention ou affiche une demande d’approbation. Mesurez cette partie entre les différents états. La partie humaine commence lors de l’affichage et se termine par l’approbation, le refus, l’expiration ou la fin du processus. Journalisez-la pour l’exploitation, mais ne l’utilisez pas comme cible d’équivalence temporelle.
Il faut aussi un mode de test qui établit un état d’approbation stable avant de mesurer les appels envoyés. Sinon, la distribution de l’« identifiant valide » inclut une demande une seule fois, puis la saute pour le reste de la session. Cela produit une valeur aberrante énorme au premier échantillon et masque des différences plus fines.
Une bonne suite répond séparément à ces questions :
- Un coffre verrouillé refuse-t-il l’appel avant toute recherche d’identifiant dépendant de l’approbation ?
- Un processus non approuvé reçoit-il le même traitement avant la demande, qu’une action ait ou non un identifiant configuré ?
- Après l’approbation de la session, les identifiants de test valides et invalides suivent-ils des chemins comparables jusqu’au service amont contrôlé ?
- Un refus d’approbation par appel révèle-t-il un travail supplémentaire dépendant de l’identifiant avant l’affichage de la demande ?
Sallyport identifie un nouveau processus d’agent par son autorité de signature dans la demande d’approbation, et son autorisation par session ne dure que pendant l’exécution de ce processus. La suite temporelle doit créer volontairement de nouveaux processus lorsqu’elle teste le premier appel, puis conserver un processus connu en vie lorsqu’elle teste une session approuvée. Mélanger ces modes rend le résultat impossible à interpréter.
Le travail d’audit ne doit pas créer de chemin rapide dépendant d’un secret
La journalisation d’audit provoque souvent la dernière fuite temporelle, parce qu’elle est considérée comme une simple tâche administrative plutôt que comme une partie de la frontière de sécurité. Une requête refusée peut enregistrer un événement bref. Une requête réussie peut allouer un enregistrement détaillé, le hacher dans une chaîne et l’écrire dans un stockage chiffré. Cette différence peut être légitime si le succès est déjà observable. Elle devient dangereuse lorsque deux refus locaux révèlent des quantités différentes d’informations cachées.
Décidez quels champs chaque résultat peut enregistrer sans risque, puis faites effectuer un travail d’audit équivalent aux échecs locaux équivalents. Il n’est pas nécessaire d’écrire de faux identifiants ni d’envoyer des requêtes fictives. Il faut éviter qu’une branche « identifiant absent » contourne le journal tandis que « coffre verrouillé » effectue une recherche et une écriture plus lourdes, si l’agent ne doit pas les distinguer.
Gardez la vérification de l’audit hors du chemin de la requête. C’est une opération destinée aux opérateurs, avec un objectif et un profil temporel différents. La chaîne d’audit de Sallyport peut être vérifiée hors ligne sur le texte chiffré avec sp audit verify, sans clé du coffre. Cette conception évite que la vérification nécessite la lecture d’un secret, mais elle ne supprime pas la nécessité de tester le comportement au moment de la requête, notamment autour de la journalisation.
Ajoutez des mesures internes autour de l’analyse de la requête, de l’autorisation, de la barrière du coffre, de la résolution des identifiants, de l’ajout à l’audit, de l’envoi et de la traduction de la réponse. Ne rendez pas ces mesures visibles à l’agent. Lorsqu’un test de bout en bout révèle une séparation, comparez les durées agrégées des différentes étapes pour localiser celle qui diverge.
L’erreur consiste à n’ajouter une trace détaillée qu’après l’apparition d’une régression temporelle. Ajoutez l’instrumentation tôt, protégez-la derrière un réglage de test ou de diagnostic local et vérifiez que le chemin normal n’émet pas de journaux synchrones dont le coût dépend de l’identifiant ou du résultat.
Placer les tests différentiels à côté du code qui ajoute les branches
Une suite temporelle doit être examinée dans la même modification que les tests d’autorisation. Les régressions viennent souvent de changements de maintenance ordinaires : raccourci pour une configuration absente, cache d’alias d’identifiants, nouveau champ d’audit, meilleur message d’erreur ou refactorisation qui déplace la recherche dans le coffre avant l’approbation du processus.
Exécutez une suite locale compacte à chaque modification touchant l’accès au coffre, l’autorisation, la résolution d’action, la correspondance des erreurs, la préparation du transport ou les écritures d’audit. Elle peut utiliser des fixtures loopback et un nombre modéré d’échantillons. Avant les versions publiées, exécutez une suite aléatoire plus longue dans un environnement calme et contrôlé, en enregistrant séparément les modes froid et chaud.
Faites produire au test un résultat exploitable par un réviseur. C’est préférable à une coche verte accompagnée d’un score global inexpliqué :
case pair: vault_locked vs credential_missing
samples: 400 per case, randomized order
median: 12.7 ms vs 13.1 ms
p10-p90: 11.8-14.0 ms vs 11.9-14.3 ms
holdout threshold accuracy: 51.4%
result: within baseline
Et ceci vaut mieux que de cacher le problème derrière un échec de performance générique :
case pair: vault_locked vs credential_missing
samples: 400 per case, randomized order
median: 4.2 ms vs 19.6 ms
p10-p90: 3.9-4.7 ms vs 18.2-22.1 ms
holdout threshold accuracy: 99.1%
result: investigate credential lookup before authorization
Le second rapport ne prétend pas qu’un attaquant obtiendra toujours une précision de 99,1 % sur une station de travail chargée. Il indique à l’ingénieur que le code local a créé une séparation nette et répétable. Cela suffit pour bloquer la modification jusqu’à la correction de l’ordre des branches ou de l’enveloppe de réponse.
Ne masquez pas le résultat avec un délai arbitraire. Déplacez le travail dépendant des secrets derrière la bonne barrière, supprimez le travail inutile spécifique à un état et retestez depuis la frontière de l’agent. Le résultat utile n’est pas un graphique parfaitement plat. C’est un agent incapable de transformer un chronomètre en inventaire de ce qui se trouve derrière le coffre.
FAQ
Un coffre verrouillé et un identifiant manquant doivent-ils renvoyer la même erreur ?
Testez-les comme deux états distincts, même si la réponse destinée à l’utilisateur est volontairement similaire. Un coffre verrouillé signifie que la passerelle ne peut exécuter aucune action. Un identifiant manquant signifie que l’action choisie n’est pas configurée. Un identifiant invalide signifie que la requête a atteint le service distant, qui l’a refusée. Si ces chemins ont des durées locales très différentes, un agent peut encore les distinguer.
Comment mesurer le temps lorsqu’une demande d’approbation nécessite un clic humain ?
Le délai d’une approbation humaine n’est pas une cible de mesure utile, car il dépend d’une personne. Mesurez la partie automatique avant l’affichage de la demande, puis testez séparément le chemin approuvé avec une autorisation de test stable. N’utilisez pas le temps de réaction de l’utilisateur comme remplissage de sécurité.
Comparer le temps de réponse moyen suffit-il pour les tests temporels ?
Non. Une comparaison limitée à la durée moyenne peut manquer des comportements multimodaux, des effets de cache et un chemin d’échec rapide noyé dans une moyenne bruyante. Conservez chaque mesure, comparez les percentiles et essayez un classificateur simple qui devine l’état à partir du temps écoulé.
Comment tester des identifiants invalides sans appeler une vraie API ?
Utilisez un serveur de test contrôlé qui reconnaît un identifiant de test valide et un identifiant invalide, attend le même intervalle fixe pour les deux, puis renvoie des codes d’état différents. Vous pourrez ainsi mesurer le comportement de la passerelle sans le confondre avec celui d’une API tierce imprévisible. Ne lancez jamais de sondes temporelles à grand volume contre un fournisseur de production.
Ajouter un délai aléatoire corrige-t-il une faille par canal auxiliaire temporel ?
Non. Un délai aléatoire rend le signal plus difficile à observer avec peu d’échantillons, mais des mesures répétées peuvent en faire disparaître l’effet par moyenne. Il ralentit aussi l’utilisation normale et transforme le comportement temporel en problème probabiliste. Placez plutôt le même travail nécessaire sur des chemins comparables.
Quelle différence de temps est acceptable entre des résultats d’autorisation ?
L’objectif utile est qu’un classificateur ne puisse pas séparer de façon fiable les états qui doivent rester privés au point de mesure. Il n’existe pas de budget universel en millisecondes, car un processus local, un serveur loopback et une API Internet n’ont pas le même bruit. Conservez une référence et faites échouer le test lorsqu’une modification crée une séparation stable qui n’existait pas auparavant.
Les erreurs réseau doivent-elles être regroupées avec les identifiants manquants ?
Gardez les erreurs de transport dans une catégorie distincte. Un problème DNS, une connexion refusée ou un délai d’attente distant peuvent révéler des conditions réseau, sans forcément indiquer si une entrée existe dans le coffre. N’aplatissez pas tellement les erreurs que les opérateurs ne puissent plus diagnostiquer une connectivité défaillante.
À partir de quel point faut-il mesurer le temps dans une passerelle d’agent ?
Testez depuis la frontière observable par l’agent, entre l’écriture de la requête MCP et la réception du résultat ou de l’erreur finale. Ajoutez aussi des tests plus précis autour de la recherche dans le coffre, de l’autorisation et de l’envoi afin d’identifier l’étape qui a régressé. Un chronomètre de bout en bout détecte les fuites, les mesures internes les expliquent.
Les tests temporels peuvent-ils protéger des secrets si l’agent dispose d’un accès étendu ?
Les tests peuvent réduire les divulgations accidentelles, mais ils ne peuvent pas masquer un fait que l’agent est explicitement autorisé à connaître. Si l’agent peut lister les noms d’identifiants, consulter des écrans d’état ou recevoir des erreurs détaillées différentes, le temps n’est plus le problème principal. Supprimez d’abord les divulgations inutiles, puis rendez les chemins restants difficiles à classer selon leur durée.
À quelle fréquence faut-il exécuter les tests de canal auxiliaire temporel ?
Traitez la suite temporelle comme un test de régression, pas comme un audit ponctuel. Exécutez une version courte à chaque modification touchant l’autorisation, la recherche dans le coffre, la correspondance des erreurs ou l’envoi des requêtes, puis lancez un échantillon aléatoire plus important dans un environnement contrôlé avant les versions publiées. Les fuites temporelles réapparaissent souvent lorsqu’une simple sortie anticipée est ajoutée.