Refactored SVG sanitizer
This commit is contained in:
parent
388f6eaaa6
commit
a9eaa20dcb
2 changed files with 39 additions and 22 deletions
|
@ -10,30 +10,25 @@ 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)
|
||||||
valid_attributes = Whitelist::ALLOWED_ATTRIBUTES[node.name]
|
node.unlink
|
||||||
return unless valid_attributes
|
return
|
||||||
|
end
|
||||||
|
|
||||||
node.attribute_nodes.each do |attr|
|
valid_attributes = Whitelist::ALLOWED_ATTRIBUTES[node.name]
|
||||||
attr_name = attribute_name_with_namespace(attr)
|
return unless valid_attributes
|
||||||
|
|
||||||
if valid_attributes.include?(attr_name)
|
node.attribute_nodes.each do |attr|
|
||||||
# xlink:href is on the whitelist but we should deny any reference other than internal ids
|
attr_name = attribute_name_with_namespace(attr)
|
||||||
if attr_name == 'xlink:href' && unsafe_href?(attr)
|
|
||||||
attr.unlink
|
if valid_attributes.include?(attr_name)
|
||||||
end
|
attr.unlink if unsafe_href?(attr)
|
||||||
else
|
else
|
||||||
if Whitelist::ALLOWED_DATA_ATTRIBUTES_IN_ELEMENTS.include?(node.name) && data_attribute?(attr)
|
# Arbitrary data attributes are allowed.
|
||||||
# Arbitrary data attributes are allowed. Verify that the attribute
|
unless allows_data_attribute?(node) && data_attribute?(attr)
|
||||||
# is a valid data attribute.
|
attr.unlink
|
||||||
attr.unlink unless attr_name =~ DATA_ATTR_PATTERN
|
|
||||||
else
|
|
||||||
attr.unlink
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
|
||||||
node.unlink
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -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
|
||||||
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
|
||||||
|
|
Loading…
Reference in a new issue