summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Speicher <rspeicher@gmail.com>2015-05-29 19:01:12 -0400
committerRobert Speicher <rspeicher@gmail.com>2015-06-02 13:04:10 -0400
commit023dd2907b4afa0bae5f8482cae75e1edd6954a8 (patch)
tree930783eafc875c69ebab009f6f0188ff58092bf1
parent1a52f19c456dfa307dd7fa0e5adbaa2ed1a68889 (diff)
downloadgitlab-ce-023dd2907b4afa0bae5f8482cae75e1edd6954a8.tar.gz
Add a `pipeline` context option for SanitizationFilter
When this option is `:description`, we use a more restrictive whitelist. This is used for Project and Group description fields.
-rw-r--r--app/views/groups/show.html.haml2
-rw-r--r--app/views/projects/_home_panel.html.haml2
-rw-r--r--lib/gitlab/markdown.rb3
-rw-r--r--lib/gitlab/markdown/sanitization_filter.rb58
-rw-r--r--spec/lib/gitlab/markdown/sanitization_filter_spec.rb14
5 files changed, 56 insertions, 23 deletions
diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml
index f42007da073..0687840af39 100644
--- a/app/views/groups/show.html.haml
+++ b/app/views/groups/show.html.haml
@@ -11,7 +11,7 @@
@#{@group.path}
- if @group.description.present?
.description
- = markdown(@group.description)
+ = markdown(@group.description, pipeline: :description)
%hr
= render 'shared/show_aside'
diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml
index 05f44acd3cb..076afb11a9d 100644
--- a/app/views/projects/_home_panel.html.haml
+++ b/app/views/projects/_home_panel.html.haml
@@ -5,7 +5,7 @@
.project-home-row.project-home-row-top
.project-home-desc
- if @project.description.present?
- = markdown(@project.description)
+ = markdown(@project.description, pipeline: :description)
- if can?(current_user, :admin_project, @project)
&ndash;
= link_to 'Edit', edit_namespace_project_path
diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb
index 5db1566f55d..fa9c0975bb8 100644
--- a/lib/gitlab/markdown.rb
+++ b/lib/gitlab/markdown.rb
@@ -57,6 +57,9 @@ module Gitlab
pipeline = HTML::Pipeline.new(filters)
context = {
+ # SanitizationFilter
+ pipeline: options[:pipeline],
+
# EmojiFilter
asset_root: Gitlab.config.gitlab.url,
asset_host: Gitlab::Application.config.asset_host,
diff --git a/lib/gitlab/markdown/sanitization_filter.rb b/lib/gitlab/markdown/sanitization_filter.rb
index 88781fea0c8..fc29d09081a 100644
--- a/lib/gitlab/markdown/sanitization_filter.rb
+++ b/lib/gitlab/markdown/sanitization_filter.rb
@@ -8,33 +8,53 @@ module Gitlab
# Extends HTML::Pipeline::SanitizationFilter with a custom whitelist.
class SanitizationFilter < HTML::Pipeline::SanitizationFilter
def whitelist
- whitelist = super
+ # Descriptions are more heavily sanitized, allowing only a few elements.
+ # See http://git.io/vkuAN
+ if pipeline == :description
+ whitelist = LIMITED
+ else
+ whitelist = super
+ end
+
+ customize_whitelist(whitelist)
+
+ whitelist
+ end
+ private
+
+ def pipeline
+ context[:pipeline] || :default
+ end
+
+ def customized?(transformers)
+ transformers.last.source_location[0] == __FILE__
+ end
+
+ def customize_whitelist(whitelist)
# Only push these customizations once
- unless customized?(whitelist[:transformers])
- # Allow code highlighting
- whitelist[:attributes]['pre'] = %w(class)
- whitelist[:attributes]['span'] = %w(class)
+ return if customized?(whitelist[:transformers])
- # Allow table alignment
- whitelist[:attributes]['th'] = %w(style)
- whitelist[:attributes]['td'] = %w(style)
+ # Allow code highlighting
+ whitelist[:attributes]['pre'] = %w(class)
+ whitelist[:attributes]['span'] = %w(class)
- # Allow span elements
- whitelist[:elements].push('span')
+ # Allow table alignment
+ whitelist[:attributes]['th'] = %w(style)
+ whitelist[:attributes]['td'] = %w(style)
- # Remove `rel` attribute from `a` elements
- whitelist[:transformers].push(remove_rel)
+ # Allow span elements
+ whitelist[:elements].push('span')
- # Remove `class` attribute from non-highlight spans
- whitelist[:transformers].push(clean_spans)
- end
+ # Remove `rel` attribute from `a` elements
+ whitelist[:transformers].push(remove_rel)
+
+ # Remove `class` attribute from non-highlight spans
+ whitelist[:transformers].push(clean_spans)
whitelist
end
- private
-
def remove_rel
lambda do |env|
if env[:node_name] == 'a'
@@ -53,10 +73,6 @@ module Gitlab
end
end
end
-
- def customized?(transformers)
- transformers.last.source_location[0] == __FILE__
- end
end
end
end
diff --git a/spec/lib/gitlab/markdown/sanitization_filter_spec.rb b/spec/lib/gitlab/markdown/sanitization_filter_spec.rb
index 4a1aa766149..80f3d2f2634 100644
--- a/spec/lib/gitlab/markdown/sanitization_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/sanitization_filter_spec.rb
@@ -42,6 +42,13 @@ module Gitlab::Markdown
end
describe 'custom whitelist' do
+ it 'customizes the whitelist only once' do
+ instance = described_class.new('Foo')
+ 3.times { instance.whitelist }
+
+ expect(instance.whitelist[:transformers].size).to eq 4
+ end
+
it 'allows syntax highlighting' do
exp = act = %q{<pre class="code highlight white c"><code><span class="k">def</span></code></pre>}
expect(filter(act).to_html).to eq exp
@@ -87,5 +94,12 @@ module Gitlab::Markdown
expect(doc.at_css('a')['href']).to be_nil
end
end
+
+ context 'when pipeline is :description' do
+ it 'uses a stricter whitelist' do
+ doc = filter('<h1>My Project</h1>', pipeline: :description)
+ expect(doc.to_html.strip).to eq 'My Project'
+ end
+ end
end
end