ruby 41 lines · 8 steps

Safely rendering Markdown in a Rails helper

A Rails view helper turns user Markdown into sanitized, allow-listed HTML you can trust in the page.

Explained by highlit
1module MarkdownHelper
2 ALLOWED_TAGS = %w[
3 p br strong em del a ul ol li blockquote code pre
4 h1 h2 h3 h4 h5 h6 hr img table thead tbody tr th td
5 ].freeze
6 
7 ALLOWED_ATTRIBUTES = %w[href title src alt].freeze
8 
9 def render_markdown(text)
10 return "".html_safe if text.blank?
11 
12 html = markdown_renderer.render(text)
13 sanitized = sanitize(
14 html,
15 tags: ALLOWED_TAGS,
16 attributes: ALLOWED_ATTRIBUTES
17 )
18 
19 content_tag(:div, sanitized, class: "markdown-body")
20 end
21 
22 private
23 
24 def markdown_renderer
25 @markdown_renderer ||= Redcarpet::Markdown.new(
26 Redcarpet::Render::HTML.new(
27 filter_html: true,
28 no_images: false,
29 no_styles: true,
30 safe_links_only: true,
31 link_attributes: { rel: "nofollow noopener", target: "_blank" }
32 ),
33 autolink: true,
34 tables: true,
35 fenced_code_blocks: true,
36 strikethrough: true,
37 no_intra_emphasis: true,
38 lax_spacing: true
39 )
40 end
41end
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Rendering untrusted Markdown safely means sanitizing the output HTML against an explicit allow-list, not trusting the renderer alone.
  2. 2Configuring both the renderer and a separate sanitize pass gives defense in depth against XSS.
  3. 3Memoizing an expensive object like a Markdown renderer avoids rebuilding it on every call.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Safely rendering Markdown in a Rails helper — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code