# How Can I Safely Render User-Submitted Markdown Without Allowing Raw HTML?

**URL:** <https://talk.commonmark.org/t/how-can-i-safely-render-user-submitted-markdown-without-allowing-raw-html/5058>\
**Category:** Application\
**Created:** [July 26, 2025, 8:13pm UTC](https://talk.commonmark.org/t/how-can-i-safely-render-user-submitted-markdown-without-allowing-raw-html/5058 "2025-07-26T20:13:44Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ricaxa](https://cdn.commonmark.org/letter_avatar_proxy/v2/letter/r/3da27b/32.png) [@ricaxa](https://talk.commonmark.org/u/ricaxa)\
**Post date:** [July 26, 2025, 8:13pm UTC](https://talk.commonmark.org/t/how-can-i-safely-render-user-submitted-markdown-without-allowing-raw-html/5058/1 "2025-07-26T20:13:44Z")

</div>

Hello

I am working on a web application that allows users to submit content in Markdown using the CommonMark spec. One concern I have run into is handling raw HTML that users include in their submissions. 😇

While some users embed safe elements like `<br>` or `<img>`, others try injecting full HTML blocks, which poses security risks. 😇 I would like to allow Markdown input only; without allowing raw HTML to be rendered in the output.

I am using the official CommonMark parser in JavaScript; but I noticed that by default, it allows raw HTML to pass through. I came across the `disableHtml()` option in some implementations does this reliably strip all embedded HTML / should I be applying an additional sanitization layer like DOMPurify? 🤔 Checked [CommonMark Spec](https://spec.commonmark.org/0.29/) for reference . I was also reading about [what is TensorFlow](https://www.igmguru.com/blog/what-is-tensorflow) and wondered if AI could help filter unsafe Markdown content.

Also; is there a difference in behavior across CommonMark implementations in different languages? 🤔

I would really appreciate best practices from anyone who’s already implemented this safely in a production app. It’s important that I strike a good balance between usability and security, especially for user-generated content that will be public.

Thank you !! 🙂

---

<div class="post-metadata">

**Author:** ![notriddle](https://cdn.commonmark.org/user_avatar/talk.commonmark.org/notriddle/32/1237_2.png) [@notriddle](https://talk.commonmark.org/u/notriddle)\
**Post date:** [August 1, 2025, 8:36pm UTC](https://talk.commonmark.org/t/how-can-i-safely-render-user-submitted-markdown-without-allowing-raw-html/5058/2 "2025-08-01T20:36:09Z")

</div>

I think you should use a separate HTML sanitizer, like DOMpurify, and not rely on your commonmark implementation to produce safe markup. The resulting pipeline will be “commonmark → dompurify → renderer”. This is a hill I will die on: commonmark parsers that let you disable inline HTML are offering an antifeature, including the reference `cmark` implementation.

There are two reasons why it’s a bad idea to rely on your commonmark implementation as a security boundary:

1. There’s more to safely embedding UGC than just disabling inline and block HTML tags. You also need to filter out [`javascript:` and `data:` URIs](https://developer.mozilla.org/en-US/docs/Web/URI/Reference/Schemes/javascript), you need to make sure the resulting HTML is properly nested, and, if you generate `id` from user input, [need to ensure it doesn’t collide with parts of the host page](https://security.stackexchange.com/questions/88973/why-do-id-attributes-need-stricter-validation)..

2. There are expressiveness holes in commonmark that can only be filled by using HTML. You can try to fix them, but there’s _only so much punctuation on the keyboard_. You either wind up reinventing HTML but worse, or you wind up with markup that can’t actually express everything.

---

<div class="post-metadata">

**Author:** ![sarah567](https://cdn.commonmark.org/letter_avatar_proxy/v2/letter/s/8edcca/32.png) [@sarah567](https://talk.commonmark.org/u/sarah567)\
**Post date:** [March 29, 2026, 1:16pm UTC](https://talk.commonmark.org/t/how-can-i-safely-render-user-submitted-markdown-without-allowing-raw-html/5058/3 "2026-03-29T13:16:54Z")

</div>

Don’t think of CommonMark as a security barrier. It is a parser, not a cleaner.

You still have to worry about javascript: urls, malformed nesting, attribute injection, and other things even if you turn off raw HTML. Different CommonMark implementations handle edge cases in completely different ways, so relying on one flag like disableHtml() is not safe.

The safe pattern in production is:

markdown → html → clean up (using DOMPurify or something similar) → display

Clean up after rendering, not before. That way, you’re only letting the real HTML that will go to the DOM through.

This isn’t a problem that can be solved with AI or TensorFlow. This isn’t a problem with classifying things; it’s strict output sanitization. Use an HTML sanitizer that has been tested in battle and make sure your configuration is tight (allowed tags, allowed attributes, and safe URI schemes).

It’s possible to make things easy to use and safe at the same time; just don’t skip the sanitization layer.
