Hello community,
here is the log from the commit of package rubygem-rails-html-sanitizer for
openSUSE:Factory checked in at 2016-03-01 09:42:57
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-rails-html-sanitizer (Old)
and /work/SRC/openSUSE:Factory/.rubygem-rails-html-sanitizer.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-rails-html-sanitizer"
Changes:
--------
---
/work/SRC/openSUSE:Factory/rubygem-rails-html-sanitizer/rubygem-rails-html-sanitizer.changes
2015-03-18 13:05:01.000000000 +0100
+++
/work/SRC/openSUSE:Factory/.rubygem-rails-html-sanitizer.new/rubygem-rails-html-sanitizer.changes
2016-03-01 09:43:06.000000000 +0100
@@ -1,0 +2,8 @@
+Tue Jan 26 05:35:48 UTC 2016 - [email protected]
+
+- updated to version 1.0.3:
+ * boo#963326: CVE-2015-7578: XSS vulnerability via attributes
+ * boo#963327: CVE-2015-7579: XSS vulnerability
+ * boo#963328: CVE-2015-7580: XSS via whitelist sanitizer
+
+-------------------------------------------------------------------
Old:
----
rails-html-sanitizer-1.0.2.gem
New:
----
rails-html-sanitizer-1.0.3.gem
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ rubygem-rails-html-sanitizer.spec ++++++
--- /var/tmp/diff_new_pack.7mvsyA/_old 2016-03-01 09:43:08.000000000 +0100
+++ /var/tmp/diff_new_pack.7mvsyA/_new 2016-03-01 09:43:08.000000000 +0100
@@ -1,7 +1,7 @@
#
# spec file for package rubygem-rails-html-sanitizer
#
-# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -24,7 +24,7 @@
#
Name: rubygem-rails-html-sanitizer
-Version: 1.0.2
+Version: 1.0.3
Release: 0
%define mod_name rails-html-sanitizer
%define mod_full_name %{mod_name}-%{version}
@@ -37,7 +37,7 @@
BuildRequires: %{rubygem gem2rpm}
BuildRequires: %{ruby}
BuildRequires: ruby-macros >= 5
-Url: https://github.com/rafaelfranca/rails-html-sanitizer
+Url: https://github.com/rails/rails-html-sanitizer
Source: http://rubygems.org/gems/%{mod_full_name}.gem
Source1: gem2rpm.yml
Summary: HTML sanitization to Rails applications (part of Rails)
@@ -53,7 +53,7 @@
%install
%gem_install \
- --doc-files="CHANGELOG.md LICENSE.txt README.md" \
+ --doc-files="CHANGELOG.md README.md" \
-f
%gem_packages
++++++ rails-html-sanitizer-1.0.2.gem -> rails-html-sanitizer-1.0.3.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/LICENSE.txt new/LICENSE.txt
--- old/LICENSE.txt 2015-03-10 21:28:27.000000000 +0100
+++ new/LICENSE.txt 1970-01-01 01:00:00.000000000 +0100
@@ -1,22 +0,0 @@
-Copyright (c) 2013 Rafael Mendonça França, Kasper Timm Hansen
-
-MIT License
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/README.md new/README.md
--- old/README.md 2015-03-10 21:28:27.000000000 +0100
+++ new/README.md 2016-01-25 19:28:23.000000000 +0100
@@ -132,10 +132,11 @@
- [`Nokogiri::XML::Node`](http://nokogiri.org/Nokogiri/XML/Node.html)
- [Nokogiri](http://nokogiri.org)
-## Contributing
+## Contributing to Rails Html Sanitizers
-1. Fork it
-2. Create your feature branch (`git checkout -b my-new-feature`)
-3. Commit your changes (`git commit -am 'Add some feature'`)
-4. Push to the branch (`git push origin my-new-feature`)
-5. Create new Pull Request
+Rails Html Sanitizers is work of many contributors. You're encouraged to
submit pull requests, propose features and discuss issues.
+
+See [CONTRIBUTING](CONTRIBUTING.md).
+
+## License
+Rails Html Sanitizers is released under the [MIT License](MIT-LICENSE).
Files old/checksums.yaml.gz and new/checksums.yaml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/rails/html/sanitizer/version.rb
new/lib/rails/html/sanitizer/version.rb
--- old/lib/rails/html/sanitizer/version.rb 2015-03-10 21:28:27.000000000
+0100
+++ new/lib/rails/html/sanitizer/version.rb 2016-01-25 19:28:23.000000000
+0100
@@ -1,7 +1,7 @@
module Rails
module Html
class Sanitizer
- VERSION = "1.0.2"
+ VERSION = "1.0.3"
end
end
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/rails/html/sanitizer.rb
new/lib/rails/html/sanitizer.rb
--- old/lib/rails/html/sanitizer.rb 2015-03-10 21:28:27.000000000 +0100
+++ new/lib/rails/html/sanitizer.rb 2016-01-25 19:28:23.000000000 +0100
@@ -13,6 +13,10 @@
node.xpath(*xpaths).remove
node
end
+
+ def properly_encode(fragment, options)
+ fragment.xml? ? fragment.to_xml(options) : fragment.to_html(options)
+ end
end
# === Rails::Html::FullSanitizer
@@ -26,9 +30,12 @@
return unless html
return html if html.empty?
- Loofah.fragment(html).tap do |fragment|
- remove_xpaths(fragment, XPATHS_TO_REMOVE)
- end.text(options)
+ loofah_fragment = Loofah.fragment(html)
+
+ remove_xpaths(loofah_fragment, XPATHS_TO_REMOVE)
+ loofah_fragment.scrub!(TextOnlyScrubber.new)
+
+ properly_encode(loofah_fragment, encoding: 'UTF-8')
end
end
@@ -97,6 +104,10 @@
attr_accessor :allowed_tags
attr_accessor :allowed_attributes
end
+ self.allowed_tags = Set.new(%w(strong em b i p code pre tt samp kbd var
sub
+ sup dfn cite big small address hr br div span h1 h2 h3 h4 h5 h6 ul ol
li dl dt dd abbr
+ acronym a img blockquote del ins))
+ self.allowed_attributes = Set.new(%w(href src width height alt cite
datetime title class name xml:lang abbr))
def initialize
@permit_scrubber = PermitScrubber.new
@@ -136,10 +147,6 @@
def allowed_attributes(options)
options[:attributes] || self.class.allowed_attributes
end
-
- def properly_encode(fragment, options)
- fragment.xml? ? fragment.to_xml(options) : fragment.to_html(options)
- end
end
end
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/lib/rails/html/scrubbers.rb
new/lib/rails/html/scrubbers.rb
--- old/lib/rails/html/scrubbers.rb 2015-03-10 21:28:27.000000000 +0100
+++ new/lib/rails/html/scrubbers.rb 2016-01-25 19:28:23.000000000 +0100
@@ -60,6 +60,11 @@
end
def scrub(node)
+ if node.cdata?
+ text = node.document.create_text_node node.text
+ node.replace text
+ return CONTINUE
+ end
return CONTINUE if skip_node?(node)
unless keep_node?(node)
@@ -76,7 +81,7 @@
end
def skip_node?(node)
- node.text? || node.cdata?
+ node.text?
end
def scrub_attribute?(name)
@@ -100,6 +105,7 @@
if @attributes
node.attribute_nodes.each do |attr|
attr.remove if scrub_attribute?(attr.name)
+ scrub_attribute(node, attr)
end
scrub_css_attribute(node)
@@ -123,6 +129,30 @@
end
var
end
+
+ def scrub_attribute(node, attr_node)
+ attr_name = if attr_node.namespace
+ "#{attr_node.namespace.prefix}:#{attr_node.node_name}"
+ else
+ attr_node.node_name
+ end
+
+ if Loofah::HTML5::WhiteList::ATTR_VAL_IS_URI.include?(attr_name)
+ # this block lifted nearly verbatim from HTML5 sanitization
+ val_unescaped =
CGI.unescapeHTML(attr_node.value).gsub(Loofah::HTML5::Scrub::CONTROL_CHARACTERS,'').downcase
+ if val_unescaped =~ /^[a-z0-9][-+.a-z0-9]*:/ && !
Loofah::HTML5::WhiteList::ALLOWED_PROTOCOLS.include?(val_unescaped.split(Loofah::HTML5::WhiteList::PROTOCOL_SEPARATOR)[0])
+ attr_node.remove
+ end
+ end
+ if
Loofah::HTML5::WhiteList::SVG_ATTR_VAL_ALLOWS_REF.include?(attr_name)
+ attr_node.value = attr_node.value.gsub(/url\s*\(\s*[^#\s][^)]+?\)/m,
' ') if attr_node.value
+ end
+ if Loofah::HTML5::WhiteList::SVG_ALLOW_LOCAL_HREF.include?(node.name)
&& attr_name == 'xlink:href' && attr_node.value =~ /^\s*[^#\s].*/m
+ attr_node.remove
+ end
+
+ node.remove_attribute(attr_node.name) if attr_name == 'src' &&
attr_node.value !~ /[^[:space:]]/
+ end
end
# === Rails::Html::TargetScrubber
@@ -137,11 +167,31 @@
# If set, attributes included will be removed.
class TargetScrubber < PermitScrubber
def allowed_node?(node)
- [email protected]?(node.name)
+ !super
end
def scrub_attribute?(name)
- @attributes.include?(name)
+ !super
+ end
+ end
+
+ # === Rails::Html::TextOnlyScrubber
+ #
+ # Rails::Html::TextOnlyScrubber allows you to permit text nodes.
+ #
+ # Unallowed elements will be stripped, i.e. element is removed but its
subtree kept.
+ class TextOnlyScrubber < Loofah::Scrubber
+ def initialize
+ @direction = :bottom_up
+ end
+
+ def scrub(node)
+ if node.text?
+ CONTINUE
+ else
+ node.before node.children
+ node.remove
+ end
end
end
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata 2015-03-10 21:28:27.000000000 +0100
+++ new/metadata 2016-01-25 19:28:23.000000000 +0100
@@ -1,7 +1,7 @@
--- !ruby/object:Gem::Specification
name: rails-html-sanitizer
version: !ruby/object:Gem::Version
- version: 1.0.2
+ version: 1.0.3
platform: ruby
authors:
- Rafael Mendonça França
@@ -9,7 +9,7 @@
autorequire:
bindir: bin
cert_chain: []
-date: 2015-03-10 00:00:00.000000000 Z
+date: 2016-01-25 00:00:00.000000000 Z
dependencies:
- !ruby/object:Gem::Dependency
name: loofah
@@ -90,7 +90,6 @@
extra_rdoc_files: []
files:
- CHANGELOG.md
-- LICENSE.txt
- README.md
- lib/rails-html-sanitizer.rb
- lib/rails/html/sanitizer.rb
@@ -98,7 +97,7 @@
- lib/rails/html/scrubbers.rb
- test/sanitizer_test.rb
- test/scrubbers_test.rb
-homepage: https://github.com/rafaelfranca/rails-html-sanitizer
+homepage: https://github.com/rails/rails-html-sanitizer
licenses:
- MIT
metadata: {}
@@ -118,7 +117,7 @@
version: '0'
requirements: []
rubyforge_project:
-rubygems_version: 2.4.5
+rubygems_version: 2.5.1
signing_key:
specification_version: 4
summary: This gem is responsible to sanitize HTML fragments in Rails
applications.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/test/sanitizer_test.rb new/test/sanitizer_test.rb
--- old/test/sanitizer_test.rb 2015-03-10 21:28:27.000000000 +0100
+++ new/test/sanitizer_test.rb 2016-01-25 19:28:23.000000000 +0100
@@ -11,6 +11,16 @@
end
end
+ def test_sanitize_nested_script
+ sanitizer = Rails::Html::WhiteListSanitizer.new
+ assert_equal '<script>alert("XSS");</script>',
sanitizer.sanitize('<script><script></script>alert("XSS");<script><</script>/</script><script>script></script>',
tags: %w(em))
+ end
+
+ def test_sanitize_nested_script_in_style
+ sanitizer = Rails::Html::WhiteListSanitizer.new
+ assert_equal '<script>alert("XSS");</script>',
sanitizer.sanitize('<style><script></style>alert("XSS");<style><</style>/</style><style>script></style>',
tags: %w(em))
+ end
+
class XpathRemovalTestSanitizer < Rails::Html::Sanitizer
def sanitize(html, options = {})
fragment = Loofah.fragment(html)
@@ -104,9 +114,12 @@
assert_equal "Frozen string with no tags", full_sanitize("Frozen string
with no tags".freeze)
end
- def test_full_sanitize_allows_turning_off_encoding_special_chars
+ def test_full_sanitize_respect_html_escaping_of_the_given_string
+ assert_equal 'test\r\nstring', full_sanitize('test\r\nstring')
assert_equal '&', full_sanitize('&')
- assert_equal '&', full_sanitize('&', encode_special_chars: false)
+ assert_equal '&', full_sanitize('&')
+ assert_equal '&amp;', full_sanitize('&amp;')
+ assert_equal 'omg <script>BOM</script>', full_sanitize('omg
<script>BOM</script>')
end
def test_strip_links_with_tags_in_tags
@@ -152,7 +165,7 @@
end
def test_sanitize_script
- assert_sanitized "a b c<script language=\"Javascript\">blah blah
blah</script>d e f", "a b cd e f"
+ assert_sanitized "a b c<script language=\"Javascript\">blah blah
blah</script>d e f", "a b cblah blah blahd e f"
end
def test_sanitize_js_handlers
@@ -173,17 +186,23 @@
tags = Loofah::HTML5::WhiteList::ALLOWED_ELEMENTS - %w(script form)
tags.each do |tag_name|
define_method "test_should_allow_#{tag_name}_tag" do
- assert_sanitized "start <#{tag_name} title=\"1\" onclick=\"foo\">foo
<bad>bar</bad> baz</#{tag_name}> end", %(start <#{tag_name} title="1">foo bar
baz</#{tag_name}> end)
+ scope_allowed_tags(tags) do
+ assert_sanitized "start <#{tag_name} title=\"1\" onclick=\"foo\">foo
<bad>bar</bad> baz</#{tag_name}> end", %(start <#{tag_name} title="1">foo bar
baz</#{tag_name}> end)
+ end
end
end
def test_should_allow_anchors
- assert_sanitized %(<a href="foo" onclick="bar"><script>baz</script></a>),
%(<a href=\"foo\"></a>)
+ assert_sanitized %(<a href="foo" onclick="bar"><script>baz</script></a>),
%(<a href=\"foo\">baz</a>)
end
def test_video_poster_sanitization
- assert_sanitized %(<video src="videofile.ogg" autoplay
poster="posterimage.jpg"></video>), %(<video src="videofile.ogg"
poster="posterimage.jpg"></video>)
- assert_sanitized %(<video src="videofile.ogg"
poster=javascript:alert(1)></video>), %(<video src="videofile.ogg"></video>)
+ scope_allowed_tags(%w(video)) do
+ scope_allowed_attributes %w(src poster) do
+ assert_sanitized %(<video src="videofile.ogg" autoplay
poster="posterimage.jpg"></video>), %(<video src="videofile.ogg"
poster="posterimage.jpg"></video>)
+ assert_sanitized %(<video src="videofile.ogg"
poster=javascript:alert(1)></video>), %(<video src="videofile.ogg"></video>)
+ end
+ end
end
# RFC 3986, sec 4.2
@@ -309,7 +328,7 @@
end
def test_should_not_fall_for_xss_image_hack_with_uppercase_tags
- assert_sanitized %(<IMG """><SCRIPT>alert("XSS")</SCRIPT>">), "<img>\">"
+ assert_sanitized %(<IMG """><SCRIPT>alert("XSS")</SCRIPT>">),
%(<img>alert("XSS")">)
end
[%(<IMG SRC="javascript:alert('XSS');">),
@@ -326,8 +345,8 @@
%(<IMG SRC="jav
ascript:alert('XSS');">),
%(<IMG SRC="  javascript:alert('XSS');">),
%(<IMG SRC="javascript:alert('XSS');">),
- %(<IMG SRC=`javascript:alert("RSnake says, 'XSS'")`>)].each_with_index do
|img_hack, i|
- define_method "test_should_not_fall_for_xss_image_hack_#{i+1}" do
+ %(<IMG SRC=`javascript:alert("RSnake says, 'XSS'")`>)].each do |img_hack|
+ define_method "test_should_not_fall_for_xss_image_hack_#{img_hack}" do
assert_sanitized img_hack, "<img>"
end
end
@@ -453,6 +472,16 @@
end
end
+ def test_sanitize_data_attributes
+ assert_sanitized %(<a href="/blah" data-method="post">foo</a>), %(<a
href="/blah">foo</a>)
+ assert_sanitized %(<a data-remote="true" data-type="script"
data-method="get" data-cross-domain="true" href="attack.js">Launch the
missiles</a>), %(<a href="attack.js">Launch the missiles</a>)
+ end
+
+ def test_allow_data_attribute_if_requested
+ text = %(<a data-foo="foo">foo</a>)
+ assert_equal %(<a data-foo="foo">foo</a>), white_list_sanitize(text,
attributes: ['data-foo'])
+ end
+
protected
def xpath_sanitize(input, options = {})
@@ -484,18 +513,18 @@
end
def scope_allowed_tags(tags)
+ old_tags = Rails::Html::WhiteListSanitizer.allowed_tags
Rails::Html::WhiteListSanitizer.allowed_tags = tags
yield Rails::Html::WhiteListSanitizer.new
-
ensure
- Rails::Html::WhiteListSanitizer.allowed_tags = nil
+ Rails::Html::WhiteListSanitizer.allowed_tags = old_tags
end
def scope_allowed_attributes(attributes)
+ old_attributes = Rails::Html::WhiteListSanitizer.allowed_attributes
Rails::Html::WhiteListSanitizer.allowed_attributes = attributes
yield Rails::Html::WhiteListSanitizer.new
-
ensure
- Rails::Html::WhiteListSanitizer.allowed_attributes = nil
+ Rails::Html::WhiteListSanitizer.allowed_attributes = old_attributes
end
end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/test/scrubbers_test.rb new/test/scrubbers_test.rb
--- old/test/scrubbers_test.rb 2015-03-10 21:28:27.000000000 +0100
+++ new/test/scrubbers_test.rb 2016-01-25 19:28:23.000000000 +0100
@@ -143,6 +143,20 @@
end
end
+class TextOnlyScrubberTest < ScrubberTest
+ def setup
+ @scrubber = Rails::Html::TextOnlyScrubber.new
+ end
+
+ def test_removes_all_tags_and_keep_the_content
+ assert_scrubbed '<tag>hello</tag>', 'hello'
+ end
+
+ def test_skips_text_nodes
+ assert_node_skipped('some text')
+ end
+end
+
class ReturningStopFromScrubNodeTest < ScrubberTest
class ScrubStopper < Rails::Html::PermitScrubber
def scrub_node(node)
@@ -157,4 +171,4 @@
def test_returns_stop_from_scrub_if_scrub_node_does
assert_scrub_stopped '<script>remove me</script>'
end
-end
\ No newline at end of file
+end