diff --git a/app/models/concerns/cache_markdown_field.rb b/app/models/concerns/cache_markdown_field.rb
index 6e2adc76ec65b09b234497ec17d3ff65410a3ecf..a8c9e54f00c648474b3886f9d26a377d1a429186 100644
--- a/app/models/concerns/cache_markdown_field.rb
+++ b/app/models/concerns/cache_markdown_field.rb
@@ -15,7 +15,7 @@ module CacheMarkdownField
   # Increment this number every time the renderer changes its output
   CACHE_REDCARPET_VERSION         = 3
   CACHE_COMMONMARK_VERSION_START  = 10
-  CACHE_COMMONMARK_VERSION        = 11
+  CACHE_COMMONMARK_VERSION        = 12
 
   # changes to these attributes cause the cache to be invalidates
   INVALIDATED_BY = %w[author project].freeze
diff --git a/changelogs/unreleased/security-xss-in-markdown-following-unrecognized-html-element.yml b/changelogs/unreleased/security-xss-in-markdown-following-unrecognized-html-element.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3bd8123a34658262051f4a02979854e7d7f897d9
--- /dev/null
+++ b/changelogs/unreleased/security-xss-in-markdown-following-unrecognized-html-element.yml
@@ -0,0 +1,5 @@
+---
+title: Fix possible XSS attack in Markdown urls with spaces
+merge_request: 2599
+author:
+type: security
diff --git a/lib/banzai/filter/spaced_link_filter.rb b/lib/banzai/filter/spaced_link_filter.rb
index a27f1d46863501214e6d5a5a9693fd3d394c3280..c6a3a763c239afe95744fd140b803df47a9b94d2 100644
--- a/lib/banzai/filter/spaced_link_filter.rb
+++ b/lib/banzai/filter/spaced_link_filter.rb
@@ -17,6 +17,9 @@ module Banzai
     # This is a small extension to the CommonMark spec.  If they start allowing
     # spaces in urls, we could then remove this filter.
     #
+    # Note: Filter::SanitizationFilter should always be run sometime after this filter
+    # to prevent XSS attacks
+    #
     class SpacedLinkFilter < HTML::Pipeline::Filter
       include ActionView::Helpers::TagHelper
 
diff --git a/lib/banzai/pipeline/gfm_pipeline.rb b/lib/banzai/pipeline/gfm_pipeline.rb
index be75e34a6730badf498f75d6b097acac1c157d66..96bea7ca9351ba50fa533d34558e1ab9c46aea6c 100644
--- a/lib/banzai/pipeline/gfm_pipeline.rb
+++ b/lib/banzai/pipeline/gfm_pipeline.rb
@@ -12,13 +12,16 @@ module Banzai
       def self.filters
         @filters ||= FilterArray[
           Filter::PlantumlFilter,
+
+          # Must always be before the SanitizationFilter to prevent XSS attacks
+          Filter::SpacedLinkFilter,
+
           Filter::SanitizationFilter,
           Filter::SyntaxHighlightFilter,
 
           Filter::MathFilter,
           Filter::ColorFilter,
           Filter::MermaidFilter,
-          Filter::SpacedLinkFilter,
           Filter::VideoLinkFilter,
           Filter::ImageLazyLoadFilter,
           Filter::ImageLinkFilter,
diff --git a/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb b/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb
index df24cef0b8b807290a3a3a92a265ecf4998809f8..91b0499375d5c274a341eaa71bd29c1231ddf08f 100644
--- a/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb
+++ b/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb
@@ -104,5 +104,17 @@ describe Banzai::Pipeline::GfmPipeline do
 
       expect(output).to include("src=\"test%20image.png\"")
     end
+
+    it 'sanitizes the fixed link' do
+      markdown_xss = "[xss](javascript: alert%28document.domain%29)"
+      output = described_class.to_html(markdown_xss, project: project)
+
+      expect(output).not_to include("javascript")
+
+      markdown_xss = "<invalidtag>\n[xss](javascript:alert%28document.domain%29)"
+      output = described_class.to_html(markdown_xss, project: project)
+
+      expect(output).not_to include("javascript")
+    end
   end
 end