Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/markdown/filter/sanitization_filter.rb')
-rw-r--r--lib/gitlab/markdown/filter/sanitization_filter.rb99
1 files changed, 99 insertions, 0 deletions
diff --git a/lib/gitlab/markdown/filter/sanitization_filter.rb b/lib/gitlab/markdown/filter/sanitization_filter.rb
new file mode 100644
index 00000000000..cf153f30622
--- /dev/null
+++ b/lib/gitlab/markdown/filter/sanitization_filter.rb
@@ -0,0 +1,99 @@
+require 'gitlab/markdown'
+require 'html/pipeline/filter'
+require 'html/pipeline/sanitization_filter'
+
+module Gitlab
+ module Markdown
+ # Sanitize HTML
+ #
+ # Extends HTML::Pipeline::SanitizationFilter with a custom whitelist.
+ class SanitizationFilter < HTML::Pipeline::SanitizationFilter
+ def whitelist
+ # Descriptions are more heavily sanitized, allowing only a few elements.
+ # See http://git.io/vkuAN
+ if context[:inline_sanitization]
+ whitelist = LIMITED
+ whitelist[:elements] -= %w(pre code img ol ul li)
+ else
+ whitelist = super
+ end
+
+ customize_whitelist(whitelist)
+
+ whitelist
+ end
+
+ private
+
+ def customized?(transformers)
+ transformers.last.source_location[0] == __FILE__
+ end
+
+ def customize_whitelist(whitelist)
+ # Only push these customizations once
+ return if customized?(whitelist[:transformers])
+
+ # Allow code highlighting
+ whitelist[:attributes]['pre'] = %w(class)
+ whitelist[:attributes]['span'] = %w(class)
+
+ # Allow table alignment
+ whitelist[:attributes]['th'] = %w(style)
+ whitelist[:attributes]['td'] = %w(style)
+
+ # Allow span elements
+ whitelist[:elements].push('span')
+
+ # Allow any protocol in `a` elements...
+ whitelist[:protocols].delete('a')
+
+ # ...but then remove links with the `javascript` protocol
+ whitelist[:transformers].push(remove_javascript_links)
+
+ # 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
+
+ def remove_javascript_links
+ lambda do |env|
+ node = env[:node]
+
+ return unless node.name == 'a'
+ return unless node.has_attribute?('href')
+
+ if node['href'].start_with?('javascript', ':javascript')
+ node.remove_attribute('href')
+ end
+ end
+ end
+
+ def remove_rel
+ lambda do |env|
+ if env[:node_name] == 'a'
+ env[:node].remove_attribute('rel')
+ end
+ end
+ end
+
+ def clean_spans
+ lambda do |env|
+ node = env[:node]
+
+ return unless node.name == 'span'
+ return unless node.has_attribute?('class')
+
+ unless has_ancestor?(node, 'pre')
+ node.remove_attribute('class')
+ end
+
+ { node_whitelist: [node] }
+ end
+ end
+ end
+ end
+end