Pourquoi un lien auto-destructeur peut prouver que le serveur a supprimé le texte chiffré, mais pas que le destinataire n’a pas fait de capture d’écran

Vous transformez un mot de passe à usage unique en lien auto-destructeur. L’autre personne l’ouvre, rafraîchit, et la page affiche « Brûlé ». On raconte souvent : « il a vu, plus rien ne reste ». Ce qui a brûlé, c’est le texte chiffré sur le serveur. Une copie à l’écran, une capture système, ou l’URL complète dans le fil de discussion ne passent pas par cette suppression. Ce que vous pouvez vérifier sur place, c’est si un second appel avec le même identifiant rend encore le texte chiffré.

D’abord la conclusion étroite : une fois le nombre de lectures atteint ou le lien expiré, le texte chiffré n’est plus sur le serveur ; un nouvel appel avec le même identifiant ne rend plus les octets d’origine. Cette conclusion ne soutient pas « le destinataire n’a pas fait de capture », « personne d’autre dans le canal n’a ouvert », ni « les sauvegardes de chat n’ont pas le lien complet ». Le contrôle, ce sont deux ouvertures plus Network — pas de traiter « Brûlé » comme un audit de l’autre appareil.

Répondre à l’intention de recherche en une phrase

Un lien auto-destructeur peut soutenir une seule conclusion : l’hôte ne détient plus le texte chiffré. Il ne peut pas soutenir que l’écran, le presse-papiers ou l’historique de chat du destinataire ont été effacés. Après le premier appel réussi du texte chiffré, rouvrir le même lien affiche « Brûlé » ou « Expiré ». Sous HTTP 410 Gone, la ressource cible n’est plus disponible à l’origine, et cet état est en général permanent. Cela répond à « le serveur le remet-il encore ». Cela ne répond pas à « a-t-il gardé une copie ».

Cette note s’adresse aux développeurs, à l’exploitation, et à quiconque veut séparer « le lien est mort » de « il n’a rien gardé » avant d’envoyer un mot de passe à usage unique, une clé API ou un code de récupération. Elle ne remplace pas le mode d’emploi de Burn-Link, et ne répète pas comment fabriquer une URL. Ce qu’il faut emporter : quelle couche a brûlé, ce qu’un rafraîchissement raté peut prouver, pourquoi les captures restent hors de cette couche, et comment deux ouvertures plus Network permettent de contrôler le côté hôte sur cet appareil.

« Brûlé » n’est pas la même chose que « il n’a rien gardé »

Le langage courant plie trois faits distincts dans « ce message disparaît après lecture ». Premier : le serveur ne stocke plus de texte chiffré. L’enregistrement de cet identifiant a disparu, et une requête ultérieure n’obtient que « Brûlé » ou « Expiré ». Deuxième : cet onglet n’affiche plus le texte en clair. Fermer la page, cliquer « Effacer de cette page », ou un script qui vide la zone à la sortie peuvent le faire. Troisième : l’appareil du destinataire ne détient aucune copie — pas de capture, pas de collage, pas de transfert du lien complet, pas de texte en clair recollé dans le chat.

Le lien auto-destructeur peut imposer le premier fait. Pour le second, il peut tout au plus vider l’affichage de cet onglet. Sur le troisième, il n’a aucune force. La page de lecture peut écrire qu’elle n’empêche ni la copie ni les captures. Ce n’est pas une fonction manquante : une page web ne peut pas interdire à un autre téléphone de photographier l’écran, et elle ne peut pas entrer dans le presse-papiers système ni dans la base locale d’une appli de chat après un clic sur « Copier le texte en clair ».

Donc « j’ai rafraîchi, ça ne s’ouvre plus » soutient une conclusion étroite : cet appel par identifiant n’a pas rendu le texte chiffré. Il ne soutient pas « seul ce collègue l’a vu », « il n’a pas fait de capture », ni « cette chaîne n’apparaîtra jamais dans une recherche de ticket ». Ces phrases-là demandent une autre observation : le texte en clair ou l’URL complète a-t-il quitté cet onglet — pas votre second rafraîchissement.

Quelle couche le serveur brûle réellement

Un lien à connaissance nulle sépare la localisation du déchiffrement. La forme est s.html?id={id}#{key} : la query ne porte que l’identifiant ; la clé n’est qu’après le dièse. La RFC 9110 exclut le fragment de l’URI cible de la requête. Quand le navigateur demande le document au serveur, il retire # et tout ce qui suit. Par conception, le serveur voit l’identifiant, pas la clé, et pas le texte en clair.

À la création, cet onglet utilise Web Crypto pour AES-256-GCM : une clé aléatoire de 32 octets, un IV de 12 octets, et le texte en clair empaqueté en texte chiffré sur cet appareil avant POST /secrets. Les champs sortants sont le texte chiffré, l’expiration et le nombre de lectures. La clé n’apparaît que dans l’URL de partage assemblée ensuite. Un élément est plafonné à 32 Ko. L’expiration peut être 1 heure, 24 heures, 7 jours, ou une destruction uniquement après lecture. Le nombre de lectures va de 1 à 10, 1 par défaut. Créer et lire sont prêts à l’emploi. Il n’y a ni compte, ni identité de connexion pour « qui a ouvert ».

À la lecture, une fois le texte chiffré remis et le nombre fixé atteint, le serveur le supprime. Quand vous rouvrez le lien, vous voyez « Brûlé » ou « Expiré ». Cela prouve que l’hôte ne détient plus ces octets chiffrés. Cela ne prouve pas que la clé n’a jamais figuré dans l’historique du chat, que le texte en clair n’a jamais touché l’autre écran, ou qu’un tiers n’a jamais cliqué « Ouvrir et afficher » sur la même URL complète.

Quiconque détient l’URL complète détient encore la clé. Coller https://…/s.html?id=…#… dans un canal, c’est remettre à la fois l’identifiant et la clé. Même après que le serveur a brûlé le texte chiffré, cette suppression ne peut pas reculer une personne qui a déjà ouvert et gardé le clair. S’il reste des lectures, un clic plus tard peut encore récupérer le texte chiffré. Brûler le texte chiffré traite le stockage durable chez l’hôte. Cela ne traite pas « tous ceux qui ont vu la chaîne entière ».

Ce qu’un rafraîchissement raté peut prouver — et ce qu’il ne peut pas

Un second ouvert qui échoue n’est pas un seul statut. Distinguez trois messages. « Brûlé » : le texte chiffré n’est plus là, soit parce que le nombre de lectures a été consommé, soit parce que l’identifiant n’était jamais valide. « Expiré » : le TTL choisi à la création est écoulé, donc le serveur a supprimé l’enregistrement même si personne n’a lu. « Clé de fragment manquante » : l’identifiant peut encore exister, mais cet appareil ne peut pas déchiffrer. Slack, Teams, WhatsApp et certains clients mail coupent tout ce qui suit #. Le destinataire voit alors « Clé de fragment manquante », ce qui n’est pas le même événement que « quelqu’un d’autre a déjà lu ».

410 Gone signifie que la ressource cible n’est plus disponible à l’origine, et que cet état est probablement permanent. La page de lecture scinde le 410 en « Brûlé » et « Expiré » : si la réponse marque expired, c’est le TTL ; sinon, c’est traité comme brûlé. Un 404 s’affiche aussi comme « Brûlé », parce que le résultat pour le destinataire est le même — le texte chiffré ne peut plus être récupéré. Une erreur réseau n’est pas une destruction : si la coupure arrive après « Ouvrir et afficher », et que la création n’autorisait qu’une lecture, le texte chiffré a peut-être déjà été emporté alors que cet onglet n’a jamais déchiffré.

Donc « ça ne s’ouvre plus chez moi » soutient ceci : un appel avec cet identifiant ne rend plus le texte chiffré. Il ne soutient pas : l’ouvreur était le collègue nommé ; il n’a pas copié ; il n’a pas fait de capture ; un robot d’aperçu ou un scanner de sécurité n’a pas consommé une lecture d’abord. Sans comptes, il n’y a pas d’accusé de lecture nominatif. Le compteur vit sur le serveur. Ce n’est pas un audit de l’appareil du destinataire.

N’expérimentez pas avec un vrai mot de passe, une clé API ou une chaîne de connexion non masquée. Écrivez une phrase qui n’existe que pour ce contrôle. Vous comparez l’appel de statut, la récupération du texte chiffré et le message de la seconde ouverture — pas besoin d’exposer à nouveau un secret vivant.

Pourquoi captures, copies et historique de chat restent hors de cette couche

Une fois le texte en clair peint à l’écran, la question quitte « le serveur a-t-il encore le texte chiffré » et devient « que s’est-il passé sur l’autre terminal ». Une capture système, un enregistrement d’écran, ou un second téléphone pointé vers l’affichage n’envoie aucune requête à l’hôte. La page de lecture ne peut pas intercepter ces actions, et elle ne peut pas vous prévenir ensuite. Ce n’est pas une case produit inachevée. Une page web ordinaire n’obtient pas d’interrupteur qui interdit à l’autre personne d’enregistrer son propre écran.

La copie reste du même côté de la clôture. La page de lecture peut proposer « Copier le texte en clair », et elle peut vider la zone quand vous partez. Ce qu’elle vide, c’est ce nœud DOM — pas le presse-papiers système, ni un brouillon de chat. macOS et certaines méthodes de saisie gardent un historique du presse-papiers. « Effacé de cette page » signifie seulement que cet onglet n’affiche plus la phrase. Cela ne signifie pas que la phrase n’est jamais entrée dans le presse-papiers.

L’historique de chat est un magasin séparé. Si le lien complet est apparu dans un canal, l’historique du groupe, la recherche, la synchro multi-appareils et un export ultérieur peuvent tous remontrer la clé après le dièse. Même après que le serveur a brûlé le texte chiffré, l’URL reste la preuve que le lien a un jour fonctionné, et elle suffit à faire cliquer encore quelqu’un qui ignore que le compteur est épuisé, puis à conclure « le lien est cassé ». La couche HTTP peut rester propre — Referer ne doit pas porter de fragment — mais cette protection a déjà disparu pour quiconque peut ouvrir le fil.

Les tickets, le courrier et l’historique du navigateur suivent la même coupure. Un fragment # apparu dans la barre d’adresse atterrit en général dans l’historique local ; un navigateur connecté peut synchroniser cette ligne vers d’autres appareils. Fermer l’onglet n’efface pas l’historique. Le lien auto-destructeur raccourcit le temps pendant lequel le serveur garde un blob, et il limite le nombre de fois où le même texte chiffré peut être récupéré. Ce n’est pas de la gestion des droits numériques, et ce n’est pas un rapport d’expertise.

Pourquoi une requête de statut ne consomme pas de lecture

Si le premier chargement de la page d’arrivée récupérait le texte chiffré, un aperçu de chat, une passerelle de sécurité mail ou un scanner d’entreprise pourrait consommer la seule lecture avant que le destinataire clique. Il verrait alors « Brûlé », même si la clé n’a jamais été donnée à l’hôte d’aperçu. Ce qui a brûlé, c’est le compteur de lectures, pas le secret du fragment. Une note précédente explique pourquoi le dièse reste hors de HTTP par défaut. Celle-ci reste sur le compteur : une requête d’aperçu et une vraie récupération du texte chiffré doivent être séparées, sinon « Brûlé » ne peut même pas soutenir « le destinataire l’a vu ».

La page de lecture FastPwd scinde ces étapes. Ouvrir la page ne demande que /secrets/{id}/status : le texte chiffré est-il encore là ? Elle n’emporte pas le blob. Après que le destinataire clique « Ouvrir et afficher », l’onglet fait GET /secrets/{id} et déchiffre en local avec la clé après le dièse. Si la clé # manque, la page ne récupère pas le texte chiffré, afin de ne pas gaspiller les lectures restantes. Ni la page de création ni la page de lecture n’exigent de compte.

Les robots d’aperçu tirent en général la page d’arrivée et ne cliquent pas le bouton. Cela abaisse le risque « aperçu égale brûlé ». Cela ne prouve pas que chaque scanner s’arrête là. Dans Network, vous devriez voir d’abord un appel de statut, puis une récupération du texte chiffré ; un chargement sans clic ne devrait pas montrer un emport réussi du blob. Le compteur reste un compteur côté serveur. Il ne fait pas partie du fragment.

Ce que vous voyez Ce que cela peut soutenir Ce que cela ne peut pas soutenir
Une seconde ouverture affiche « Brûlé » Un appel avec cet identifiant ne rend plus le texte chiffré Le destinataire n’a pas fait de capture et n’a pas copié
La page affiche « Expiré » Le TTL est écoulé et le serveur a supprimé l’enregistrement Quelqu’un l’a lu avec succès
La page affiche « Clé de fragment manquante » L’adresse n’a pas de clé après # Le texte chiffré a déjà été emporté
La page a chargé ; le bouton n’a pas été cliqué Une requête de statut ne devrait pas consommer de lecture Chaque robot d’aperçu refusera de récupérer le texte chiffré
Network ne montre que du texte chiffré au POST Cette création n’a pas envoyé la phrase d’origine comme champ métier Après collage du lien complet dans le chat, vous seul pouvez encore le voir
Le texte en clair a été effacé de cette page Cet onglet n’affiche plus cette phrase Le presse-papiers et les captures sont vides aussi

Contrôler maintenant : deux ouvertures, statut et Network

Un slogan n’est pas une preuve. Préparez un canari jetable, par exemple canary-fp-20260905-burn-vs-shot. Ne réutilisez pas un mot de passe vivant. Laissez le nombre de lectures à 1 par défaut, et gardez l’expiration à 24 heures.

  1. Placez le canari sur la page de création et générez un lien. Ouvrez Network dans DevTools et cochez Preserve log. Cherchez le canari et la clé après le dièse séparément : le corps de POST /secrets doit contenir le texte chiffré, l’expiration et le nombre de lectures — pas la phrase d’origine ni la clé.
  2. Ouvrez la page de lecture avec le même lien complet. Ne cliquez pas encore « Ouvrir et afficher ». Network doit montrer /secrets/{id}/status et ne doit pas montrer un GET /secrets/{id} réussi qui a emporté le blob. La page doit attendre la confirmation.
  3. Cliquez « Ouvrir et afficher ». C’est seulement alors que le texte chiffré doit être récupéré par identifiant et déchiffré sur cet appareil avec AES-256-GCM. La note de succès dira que le serveur a supprimé ce texte chiffré — ou, si vous avez monté le compteur au-dessus de 1, que la suppression attend que ce nombre soit atteint.
  4. Rafraîchissez la page de lecture, ou ouvrez le même lien dans un contexte de navigateur neuf. Avec une lecture, vous devriez voir « Brûlé ». Cherchez à nouveau dans Network : la récupération du texte chiffré doit renvoyer 410 ou une réponse traitée comme brûlée. Le canari ne doit plus réapparaître en clair dans aucun corps de requête.

Ces quatre étapes prouvent un seul changement : entre deux ouvertures que vous contrôlez, le texte chiffré sur le serveur est passé de présent à absent. Elles ne prouvent pas que, s’il s’était agi d’un vrai mot de passe pour un collègue, il n’aurait pas fait de capture. « Gardera-t-il une copie » appartient à la note de passation — pas de capture, ne pas recoller le clair dans le canal, faire tourner le secret après usage — pas à l’espoir que « Brûlé » auditera son terminal à votre place.

N’envoyez pas le lien complet et le texte chiffré par le même chemin. Placez un fichier .lock sur un disque ou dans un mail, et envoyez la phrase secrète par Burn-Link. Ne déposez pas l’URL Burn-Link complète dans les notes de ce dossier. Si la clé et le coffre voyagent dans le même message, brûler le texte chiffré n’aidera personne qui a déjà vu la chaîne entière.

Trois façons de lire « Brûlé » trop loin

Première : traiter « Expiré » comme la preuve que quelqu’un a lu. La création a utilisé 1 heure ; le collègue a cliqué le lendemain ; la page dit « Expiré ». Le serveur a supprimé le texte chiffré, mais la raison est le TTL, pas un compteur de lectures épuisé. Un contenu non lu qui a expiré ne peut pas être récupéré. Ce n’est pas la même chose que « il a déjà été ouvert ».

Deuxième : traiter un fragment manquant comme déjà brûlé. Slack, Teams et certains clients mail coupent tout ce qui suit #. Le destinataire ouvre s.html?id=… sans clé. La page de lecture ne récupère pas le texte chiffré sans clé. Si vous ouvrez plus tard le lien complet, le contenu peut encore être là. Demandez-lui de renvoyer la chaîne qui inclut le dièse. Ne concluez pas « quelqu’un est arrivé avant ».

Troisième : traiter « Effacer de cette page » comme un effacement global. La page de lecture peut vider la zone à la sortie, et elle peut utiliser history.replaceState pour retirer le fragment de la barre d’adresse. Cela ne change que ce que cet onglet affiche, et si un rafraîchissement ultérieur porte encore la clé. Les captures système, l’historique du presse-papiers, les sauvegardes de chat et l’historique synchronisé du navigateur restent hors de cet effacement.

Questions fréquentes

S’il rafraîchit et voit « Brûlé », cela veut-il dire qu’il n’a rien gardé ?

Non. Cela signifie seulement que le texte chiffré n’est plus sur le serveur : un nouvel appel par identifiant ne rend plus les octets d’origine. Une capture, une copie, un enregistrement d’écran, une sauvegarde de chat ou le transfert du lien complet ne passent pas par cette suppression. « Brûlé » n’est pas la preuve que l’appareil du destinataire est propre.

L’aperçu d’un chat peut-il brûler le secret avant le destinataire ?

Un aperçu charge en général seulement la page d’arrivée. La page de lecture demande d’abord si le texte chiffré est encore là, sans l’emporter ; « Ouvrir et afficher » est ce qui récupère le texte chiffré par identifiant. La plupart des robots d’aperçu ne cliquent pas ce bouton à votre place, mais vous ne pouvez pas supposer que chaque scanner s’arrête à la page d’arrivée. Le nombre de lectures est un compteur côté serveur. Le contrôle : sur un chargement sans clic, Network ne doit pas montrer un emport réussi du texte chiffré.

Un lien auto-destructeur peut-il prouver qui a ouvert le lien ?

Non. Créer et lire n’exigent aucun compte, et le serveur n’étiquette pas le lecteur par une identité de connexion. Ce que vous pouvez vérifier, c’est si l’identifiant a encore du texte chiffré après un appel. Vous ne pouvez pas inverser « Brûlé » en un nom, et vous ne pouvez pas l’écrire comme un accusé de lecture.

Faut-il s’inscrire pour créer ou lire ? Le texte en clair est-il envoyé ?

Non. Cet onglet chiffre avec AES-256-GCM, puis envoie le texte chiffré. La clé se place dans le fragment #. Cherchez un canari dans Network : le corps doit contenir le texte chiffré, pas la phrase d’origine ni la clé après le dièse. Au-delà de 32 Ko, ou pour un fichier entier, utilisez le chiffrement de fichier sur cet appareil. Ne traitez pas un lien auto-destructeur comme un disque.

Rejouer le même canari sur un outil prêt à l’emploi

Si vous voulez une page qui écrit la frontière de calcul au grand jour, ouvrez Burn-Link de FastPwd. Aucun compte n’est requis. Collez le canari ci-dessus, laissez le nombre de lectures à 1, générez le lien, et terminez les deux ouvertures de la section de contrôle. Surveillez Network en même temps : vous devriez voir le POST de texte chiffré à la création, le statut sur la page de lecture, la récupération après le clic, et une réponse brûlée à la seconde ouverture. Vous ne devriez pas voir la phrase d’origine ni la clé après le dièse comme champ métier.

N’empruntez ce chemin que lorsqu’un mot de passe doit atteindre un collègue. Vous pouvez d’abord générer le mot de passe aléatoire dans le générateur de mots de passe, en local, longueur 6–128, 16 par défaut ; en dessous de 8, un avertissement indique une sécurité plus faible. La génération n’est pas envoyée. Un contrat entier, un scan de pièce d’identité, ou tout ce qui dépasse 32 Ko appartient au chiffrement de fichier, avec le même AES-256-GCM vers .lock / .enc, un fichier jusqu’à 5 Go. Envoyez la phrase secrète seule, par un lien auto-destructeur. Ne l’écrivez pas dans les notes du disque.

Avant le prochain envoi, retenez trois faits. Premier : « Brûlé » prouve que le texte chiffré n’est plus sur le serveur — pas que l’autre personne n’a pas fait de capture. Deuxième : charger la page d’arrivée ne devrait pas consommer de lecture ; « Ouvrir et afficher » est ce qui récupère le texte chiffré. Troisième : une fois le lien complet collé dans le chat, la clé après le dièse est visible pour quiconque peut voir ce message. Seule une observation que vous pouvez répéter mérite d’entrer dans votre propre note de passation.

Pour aller plus loin

Pourquoi la partie après le dièse reste hors de HTTP par défaut, et quelle couche tombe quand vous collez le lien entier, est dans Pourquoi un fragment d’URL peut porter une clé, et quand cette protection lâche. « Chiffrement local, rien n’est envoyé » n’est pas une preuve tant que vous n’avez pas cherché un canari dans Network : Vérifier que le chiffrement local n’envoie pas le texte en clair. S’il faut encore masquer des numéros de pièce dans un ticket avant qu’ils quittent cet appareil, voir Avant de coller un ticket ou un journal dans une IA, vérifier quels champs quittent cet appareil.