Vulnérabilités XSS Markdown : étapes sûres pour sanitiser le rich-text
Les vulnérabilités XSS dans Markdown peuvent se cacher dans les commentaires et notes. Apprenez la sanitisation HTML sûre, les restrictions d’embed et comment tester de vrais payloads avant le déploiement.

Pourquoi Markdown et le rich-text peuvent devenir un problème de sécurité
Markdown et les éditeurs rich-text semblent sûrs parce qu’ils ressemblent à du texte. Mais beaucoup d’apps font la même chose en coulisses : elles prennent ce que l’utilisateur a tapé, le convertissent en HTML, puis affichent cet HTML dans le navigateur d’une autre personne.
C’est à cette dernière étape que les ennuis commencent. Si un attaquant parvient à glisser du HTML que le navigateur interprète comme du code, il peut exécuter du JavaScript dans la session d’un autre utilisateur. C’est le XSS (cross-site scripting) en termes simples : le script de l’attaquant s’exécute comme s’il venait de votre site, avec les accès de la victime.
Les commentaires, notes et réponses du support sont des chemins d’attaque courants parce qu’ils sont faciles à poster (souvent sans revue), vus par beaucoup de personnes (admins, collègues, clients) et stockés pour être réaffichés plus tard. Un mauvais message peut nuire pendant des mois.
Le plus délicat, c’est que les éditeurs Markdown et rich-text génèrent souvent du HTML inattendu. Un simple collage depuis Google Docs peut apporter des balises et attributs étranges. Certains setups Markdown autorisent le HTML brut volontairement. D’autres éditeurs génèrent des attributs que vous n’aviez pas prévu. Si votre app rend directement cette sortie, vous pouvez vous retrouver avec des vulnérabilités XSS Markdown même quand l’interface a l’air inoffensive.
Un exemple réaliste : un fondateur ajoute une fonctionnalité de notes où les collègues collent des extraits et formatent du texte. Quelqu’un colle du contenu qui inclut un gestionnaire d’événement comme onerror sur une image. Si votre renderer le conserve, à chaque fois qu’un admin ouvre cette note, le navigateur exécute le payload.
Le rendu de contenu est une fonctionnalité de sécurité, pas juste un choix de formatage.
Les risques XSS de base dans le contenu généré par les utilisateurs
Le XSS survient quand votre app affiche une entrée utilisateur comme si c’était du contenu de confiance. Avec Markdown et le rich-text, le risque augmente parce que vous convertissez souvent l’entrée en HTML puis l’affichez dans le navigateur d’un tiers.
Pour les commentaires, notes et profils, le problème le plus fréquent est le XSS stocké. Quelqu’un poste un « commentaire » contenant du HTML ou du JavaScript furtif. Votre serveur l’enregistre, et chaque personne qui consulte ce fil exécute le code de l’attaquant.
Le XSS réfléchi est l’autre type courant : le payload est renvoyé immédiatement (souvent depuis une URL ou un champ de recherche). C’est aussi important, mais le XSS stocké est celui qui continue à vous nuire dans le temps.
Les victimes ne sont pas que des utilisateurs au hasard. Le personnel est souvent plus à risque parce qu’il voit plus de contenu : modérateurs, agents support, admins qui ouvrent des tableaux de bord montrant des posts d’utilisateurs.
Si un XSS stocké passe, un attaquant peut voler des cookies de session ou des tokens d’accès, lire des données privées affichées dans l’UI (messages, e‑mails, infos de facturation), effectuer des actions au nom de la victime (poster, supprimer, modifier des réglages) ou tromper les utilisateurs avec une fausse interface (phishing à l’intérieur de votre site).
« Seuls des utilisateurs internes peuvent y accéder » reste risqué. Les comptes internes ont souvent plus de privilèges, réutilisent des mots de passe et sont intégrés à d’autres systèmes. Un commentaire malveillant peut rapidement sauter d’un utilisateur peu privilégié à un compte staff.
Un exemple simple : un utilisateur poste une note qui semble normale, mais elle contient un gestionnaire d’événement caché dans une balise autorisée. Quand un agent support clique pour développer la note, le payload s’exécute et envoie silencieusement leur session à l’attaquant. C’est ainsi que des vulnérabilités XSS Markdown deviennent de véritables prises de compte.
Où le HTML non sûr se faufile
La plupart des équipes s’attendent à des problèmes seulement si elles autorisent le HTML brut. La surprise, c’est qu’on peut rencontrer des vulnérabilités XSS Markdown même lorsque les utilisateurs ne tapent que du Markdown « normal ».
Les fonctionnalités Markdown compilent en HTML que le navigateur interprétera si vous ne le nettoyez pas. Les liens et images sont les plus problématiques : un [text](...) ou  apparemment inoffensif devient une balise \\u003ca\\u003e ou \\u003cimg\\u003e. Le risque vient souvent moins de la balise que du schéma d’URL et des attributs qui s’y retrouvent.
Certains parseurs Markdown autorisent aussi des blocs HTML bruts par défaut. Cela signifie qu’un utilisateur peut coller \\u003cimg onerror=...\\u003e ou \\u003csvg\\u003e directement dans un commentaire et que cela passe inchangé, puis s’exécute lors du rendu. Même si vous pensez « on échappe le HTML », vérifiez les réglages du parser et les plugins qui peuvent le réactiver.
Les éditeurs rich-text peuvent être pires car ils génèrent du HTML qui a l’air inoffensif au premier abord. Une courte phrase en gras peut inclure des attributs supplémentaires, des styles inline et des balises étranges que votre sanitizer doit comprendre correctement. Une erreur courante est d’autoriser des balises « sûres » tout en oubliant des attributs dangereux, comme les gestionnaires d’événements (onload, onclick) ou des attributs portant des URLs qui peuvent cacher des javascript:.
Le copier-coller depuis Google Docs ou Notion génère souvent du balisage désordonné. Les utilisateurs collent du texte formaté, et soudain vous avez des spans imbriqués, du CSS inline et des attributs méta qui ne faisaient pas partie de votre plan. Ce HTML supplémentaire augmente la probabilité d’un contournement ou de dommages imprévus par votre sanitizer.
Lors de la revue, concentrez-vous sur les points d’entrée qui posent fréquemment problème : HTML brut activé dans le parser Markdown ; liens ou images dont l’URL n’est pas restreinte à des schémas sûrs ; listes d’« attributs autorisés » trop larges ; plugins ajoutant des fonctionnalités HTML (tables, mentions, embeds) ; et chemins de collage acceptant du HTML complet plutôt que du texte brut.
Choisir un modèle de contenu sûr avant de choisir un sanitizer
La plupart des bugs XSS stockés viennent d’un décalage : vous pensiez enregistrer « commentaires », mais votre système stocke en fait des mini‑pages web. Avant de choisir une librairie, décidez ce que les utilisateurs sont autorisés à exprimer.
Une manière pratique de raisonner sur les vulnérabilités XSS Markdown est de choisir un modèle de contenu et de s’y tenir :
- Texte brut : le plus sûr et le plus simple. Vous pouvez toujours supporter des sauts de ligne et un autolink basique.
- Markdown limité : adapté à la plupart des produits. Autorise la mise en forme (gras, italique, listes, code) mais reste prévisible.
- Rich-text complet (style HTML) : risque le plus élevé. Ne le choisissez que si vous avez vraiment besoin de mises en page complexes.
Une fois décidé, écrivez vos règles sous forme d’allowlist. Pour du Markdown limité, un ensemble typique sûr est : p, strong, em, ul, ol, li, code, pre, et a. Gardez la liste volontairement courte.
Soyez explicite aussi sur ce qui est toujours refusé. Les évidents : script, iframe, object, embed, et style. Mais de nombreuses balises « normales » peuvent être dangereuses selon votre configuration, surtout tout ce qui peut charger du contenu distant ou affecter la page.
Les attributs demandent la même rigueur. Par exemple, les liens ne devraient autoriser que href, et vous devez rejeter tout ce qui ressemble à un gestionnaire d’événement (onclick, onerror, etc.).
Comment sanitiser le HTML en toute sécurité (sans tout casser)
La façon la plus sûre de traiter les vulnérabilités XSS Markdown est de partir du principe que le contenu utilisateur et vos dépendances évolueront. Votre parser Markdown se met à jour, les navigateurs changent et des balises « inoffensives » peuvent acquérir de nouveaux comportements.
C’est pour ça que ne sanitiser qu’à l’enregistrement est risqué. Sanitizez aussi au rendu, pour que l’ancien contenu reste sûr après une mise à jour de dépendance ou un changement de configuration.
Une règle pratique : préférez une allowlist. Les blocklists ratent souvent des cas limites (nouvelles balises, attributs étranges, particularités des navigateurs). Une allowlist répond clairement à la question : « Qu’autorisons‑nous dans les commentaires ? » En général, c’est du formatage basique, des liens simples et rien qui puisse exécuter du code.
Avant de sanitiser, normalisez ce que vous allez nettoyer. Les attaquants utilisent des astuces comme des caractères encodés et des espaces bizarres pour contourner les filtres. Décodez les entités, normalisez l’Unicode et parsez en un véritable arbre HTML (pas avec des regex). Puis exécutez le sanitizer sur cette représentation normalisée pour éviter d’être trompé par des orthographes alternatives.
Un workflow qui évite la plupart des cassures :
- Parsez le Markdown en HTML avec une librairie de confiance.
- Normalisez et décodez le HTML (entités, Unicode, espaces dans les attributs).
- Sanitizez avec une allowlist (balises + attributs + schémas d’URL).
- Rendu de la sortie sanitizée, et appliquez en parallèle une Content Security Policy stricte.
- Journalisez ou signalez le contenu qui est fortement épuré (souvent signe de sondage).
Gardez vos règles de sanitizer en un seul endroit et traitez-les comme du code. Versionnez la config, ajoutez un court changelog et écrivez quelques tests qui affirment ce qui est conservé vs supprimé. Exemple : si vous décidez plus tard d’autoriser \\u003cimg\\u003e, modifiez l’allowlist et mettez à jour les tests, puis re‑sanitisez au rendu pour que les anciens commentaires ne deviennent pas soudainement dangereux.
Verrouillez liens, images et styles
Les liens, images et le style sont là où le Markdown « sûr » se transforme souvent en XSS stocké. Même si vous nettoyez les balises HTML, traitez chaque URL et chaque valeur de style comme des entrées non fiables.
Commencez par les liens. Une ancre normale peut devenir une attaque si vous autorisez des schémas d’URL risqués comme javascript: ou data:. La règle la plus sûre : n’autoriser que https: (et peut‑être http: pour des outils internes ou dev), et rejeter tout le reste. Normalisez et décodez avant de vérifier, car les attaquants utilisent des mélanges de casse et des caractères encodés.
Si vous ouvrez les liens utilisateur dans un nouvel onglet avec target=\"_blank\", sécurisez-les. Sans rel adéquat, la nouvelle page peut contrôler l’onglet d’origine (tabnabbing). Faites-en un comportement par défaut de votre renderer plutôt que de compter sur les auteurs.
Les images ne sont pas « juste des images ». Un src peut pointer vers des pixels de tracking, des ressources internes réseau ou des schémas étranges. Si vous autorisez les images, restreignez les schémas src et envisagez de proxier les images pour que le navigateur ne les récupère pas directement depuis des serveurs contrôlés par un attaquant.
Le style est un danger discret. Même quand le CSS ne peut pas exécuter de script, il peut masquer des avertissements, déplacer des boutons ou rendre une fausse boîte de connexion crédible. Pour la sécurité des commentaires rich-text, préférez une allowlist minime de mise en forme (gras, italique, listes) et évitez de laisser les utilisateurs définir du CSS arbitraire.
Un ensemble de règles pratique :
- Autoriser seulement
https:(optionnellementhttp:) danshrefetsrc; bloquerjavascript:,data:,file:etblob:. - Si
target=\"_blank\"est utilisé, forcerrel=\"noopener noreferrer\". - Supprimer les
styleinline et bloquer totalement\\u003cstyle\\u003e. - Limiter le support des images, ou proxier/cache les images côté serveur.
- Définir des limites claires : longueur maximale d’URL, nombre max d’attributs, nombre max d’éléments.
Exemple : une app de notes rend du Markdown et autorise les images. Un attaquant poste un « diagramme utile » qui se charge depuis son serveur, enregistre chaque vue et utilise du CSS pour cacher le vrai bouton « Supprimer la note » sous une fausse invite de « Réauthentification ». Corriger ces vulnérabilités XSS Markdown, c’est traiter ces risques comme des priorités produit, pas comme des cas marginaux.
Embeds : le moyen le plus rapide d’autoriser involontairement l’exécution de script
Les embeds paraissent innocents car ils ressemblent à « juste une vidéo » ou « juste un tweet ». En pratique, ils sont l’un des moyens les plus rapides de transformer du contenu utilisateur en XSS stocké, surtout quand le Markdown ou le rich-text autorise le HTML brut. Beaucoup de vulnérabilités XSS Markdown viennent d’une exception ajoutée pour les iframes.
Si vous supportez les embeds, décidez d’emblée quels fournisseurs sont autorisés et ce que « embed » signifie dans votre app. « N’importe quel iframe » n’est pas une fonctionnalité. C’est un trou de sécurité.
Un modèle plus sûr : l’utilisateur colle une URL normale, votre serveur la vérifie contre une allowlist, puis votre serveur génère le HTML d’embed final. N’acceptez pas de balises iframe fournies par l’utilisateur ni d’attributs arbitraires comme srcdoc, onload ou allow.
Règles pour garder les embeds utiles sans donner une surface de scripting :
- Autoriser seulement des fournisseurs spécifiques (par hostname et motif de chemin), et bloquer tout le reste.
- Générer le HTML d’embed côté serveur à partir d’un template propre, pas à partir du HTML utilisateur.
- Désactiver les iframes inline dans les commentaires/notes sauf raison très solide.
- Si vous devez permettre un iframe, imposez des limites de taille fixes et un
sandboxstrict. - Supprimer tous les gestionnaires d’événements et attributs risqués ; n’autorisez jamais les URLs
javascript:.
Même avec sandboxing, souvenez‑vous que les embeds chargent du contenu tiers. Traitez‑les comme une frontière séparée.
Testez de vrais payloads XSS avant de déployer
Les sanitizers ont l’air corrects dans une démo rapide, puis échouent face aux entrées étranges que les vrais utilisateurs créent. Avant de déployer commentaires ou notes, exécutez un petit ensemble de tests répétables qui tentent de casser votre renderer et vos règles de sanitisation HTML.
Commencez par tester avec trois rôles et trois vues. Utilisez un utilisateur normal qui peut poster du contenu, puis vérifiez ce que voit un modérateur et ce que voit un admin. Le XSS stocké se déclenche souvent seulement quand quelqu’un d’autre charge la page, surtout dans les dashboards, files de modération, aperçus d’e-mails ou panneaux d’activité récente.
Utilisez une courte suite de payloads couvrant des contournements courants (ne vous fiez pas à un ou deux payloads évidents). Par exemple, essayez des caractères encodés (entités HTML, attributs en casse mixte), des balises malformées ou non fermées (pour embrouiller le parseur), des balises imbriquées (balise extérieure sûre, balise intérieure dangereuse), des URLs dangereuses dans les liens (javascript: ou data:) et des attributs gestionnaires d’événements (comme onerror) sur n’importe quelle balise que votre sanitizer autorise.
Gardez vos tests réalistes : le contenu doit toujours s’afficher s’il est inoffensif, mais ne doit jamais exécuter de code. Un bon contrôle : « Ce commentaire s’affiche‑t‑il comme texte ou balisage sûr, sans popups, redirections, appels réseau ou changements d’UI inattendus ? »
Vérifiez aussi le comportement sur tous les endroits où le contenu est affiché. Un sanitizer appliqué dans l’éditeur mais pas dans l’e‑mail de notification, ou appliqué sur la page de commentaire mais pas dans le tableau admin, est un chemin classique pour du XSS stocké.
Erreurs courantes qui causent du XSS stocké
Le XSS stocké survient généralement quand vous supposez que le contenu utilisateur est « déjà sûr » parce qu’il provient d’un éditeur sophistiqué. Un WYSIWYG peut toujours produire du HTML dangereux (ou être contourné), et les parseurs Markdown permettent souvent des cas limites surprenants. C’est pourquoi les vulnérabilités XSS Markdown apparaissent dans des produits qui « ne prennent en charge que des commentaires ».
Un piège commun est de n’assainir que côté client. Le nettoyage côté client est facile à contourner par une requête directe à votre API ou en rejouant une requête depuis un autre appareil. Si le serveur stocke du contenu non nettoyé, vous avez un XSS stocké prêt à se déclencher partout où ce contenu est affiché.
Autre erreur : autoriser du HTML brut dans le Markdown pour garder des fonctionnalités (boutons personnalisés, iframes, styles sophistiqués). Ce choix transforme silencieusement votre fonctionnalité Markdown en un service d’hébergement HTML. Même si vous supprimez les balises évidentes comme \\u003cscript\\u003e, les attaquants peuvent utiliser des gestionnaires d’événements (onerror), des URLs trompeuses ou des payloads basés sur SVG selon ce que vous autorisez.
Une source fréquente d’incidents : des « renderers secondaires » oubliés. Vous pouvez sanitiser la page principale, mais pas la vue admin, pas le template d’e‑mail et pas le flux d’export PDF.
Les schémas de défaillance récurrents : traiter la sortie de l’éditeur comme donnée de confiance et la stocker telle quelle ; nettoyer uniquement côté client puis sauvegarder le contenu brut côté serveur ; utiliser des sanitizers différents (ou des allowlists différentes) selon les endroits ; rendre le même contenu sauvegardé dans HTML, e‑mail et outils admin sans re‑vérifier ; et logger ou prévisualiser du HTML brut dans des tableaux de bord internes.
Exemple : un utilisateur poste un « commentaire inoffensif » contenant une image avec un attribut spécialement conçu. La page publique est sûre, mais le panneau admin utilise un renderer différent pour la modération, et le payload s’exécute quand le personnel ouvre la file.
Liste de contrôle rapide pour sécuriser commentaires et notes
Les commentaires et notes sont souvent les premiers endroits où apparaissent des vulnérabilités XSS Markdown, car ils semblent anodins et sont déployés rapidement. Avant de les activer pour des utilisateurs réels, faites un passage rapide avec une mentalité sécurité.
Checklist qui attrape la plupart des problèmes XSS stockés :
- Confirmez que le HTML brut est soit entièrement désactivé dans Markdown, soit sanitizé après rendu. Ne comptez pas sur « l’éditeur ne le générera pas ».
- Utilisez une allowlist pour les balises et attributs. Bloquez tous les gestionnaires d’événements comme
onclicket évitez les attributs risqués commestylesauf si vous les filtrez strictement. - Validez et normalisez les URLs dans
hrefetsrc. Rejetez les schémasjavascript:etdata:(et tout ce que vous n’autorisez pas explicitement). - Verrouillez les embeds. Si vous autorisez des iframes ou la fonctionnalité « coller un lien vidéo », imposez des règles strictes et envisagez d’afficher juste des liens.
- Vérifiez tous les endroits où le contenu apparaît, pas seulement la page principale : vues admin, e‑mails de notification, webviews mobiles, exports (PDF/print) et tableaux de bord internes.
Après la checklist, faites un petit test fumée avec de vrais payloads. L’objectif n’est pas de « voir une boîte d’alerte ». C’est de confirmer que votre sortie reste inerte partout.
Essayez quelques entrées connues dangereuses (balises script, attributs gestionnaires d’événements, URLs bizarres) et confirmez qu’elles s’affichent en texte ou sont supprimées. Vérifiez la version stockée dans la base de données est sûre, pas seulement l’aperçu. Répétez le test côté admin, car les admins voient souvent plus de contenu et ont plus de privilèges.
Scénario exemple : une fonctionnalité de commentaire simple qui devient XSS
Un fondateur lance un widget de feedback : les utilisateurs peuvent laisser des commentaires en Markdown sur chaque page. Ça paraît sûr car « c’est juste du texte », et l’aperçu ressemble à ce qu’on attend.
Pour supporter le rich text, l’app convertit le Markdown en HTML puis l’affiche sur le dashboard admin. Quelqu’un a aussi ajouté des fonctionnalités « sympas » : autolink des URLs, support des images et un embed rapide pour les vidéos.
Un attaquant poste un commentaire qui paraît normal dans le widget, comme un rapport de bug avec un lien. Mais le Markdown contient du HTML que le convertisseur conserve, ou il cache un payload dans un attribut d’une balise autorisée. Rien n’arrive pour l’attaquant. Plus tard, quand un admin ouvre le dashboard, le commentaire exécute du code dans le navigateur de l’admin.
La suite est rarement subtile. L’attaquant peut voler la session admin et prendre le contrôle du compte, lire des feedback privés ou des notes internes affichées sur la même page, et modifier des réglages (webhooks, clés API) en utilisant les permissions de l’admin.
Un design plus sûr l’aurait empêché avant le déploiement. Traitez les commentaires comme des données non fiables et verrouillez ce que « rich text » signifie réellement : convertissez le Markdown en un sous‑ensemble HTML limité, sanitizez avec une allowlist stricte, supprimez ou réécrivez les attributs risqués (surtout les gestionnaires d’événements et certains schémas d’URL), désactivez les embeds par défaut (ou n’autorisez qu’un petit ensemble de fournisseurs avec des règles strictes), et testez de vrais payloads dans la vue admin exacte, pas seulement dans le widget public.
Prochaines étapes : déployez en sécurité et demandez un second avis
Si vous voulez déployer commentaires ou notes sans surprises, traitez le rich-text comme une fonctionnalité qui nécessite un petit plan de sécurité, pas comme une option UI rapide.
Commencez par consigner vos décisions pour les appliquer partout : choisissez un modèle de contenu (texte brut, Markdown sans HTML ou HTML sanitizé), définissez les éléments et attributs autorisés (soyez strict ; la plupart des apps ont besoin de très peu), verrouillez les embeds dès le départ (ou attendez d’avoir le temps), créez un petit jeu de payloads XSS correspondant à vos fonctionnalités (liens, images, blocs de code, mentions) et décidez où la sanitisation a lieu (le serveur doit être la source de vérité).
Ajoutez ensuite une porte de déploiement. Le but est simple : aucun déploiement sans que vos payloads sauvegardés ne s’affichent sans danger dans l’UI réelle. Cela attrape des problèmes que les tests unitaires manquent, comme un plugin Markdown côté client qui réactive silencieusement le HTML brut.
La porte de déploiement peut rester légère. Exécutez le jeu de payloads sur les flux de création, édition et aperçu. Vérifiez le rendu dans le navigateur, pas seulement les réponses d’API. Confirmez que les mêmes règles s’appliquent partout où le contenu utilisateur apparaît (feed, e‑mail, vues admin). Ajoutez un test de régression pour chaque bug trouvé afin qu’il reste corrigé.
Si votre app a été générée ou aidée par des outils comme Lovable, Bolt, v0, Cursor ou Replit, partez du principe que les valeurs par défaut peuvent être incohérentes. Un écran peut utiliser un renderer sûr, un autre une librairie différente ou un mode aperçu qui autorise le HTML brut.
Si vous voulez un second avis à faible friction, FixMyMess (fixmymess.ai) se concentre sur le diagnostic et la réparation de codebases générées par IA, y compris les chemins de rendu Markdown et rich-text dangereux, et peut commencer par un audit de code gratuit pour repérer les risques de XSS stocké et problèmes associés avant le déploiement.
Questions Fréquentes
Why can Markdown be a security risk if it’s “just text”?
Markdown is généralement converti en HTML, et cet HTML est rendu dans le navigateur d’un autre utilisateur. Si une partie de l’entrée survit comme HTML exécutable ou contient des attributs dangereux, cela peut devenir un XSS stocké, même si l’éditeur semble être « juste du texte ».
What type of XSS is most common with comments and notes?
Il s’agit en général de XSS stocké : un commentaire ou une note malveillante est enregistré, puis s’exécute plus tard quand quelqu’un d’autre la consulte. C’est pire que le XSS réfléchi car cela peut continuer à toucher des administrateurs, agents de support et clients longtemps après la publication initiale.
Where does unsafe HTML usually sneak in with Markdown or rich-text?
Le support de HTML brut est la cause principale, mais les liens et images non restreints (schémas d’URL dangereux) posent aussi problème. Le collage depuis un éditeur rich-text peut introduire des balises et attributs inattendus que votre nettoyeur ne traite pas comme prévu.
What’s the safest “content model” to choose for user comments?
Par défaut, choisissez Markdown limité : autorisez la mise en forme de base et les liens, et rejetez le reste. Gardez la liste des éléments autorisés courte et explicite pour éviter d’héberger des mini-pages web dans les commentaires.
Should I sanitize on save, on render, or both?
Sanitisez aussi au rendu, pas seulement à l’enregistrement. La sanitisation au rendu protège le contenu ancien si votre parser Markdown, votre configuration de sanitizer ou le comportement des navigateurs change.
How do I make Markdown links safe against `javascript:` tricks?
Autorisez seulement des schémas sûrs comme https: (et éventuellement http: dans des cas contrôlés) après décodage et normalisation. Bloquez javascript:, data:, file: et autres schémas inattendus — ce sont des méthodes courantes pour dissimuler de l’exécution dans des liens Markdown apparemment normaux.
Are images in Markdown dangerous, or just annoying?
Si vous devez permettre des images, traitez src comme non fiable : restreignez les schémas et envisagez de proxier les images pour que le navigateur ne récupère pas directement des URL contrôlées par un attaquant. Si les images ne sont pas indispensables, la façon la plus sûre est de les désactiver.
What’s the safest way to support embeds (videos, tweets, etc.)?
N’acceptez pas du HTML iframe arbitraire envoyé par les utilisateurs. Une approche plus sûre : laissez l’utilisateur coller une URL normale, puis faites valider côté serveur et générez un extrait d’embed propre pour les fournisseurs autorisés seulement.
What’s one mistake teams make when they “sanitize” rich-text?
Sanitisez côté serveur, pas seulement dans le navigateur. Le filtrage client est facile à contourner en appelant directement l’API, ce qui peut laisser du contenu non nettoyé en base et s’exécutant ensuite dans les vues administratives ou dans des e-mails.
How can I quickly test if my Markdown rendering is vulnerable to XSS?
Testez un petit ensemble de payloads réalistes sur tous les endroits où le contenu apparaît : page publique, écrans admin/modération, notifications et aperçus. L’objectif est que l’entrée reste inerte partout — pas de popups, redirections, changements d’UI inattendus ni d’appels réseau cachés.