diff --git a/app/services/markdown_processor/parser.rb b/app/services/markdown_processor/parser.rb index e6e77b73c..b705466e6 100644 --- a/app/services/markdown_processor/parser.rb +++ b/app/services/markdown_processor/parser.rb @@ -5,6 +5,8 @@ module MarkdownProcessor %r{data:text/html[,;][\sa-z0-9]*}i, ].freeze + CODE_BLOCKS_REGEX = /(~{3}|`{3}|`{2}|`)[\s\S]*?\1/ + WORDS_READ_PER_MINUTE = 275.0 # @param content [String] The user input, mix of markdown and liquid. This might be an @@ -95,7 +97,8 @@ module MarkdownProcessor end def catch_xss_attempts(markdown) - return unless markdown.match?(Regexp.union(BAD_XSS_REGEX)) + markdown_without_code_blocks = markdown.gsub(CODE_BLOCKS_REGEX, "") + return unless markdown_without_code_blocks.match?(Regexp.union(BAD_XSS_REGEX)) raise ArgumentError, I18n.t("services.markdown_processor.parser.invalid_markdown_detected") end diff --git a/spec/services/markdown_processor/parser_spec.rb b/spec/services/markdown_processor/parser_spec.rb index b8e2e4849..57d16892a 100644 --- a/spec/services/markdown_processor/parser_spec.rb +++ b/spec/services/markdown_processor/parser_spec.rb @@ -262,6 +262,46 @@ RSpec.describe MarkdownProcessor::Parser, type: :service do generate_and_parse_markdown("```const data = 'data:text/html';```") end.not_to raise_error end + + it "does not raise error if XSS is inside tripe backticks code blocks" do + code_block = "```\n src='data \n```" + + expect { generate_and_parse_markdown(code_block) }.not_to raise_error + end + + it "does not raise error if XSS is inside double backticks code blocks" do + code_block = "`` src='data ``" + + expect { generate_and_parse_markdown(code_block) }.not_to raise_error + end + + it "does not raise error if XSS is inside single backtick code blocks" do + code_block = "` src='data `" + + expect { generate_and_parse_markdown(code_block) }.not_to raise_error + end + + it "does not raise error if XSS is inside triple tildes code blocks" do + code_block = "~~~\n src='data \n~~~" + + expect { generate_and_parse_markdown(code_block) }.not_to raise_error + end + + it "raises and error if XSS attempt is in between codeblocks" do + markdown = <<~MARKDOWN + ``` + code block 1 + ``` + + src='data + + ``` + code block 2 + ``` + MARKDOWN + + expect { generate_and_parse_markdown(markdown) }.to raise_error(ArgumentError) + end end context "when provided with an @username" do