Commit a9eaa20d authored by Gabriel Mazetto's avatar Gabriel Mazetto Committed by Robert Speicher

Refactored SVG sanitizer

parent 388f6eaa
...@@ -10,7 +10,11 @@ module Gitlab ...@@ -10,7 +10,11 @@ module Gitlab
DATA_ATTR_PATTERN = /\Adata-(?!xml)[a-z_][\w.\u00E0-\u00F6\u00F8-\u017F\u01DD-\u02AF-]*\z/u DATA_ATTR_PATTERN = /\Adata-(?!xml)[a-z_][\w.\u00E0-\u00F6\u00F8-\u017F\u01DD-\u02AF-]*\z/u
def scrub(node) def scrub(node)
if Whitelist::ALLOWED_ELEMENTS.include?(node.name) unless Whitelist::ALLOWED_ELEMENTS.include?(node.name)
node.unlink
return
end
valid_attributes = Whitelist::ALLOWED_ATTRIBUTES[node.name] valid_attributes = Whitelist::ALLOWED_ATTRIBUTES[node.name]
return unless valid_attributes return unless valid_attributes
...@@ -18,23 +22,14 @@ module Gitlab ...@@ -18,23 +22,14 @@ module Gitlab
attr_name = attribute_name_with_namespace(attr) attr_name = attribute_name_with_namespace(attr)
if valid_attributes.include?(attr_name) if valid_attributes.include?(attr_name)
# xlink:href is on the whitelist but we should deny any reference other than internal ids attr.unlink if unsafe_href?(attr)
if attr_name == 'xlink:href' && unsafe_href?(attr)
attr.unlink
end
else
if Whitelist::ALLOWED_DATA_ATTRIBUTES_IN_ELEMENTS.include?(node.name) && data_attribute?(attr)
# Arbitrary data attributes are allowed. Verify that the attribute
# is a valid data attribute.
attr.unlink unless attr_name =~ DATA_ATTR_PATTERN
else else
# Arbitrary data attributes are allowed.
unless allows_data_attribute?(node) && data_attribute?(attr)
attr.unlink attr.unlink
end end
end end
end end
else
node.unlink
end
end end
def attribute_name_with_namespace(attr) def attribute_name_with_namespace(attr)
...@@ -45,12 +40,16 @@ module Gitlab ...@@ -45,12 +40,16 @@ module Gitlab
end end
end end
def allows_data_attribute?(node)
Whitelist::ALLOWED_DATA_ATTRIBUTES_IN_ELEMENTS.include?(node.name)
end
def unsafe_href?(attr) def unsafe_href?(attr)
!attr.value.start_with?('#') attribute_name_with_namespace(attr) == 'xlink:href' && !attr.value.start_with?('#')
end end
def data_attribute?(attr) def data_attribute?(attr)
attr.name.start_with?('data-') attr.name.start_with?('data-') && attr.name =~ DATA_ATTR_PATTERN && attr.namespace.nil?
end end
end end
end end
......
...@@ -56,5 +56,23 @@ describe Gitlab::Sanitizers::SVG do ...@@ -56,5 +56,23 @@ describe Gitlab::Sanitizers::SVG do
expect(scrubber.unsafe_href?(namespaced_attr)).to be_falsey expect(scrubber.unsafe_href?(namespaced_attr)).to be_falsey
end end
end end
describe '#data_attribute?' do
let(:data_attr) { double(Nokogiri::XML::Attr, name: 'data-gitlab', namespace: nil, value: 'gitlab is awesome') }
let(:namespaced_attr) { double(Nokogiri::XML::Attr, name: 'data-gitlab', namespace: namespace, value: 'gitlab is awesome') }
let(:other_attr) { double(Nokogiri::XML::Attr, name: 'something', namespace: nil, value: 'content') }
it 'returns true if is a valid data attribute' do
expect(scrubber.data_attribute?(data_attr)).to be_truthy
end
it 'returns false if attribute is namespaced' do
expect(scrubber.data_attribute?(namespaced_attr)).to be_falsey
end
it 'returns false if not a data attribute' do
expect(scrubber.data_attribute?(other_attr)).to be_falsey
end
end
end end
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