summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMarius Balteanu <marius.balteanu@zitec.com>2021-08-11 21:49:27 +0000
committerMarius Balteanu <marius.balteanu@zitec.com>2021-08-11 21:49:27 +0000
commite8c911577fe09b83793f7ffc95123642ab07668d (patch)
treeeed2696ff6d6b27c09e1ebac84418acad96216a6 /lib
parent46ecdcec4d3d6cec4825221a1cd0e1646e7a5792 (diff)
downloadredmine-e8c911577fe09b83793f7ffc95123642ab07668d.tar.gz
redmine-e8c911577fe09b83793f7ffc95123642ab07668d.zip
Relax allowed protocols in links by denying specific protocols for CommonMark text formatting (#32424).
Patch by Martin Cizek. git-svn-id: http://svn.redmine.org/redmine/trunk@21161 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'lib')
-rw-r--r--lib/redmine/helpers/url.rb13
-rw-r--r--lib/redmine/wiki_formatting/common_mark/sanitization_filter.rb28
2 files changed, 36 insertions, 5 deletions
diff --git a/lib/redmine/helpers/url.rb b/lib/redmine/helpers/url.rb
index 0c6cbdecd..6f1f853e4 100644
--- a/lib/redmine/helpers/url.rb
+++ b/lib/redmine/helpers/url.rb
@@ -22,6 +22,7 @@ require 'uri'
module Redmine
module Helpers
module URL
+ # safe for resources fetched without user interaction?
def uri_with_safe_scheme?(uri, schemes = ['http', 'https', 'ftp', 'mailto', nil])
# URLs relative to the current document or document root (without a protocol
# separator, should be harmless
@@ -32,6 +33,18 @@ module Redmine
rescue URI::Error
false
end
+
+ # safe to render links to given uri?
+ def uri_with_link_safe_scheme?(uri)
+ # regexp adapted from Sanitize (we need to catch even invalid protocol specs)
+ return true unless uri =~ /\A\s*([^\/#]*?)(?:\:|&#0*58|&#x0*3a)/i
+
+ # absolute scheme
+ scheme = $1.downcase
+ return false unless /\A[a-z][a-z0-9\+\.\-]*\z/.match?(scheme) # RFC 3986
+
+ %w(data javascript vbscript).none?(scheme)
+ end
end
end
end
diff --git a/lib/redmine/wiki_formatting/common_mark/sanitization_filter.rb b/lib/redmine/wiki_formatting/common_mark/sanitization_filter.rb
index a76201dfd..df09fd9c8 100644
--- a/lib/redmine/wiki_formatting/common_mark/sanitization_filter.rb
+++ b/lib/redmine/wiki_formatting/common_mark/sanitization_filter.rb
@@ -22,6 +22,11 @@ module Redmine
module CommonMark
# sanitizes rendered HTML using the Sanitize gem
class SanitizationFilter < HTML::Pipeline::SanitizationFilter
+ include Redmine::Helpers::URL
+ RELAXED_PROTOCOL_ATTRS = {
+ "a" => %w(href).freeze,
+ }.freeze
+
def whitelist
@@whitelist ||= customize_whitelist(super.deep_dup)
end
@@ -72,11 +77,24 @@ module Redmine
node.remove_attribute("id")
}
- # allow the same set of URL schemes for links as is the default in
- # Redmine::Helpers::URL#uri_with_safe_scheme?
- whitelist[:protocols]["a"]["href"] = [
- 'http', 'https', 'ftp', 'mailto', :relative
- ]
+ # https://github.com/rgrove/sanitize/issues/209
+ whitelist[:protocols].delete("a")
+ whitelist[:transformers].push lambda{|env|
+ node = env[:node]
+ return if node.type != Nokogiri::XML::Node::ELEMENT_NODE
+
+ name = env[:node_name]
+ return unless RELAXED_PROTOCOL_ATTRS.include?(name)
+
+ RELAXED_PROTOCOL_ATTRS[name].each do |attr|
+ next unless node.has_attribute?(attr)
+
+ node[attr] = node[attr].strip
+ unless !node[attr].empty? && uri_with_link_safe_scheme?(node[attr])
+ node.remove_attribute(attr)
+ end
+ end
+ }
whitelist
end