Ce qui se passe
Parameter a signalé le 18 octobre une chaîne d'attaque qui partait d'un lien /share/<id>
ordinaire. L'ouvrir suffisait : l'aperçu s'ouvrait seul, et le code de l'attaquant tournait comme
chatgpt.com en environ 4,5 secondes. La variante la plus stable demandait un clic sur Preview. OpenAI a reproduit le problème, l'a relevé de P2 à P1, puis
a confirmé le correctif le 26 octobre, avec une prime de 5 000 $. Il n'y a rien à faire côté
utilisateur, et Parameter ne fait état d'aucune exploitation.
La chaîne
Chaque pièce était défendable seule. L'aperçu HTML tourne dans un cadre séparé, sur une autre adresse, et ne peut pas lire la page principale. Mais une même conversation peut aussi contenir un graphique, qui charge MathLive dans la page principale.
Trois maillons méritent d'être regardés de près.
Le récepteur postMessage. MathLive acceptait update-setting de n'importe quelle origine, sans
vérifier la fenêtre émettrice. Le réglage en question, une disposition de clavier, pouvait contenir
du HTML, que createHTML laissait passer tel quel avant son affectation à innerHTML.
L'iframe srcdoc. Un script inséré par innerHTML ne s'exécute pas, mais un cadre srcdoc sans
attribut sandbox ouvre un nouveau document, avec l'identité de la page qui l'a créé.
La CSP. Le code en ligne était bloqué et www.youtube.com autorisé. Or
https://www.youtube.com/oembed?callback= renvoyait du JavaScript contenant le paramètre, même
pour répondre qu'il était invalide. Finir ce paramètre par ;void neutralisait l'objet d'erreur
ajouté ensuite. Parameter insiste : ce contournement n'est pas la cause, seulement le dernier verrou.
Ce que ça permettait
Le code lisait le jeton de session dans #client-bootstrap, puis appelait /backend-api/conversations
comme l'application elle-même. Parameter a envoyé hors du site un petit extrait d'une conversation jamais
partagée, en se limitant volontairement à cette preuve. Les autres actions accessibles depuis le
front-end relevaient du même périmètre.
Comment s'y prendre
Si vous affichez du contenu généré ou fourni par des tiers :
window.addEventListener('message', (event) => {
if (event.origin !== ORIGINE_ATTENDUE) return;
if (event.source !== fenetreAutorisee) return;
appliquerReglage(valider(event.data));
});- Vérifiez l'origine et la fenêtre avant tout changement d'état.
- Refusez le HTML brut dans les messages de configuration.
- Gardez
sandboxsur tout document créé à partir d'une entrée influençable. - Auditez vos dépendances : c'est une bibliothèque tierce qui avait posé ce récepteur.
- Traitez une CSP comme un filet de secours.
Source : Parameter, octobre 2026. Sujet repris le 31 octobre par Simon Willison et The Hacker News. Source en anglais.