diff options
author | Marius Balteanu <marius.balteanu@zitec.com> | 2021-08-11 21:49:27 +0000 |
---|---|---|
committer | Marius Balteanu <marius.balteanu@zitec.com> | 2021-08-11 21:49:27 +0000 |
commit | e8c911577fe09b83793f7ffc95123642ab07668d (patch) | |
tree | eed2696ff6d6b27c09e1ebac84418acad96216a6 /lib | |
parent | 46ecdcec4d3d6cec4825221a1cd0e1646e7a5792 (diff) | |
download | redmine-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.rb | 13 | ||||
-rw-r--r-- | lib/redmine/wiki_formatting/common_mark/sanitization_filter.rb | 28 |
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*([^\/#]*?)(?:\:|�*58|�*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 |