Commit bfab73b0 authored by Robert Speicher's avatar Robert Speicher Committed by Lin Jen-Shin

Merge branch 'bvl-markup-pipeline' into 'security'

Render asciidoc & other markup using banzai in a pipeline

See merge request !2088
parent 401ab708
---
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
...@@ -30,15 +30,14 @@ module Gitlab ...@@ -30,15 +30,14 @@ module Gitlab
) )
asciidoc_opts[:attributes].unshift(*DEFAULT_ADOC_ATTRS) asciidoc_opts[:attributes].unshift(*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)
html = Banzai.post_process(html, context) html = Banzai.post_process(html, context)
filter = Banzai::Filter::SanitizationFilter.new(html)
html = filter.call.to_s
html.html_safe html.html_safe
end end
......
...@@ -14,12 +14,11 @@ module Gitlab ...@@ -14,12 +14,11 @@ module Gitlab
def self.render(file_name, input, context) 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
html = Banzai.render(html, context)
html = Banzai.post_process(html, context) html = Banzai.post_process(html, context)
filter = Banzai::Filter::SanitizationFilter.new(html)
html = filter.call.to_s
html.html_safe html.html_safe
end end
end end
......
...@@ -41,7 +41,7 @@ module Gitlab ...@@ -41,7 +41,7 @@ module Gitlab
render(input, context, asciidoc_opts) render(input, context, asciidoc_opts)
end end
end end
context "XSS" do context "XSS" do
links = { links = {
'links' => { 'links' => {
...@@ -50,7 +50,7 @@ module Gitlab ...@@ -50,7 +50,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>',
...@@ -60,10 +60,18 @@ module Gitlab ...@@ -60,10 +60,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], context)).to eql 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 noopener"')
end
end
end end
def render(*args) def render(*args)
......
require 'spec_helper'
describe Gitlab::OtherMarkup, lib: true do
context "XSS Checks" do
links = {
'links' => {
file: 'file.rdoc',
input: 'XSS[JaVaScriPt:alert(1)]',
output: '<p><a>XSS</a></p>'
}
}
links.each do |name, data|
it "does not convert dangerous #{name} into HTML" do
expect(render(data[:file], data[:input], context)).to eql data[:output]
end
end
end
def render(*args)
described_class.render(*args)
end
end
require 'spec_helper'
describe Gitlab::OtherMarkup, lib: true do
context "XSS Checks" do
it "does not convert dangerous #{name} into HTML" do
context = {}
filename = 'file.rdoc'
input = 'XSS[JaVaScriPt:alert(1)]'
output = '<p><a>XSS</a></p>'
expect(render(filename, input, context)).to eql output
end
end
context 'external links' do
it 'adds the `rel` attribute to the link' do
context = {}
output = render('file.rdoc', '{Google}[https://google.com]', context)
expect(output).to include('rel="nofollow noreferrer noopener"')
end
end
def render(*args)
described_class.render(*args).strip
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