ignore code blocks when checking markdown for XSS (#20641)

Code blocks are rendered as raw strings and therefore don´t need to be
checked for XSS. Checking them for XSS disallow users to write articles about
XSS in markdown, for example.

Co-authored-by: Mac Siri <mac@forem.com>
This commit is contained in:
Kim Emmanuel 2024-03-07 18:03:39 -03:00 committed by GitHub
parent 6f7c39dd40
commit 04fb62a6f5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 44 additions and 1 deletions

View file

@ -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

View file

@ -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