diff --git a/Gemfile b/Gemfile
index 3b637a025385329c3bf05aff5c917c0c42e81f51..06e1e28e98aa94b2b011221fd187c93177dabca1 100644
--- a/Gemfile
+++ b/Gemfile
@@ -154,7 +154,7 @@ gem 'html-pipeline', '~> 2.13.2'
 gem 'deckar01-task_list', '2.3.1'
 gem 'gitlab-markup', '~> 1.7.1'
 gem 'github-markup', '~> 1.7.0', require: 'github/markup'
-gem 'commonmarker', '~> 0.21'
+gem 'commonmarker', '~> 0.23.2'
 gem 'kramdown', '~> 2.3.1'
 gem 'RedCloth', '~> 4.3.2'
 gem 'rdoc', '~> 6.3.2'
diff --git a/Gemfile.lock b/Gemfile.lock
index 99cd6b8bab638fa54bf56a767227ad840e28301a..78b6eedd42bf7c0f6da3ec792fa09db4d842c6c4 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -200,8 +200,7 @@ GEM
       open4 (~> 1.3)
     coderay (1.1.3)
     colored2 (3.1.2)
-    commonmarker (0.21.0)
-      ruby-enum (~> 0.5)
+    commonmarker (0.23.2)
     concurrent-ruby (1.1.9)
     connection_pool (2.2.2)
     contracts (0.11.0)
@@ -1116,8 +1115,6 @@ GEM
     rubocop-rspec (1.44.1)
       rubocop (~> 0.87)
       rubocop-ast (>= 0.7.1)
-    ruby-enum (0.8.0)
-      i18n
     ruby-fogbugz (0.2.1)
       crack (~> 0.4)
     ruby-magic (0.4.0)
@@ -1414,7 +1411,7 @@ DEPENDENCIES
   capybara-screenshot (~> 1.0.22)
   carrierwave (~> 1.3)
   charlock_holmes (~> 0.7.7)
-  commonmarker (~> 0.21)
+  commonmarker (~> 0.23.2)
   concurrent-ruby (~> 1.1)
   connection_pool (~> 2.0)
   countries (~> 3.0)
diff --git a/spec/features/markdown/markdown_spec.rb b/spec/features/markdown/markdown_spec.rb
index 3208ad82c037813a2519b0bebf57ca5fbe3de1b8..9eff02a8c1b0a7fc2aa38f8b101a42555b131f27 100644
--- a/spec/features/markdown/markdown_spec.rb
+++ b/spec/features/markdown/markdown_spec.rb
@@ -133,8 +133,9 @@ def doc(html = @html)
         expect(doc.at_css('td:contains("Baz")')['align']).to eq 'left'
       end
 
+      # note that 2 are from the hardcoded <sup>, and 2 from footnotes
       aggregate_failures 'permits superscript elements' do
-        expect(doc).to have_selector('sup', count: 2)
+        expect(doc).to have_selector('sup', count: 4)
       end
 
       aggregate_failures 'permits subscript elements' do
@@ -148,6 +149,11 @@ def doc(html = @html)
       aggregate_failures "removes `href` from `a` elements if it's fishy" do
         expect(doc).not_to have_selector('a[href*="javascript"]')
       end
+
+      aggregate_failures 'permits footnotes' do
+        expect(doc).to have_selector('section.footnotes ol li p:contains("Footnote 1")')
+        expect(doc).to have_selector('section.footnotes ol li p:contains("Footnote with w")')
+      end
     end
 
     describe 'Escaping' do
diff --git a/spec/fixtures/markdown.md.erb b/spec/fixtures/markdown.md.erb
index 100d17cc16ee2046564302587dcee0fe3046ec60..2da16408fbc8225cfa322da1b1a8a429b37f5253 100644
--- a/spec/fixtures/markdown.md.erb
+++ b/spec/fixtures/markdown.md.erb
@@ -52,6 +52,15 @@ Redcarpet supports this superscript syntax ( x^2 ).
 
 This (C<sub>6</sub>H<sub>12</sub>O<sub>6</sub>) is an example of subscripts in Markdown.
 
+### Footnotes
+
+This is footnote 1.[^f1]
+
+A footnote with a `w` was failing.[^f2-w]
+
+[^f1]: Footnote 1
+[^f2-w]: Footnote with w
+
 ### Next step
 
 After the Markdown has been turned into HTML, it gets passed through...
diff --git a/spec/lib/banzai/pipeline/full_pipeline_spec.rb b/spec/lib/banzai/pipeline/full_pipeline_spec.rb
index 72661003361eaf4355277374c6c5c188fd92e61d..7a335fad3f8a8f5e919f9e3dd4e7d455ca1347b7 100644
--- a/spec/lib/banzai/pipeline/full_pipeline_spec.rb
+++ b/spec/lib/banzai/pipeline/full_pipeline_spec.rb
@@ -34,15 +34,16 @@
     let(:identifier) { html[/.*fnref1-(\d+).*/, 1] }
     let(:footnote_markdown) do
       <<~EOF
-        first[^1] and second[^second]
+        first[^1] and second[^second] and twenty[^twenty]
         [^1]: one
         [^second]: two
+        [^twenty]: twenty
       EOF
     end
 
     let(:filtered_footnote) do
       <<~EOF
-        <p dir="auto">first<sup class="footnote-ref"><a href="#fn1-#{identifier}" id="fnref1-#{identifier}">1</a></sup> and second<sup class="footnote-ref"><a href="#fn2-#{identifier}" id="fnref2-#{identifier}">2</a></sup></p>
+        <p dir="auto">first<sup class="footnote-ref"><a href="#fn1-#{identifier}" id="fnref1-#{identifier}">1</a></sup> and second<sup class="footnote-ref"><a href="#fn2-#{identifier}" id="fnref2-#{identifier}">2</a></sup> and twenty<sup class="footnote-ref"><a href="#fn3-#{identifier}" id="fnref3-#{identifier}">3</a></sup></p>
 
         <section class="footnotes"><ol>
         <li id="fn1-#{identifier}">
@@ -51,6 +52,9 @@
         <li id="fn2-#{identifier}">
         <p>two <a href="#fnref2-#{identifier}" class="footnote-backref"><gl-emoji title="leftwards arrow with hook" data-name="leftwards_arrow_with_hook" data-unicode-version="1.1">↩</gl-emoji></a></p>
         </li>
+        <li id="fn3-#{identifier}">
+        <p>twenty <a href="#fnref3-#{identifier}" class="footnote-backref"><gl-emoji title="leftwards arrow with hook" data-name="leftwards_arrow_with_hook" data-unicode-version="1.1">↩</gl-emoji></a></p>
+        </li>
         </ol></section>
       EOF
     end
diff --git a/spec/support/matchers/markdown_matchers.rb b/spec/support/matchers/markdown_matchers.rb
index dfdb5bc01ae177368dc508c3e41364f73d5d9d0e..f01c4075eebd259bde8779cc3118efed882affb9 100644
--- a/spec/support/matchers/markdown_matchers.rb
+++ b/spec/support/matchers/markdown_matchers.rb
@@ -41,7 +41,7 @@ module MarkdownMatchers
     set_default_markdown_messages
 
     match do |actual|
-      expect(actual).to have_selector('gl-emoji', count: 10)
+      expect(actual).to have_selector('gl-emoji', count: 12)
 
       emoji_element = actual.at_css('gl-emoji')
       expect(emoji_element['data-name'].to_s).not_to be_empty