diff options
| author | Robert Speicher <robert@gitlab.com> | 2016-06-13 03:25:01 +0000 |
|---|---|---|
| committer | Robert Speicher <robert@gitlab.com> | 2016-06-13 03:25:01 +0000 |
| commit | 06a99cf7ea82105a182c2805ea05266e5ce6c0a2 (patch) | |
| tree | 255e995c6205562ea561266e6849823654eed8c1 /lib | |
| parent | 8d243f9bdacea1909bf503eb715bd437c3b48aa7 (diff) | |
| parent | 7c87dac5f1f3d333b06dbcb2c7f66538abfb8255 (diff) | |
| download | gitlab-ce-06a99cf7ea82105a182c2805ea05266e5ce6c0a2.tar.gz | |
Merge branch 'bug/svg_sanitizer' into 'master'
Improve SVG sanitizer to handle namespaced attributes
* Small refactor in the SVG sanitizer
* Enable already whitelisted namespaced attributes to be allowed
* Disable `xlink:href`to reference any external resource
Fixes #18100
See merge request !4427
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/gitlab/sanitizers/svg.rb | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/lib/gitlab/sanitizers/svg.rb b/lib/gitlab/sanitizers/svg.rb index 5e95f6c0529..8304b9a482c 100644 --- a/lib/gitlab/sanitizers/svg.rb +++ b/lib/gitlab/sanitizers/svg.rb @@ -12,23 +12,45 @@ module Gitlab def scrub(node) unless Whitelist::ALLOWED_ELEMENTS.include?(node.name) node.unlink - else - node.attributes.each do |attr_name, attr| - valid_attributes = Whitelist::ALLOWED_ATTRIBUTES[node.name] - - unless valid_attributes && valid_attributes.include?(attr_name) - if Whitelist::ALLOWED_DATA_ATTRIBUTES_IN_ELEMENTS.include?(node.name) && - attr_name.start_with?('data-') - # Arbitrary data attributes are allowed. Verify that the attribute - # is a valid data attribute. - attr.unlink unless attr_name =~ DATA_ATTR_PATTERN - else - attr.unlink - end + return + end + + valid_attributes = Whitelist::ALLOWED_ATTRIBUTES[node.name] + return unless valid_attributes + + node.attribute_nodes.each do |attr| + attr_name = attribute_name_with_namespace(attr) + + if valid_attributes.include?(attr_name) + attr.unlink if unsafe_href?(attr) + else + # Arbitrary data attributes are allowed. + unless allows_data_attribute?(node) && data_attribute?(attr) + attr.unlink end end end end + + def attribute_name_with_namespace(attr) + if attr.namespace + "#{attr.namespace.prefix}:#{attr.name}" + else + attr.name + end + end + + def allows_data_attribute?(node) + Whitelist::ALLOWED_DATA_ATTRIBUTES_IN_ELEMENTS.include?(node.name) + end + + def unsafe_href?(attr) + attribute_name_with_namespace(attr) == 'xlink:href' && !attr.value.start_with?('#') + end + + def data_attribute?(attr) + attr.name.start_with?('data-') && attr.name =~ DATA_ATTR_PATTERN && attr.namespace.nil? + end end end end |
