Commit 99996b6b authored by Robert Speicher's avatar Robert Speicher Committed by Bob Van Landuyt

Merge branch 'bvl-security-9-1-markup-pipeline'

(security-9-1) Render asciidoc & other markup using banzai in a pipeline

See merge request !2098
parent 9b03ed0a
...@@ -116,13 +116,13 @@ module MarkupHelper ...@@ -116,13 +116,13 @@ module MarkupHelper
if gitlab_markdown?(file_name) if gitlab_markdown?(file_name)
markdown_unsafe(text, context) markdown_unsafe(text, context)
elsif asciidoc?(file_name) elsif asciidoc?(file_name)
asciidoc_unsafe(text) asciidoc_unsafe(text, context)
elsif plain?(file_name) elsif plain?(file_name)
content_tag :pre, class: 'plain-readme' do content_tag :pre, class: 'plain-readme' do
text text
end end
else else
other_markup_unsafe(file_name, text) other_markup_unsafe(file_name, text, context)
end end
rescue RuntimeError rescue RuntimeError
simple_format(text) simple_format(text)
...@@ -217,12 +217,12 @@ module MarkupHelper ...@@ -217,12 +217,12 @@ module MarkupHelper
Banzai.render(text, context) Banzai.render(text, context)
end end
def asciidoc_unsafe(text) def asciidoc_unsafe(text, context = {})
Gitlab::Asciidoc.render(text) Gitlab::Asciidoc.render(text, context)
end end
def other_markup_unsafe(file_name, text) def other_markup_unsafe(file_name, text, context = {})
Gitlab::OtherMarkup.render(file_name, text) Gitlab::OtherMarkup.render(file_name, text, context)
end end
def prepare_for_rendering(html, context = {}) def prepare_for_rendering(html, context = {})
......
---
title: Make Asciidoc & other markup go through pipeline to prevent XSS
merge_request:
author:
module Banzai
module Pipeline
class MarkupPipeline < BasePipeline
def self.filters
@filters ||= FilterArray[
Filter::SanitizationFilter,
Filter::ExternalLinkFilter,
Filter::PlantumlFilter
]
end
end
end
end
...@@ -15,17 +15,17 @@ module Gitlab ...@@ -15,17 +15,17 @@ module Gitlab
# #
# input - the source text in Asciidoc format # input - the source text in Asciidoc format
# #
def self.render(input) def self.render(input, context)
asciidoc_opts = { safe: :secure, asciidoc_opts = { safe: :secure,
backend: :gitlab_html5, backend: :gitlab_html5,
attributes: DEFAULT_ADOC_ATTRS } attributes: DEFAULT_ADOC_ATTRS }
context[:pipeline] = :markup
plantuml_setup plantuml_setup
html = ::Asciidoctor.convert(input, asciidoc_opts) html = ::Asciidoctor.convert(input, asciidoc_opts)
html = Banzai.render(html, context)
filter = Banzai::Filter::SanitizationFilter.new(html)
html = filter.call.to_s
html.html_safe html.html_safe
end end
......
...@@ -5,12 +5,12 @@ module Gitlab ...@@ -5,12 +5,12 @@ module Gitlab
# #
# input - the source text in a markup format # input - the source text in a markup format
# #
def self.render(file_name, input) def self.render(file_name, input, context)
html = GitHub::Markup.render(file_name, input). html = GitHub::Markup.render(file_name, input).
force_encoding(input.encoding) force_encoding(input.encoding)
context[:pipeline] = :markup
filter = Banzai::Filter::SanitizationFilter.new(html) html = Banzai.render(html, context)
html = filter.call.to_s
html.html_safe html.html_safe
end end
......
...@@ -22,7 +22,7 @@ module Gitlab ...@@ -22,7 +22,7 @@ module Gitlab
expect(Asciidoctor).to receive(:convert) expect(Asciidoctor).to receive(:convert)
.with(input, expected_asciidoc_opts).and_return(html) .with(input, expected_asciidoc_opts).and_return(html)
expect(render(input)).to eq(html) expect(render(input, context)).to eq(html)
end end
context "XSS" do context "XSS" do
...@@ -33,7 +33,7 @@ module Gitlab ...@@ -33,7 +33,7 @@ module Gitlab
}, },
'images' => { 'images' => {
input: 'image:https://localhost.com/image.png[Alt text" onerror="alert(7)]', input: 'image:https://localhost.com/image.png[Alt text" onerror="alert(7)]',
output: "<div>\n<p><span><img src=\"https://localhost.com/image.png\" alt=\"Alt text\"></span></p>\n</div>" output: "<img src=\"https://localhost.com/image.png\" alt=\"Alt text\">"
}, },
'pre' => { 'pre' => {
input: '```mypre"><script>alert(3)</script>', input: '```mypre"><script>alert(3)</script>',
...@@ -43,10 +43,18 @@ module Gitlab ...@@ -43,10 +43,18 @@ module Gitlab
links.each do |name, data| links.each do |name, data|
it "does not convert dangerous #{name} into HTML" do it "does not convert dangerous #{name} into HTML" do
expect(render(data[:input])).to eq(data[:output]) expect(render(data[:input], context)).to include(data[:output])
end end
end end
end end
context 'external links' do
it 'adds the `rel` attribute to the link' do
output = render('link:https://google.com[Google]', context)
expect(output).to include('rel="nofollow noreferrer"')
end
end
end end
def render(*args) def render(*args)
......
...@@ -13,7 +13,7 @@ describe Gitlab::OtherMarkup, lib: true do ...@@ -13,7 +13,7 @@ describe Gitlab::OtherMarkup, lib: true do
} }
links.each do |name, data| links.each do |name, data|
it "does not convert dangerous #{name} into HTML" do it "does not convert dangerous #{name} into HTML" do
expect(render(data[:file], data[:input])).to eq(data[:output]) expect(render(data[:file], data[:input], context)).to eq(data[:output])
end end
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment