loofah 2.0.3 → 2.1.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of loofah might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.rdoc +11 -0
- data/Gemfile +2 -1
- data/Rakefile +1 -0
- data/lib/loofah.rb +1 -1
- data/lib/loofah/html5/scrub.rb +24 -22
- data/test/assets/testdata_sanitizer_tests1.dat +1 -1
- data/test/html5/test_sanitizer.rb +26 -3
- data/test/integration/test_helpers.rb +1 -1
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a709ec5b5b8064cd96fd216b5ac5ece3db3c2099
|
4
|
+
data.tar.gz: 212f9cb43700926714c873d2dd6ee661bcdb832a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 31120a6cb665a25b264707c6a85aff7a14beab7269e20a3d4403a72ae0b2bf625b6942df6178e92e419b1859c7e48255f19c407003f031773426cf158a953d14
|
7
|
+
data.tar.gz: 21386a195c02a5faa3d52ff14f82534a087da91f009260d215bc07c8a46976803f424b2ddf4969756e7f63dec40ee0a270aac6d0549d9362fb87756da13b532d
|
data/CHANGELOG.rdoc
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
= Changelog
|
2
2
|
|
3
|
+
== 2.1.0.rc1 / 2015-08-17
|
4
|
+
|
5
|
+
Notes:
|
6
|
+
|
7
|
+
* Re-implemented CSS parsing and sanitization using the {crass}[https://github.com/rgrove/crass] library. #91
|
8
|
+
|
9
|
+
Bug fixes:
|
10
|
+
|
11
|
+
* Allow negative values in CSS properties. Restores functionality that was reverted in v2.0.3. #91
|
12
|
+
|
13
|
+
|
3
14
|
== 2.0.3 / 2015-08-17
|
4
15
|
|
5
16
|
Bug fixes:
|
data/Gemfile
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
source "https://rubygems.org/"
|
6
6
|
|
7
7
|
gem "nokogiri", ">=1.5.9"
|
8
|
+
gem "crass", "~>1.0.2"
|
8
9
|
|
9
10
|
gem "rdoc", "~>4.0", :group => [:development, :test]
|
10
11
|
gem "rake", ">=0.8", :group => [:development, :test]
|
@@ -15,6 +16,6 @@ gem "hoe-gemspec", ">=0", :group => [:development, :test]
|
|
15
16
|
gem "hoe-debugging", ">=0", :group => [:development, :test]
|
16
17
|
gem "hoe-bundler", ">=0", :group => [:development, :test]
|
17
18
|
gem "hoe-git", ">=0", :group => [:development, :test]
|
18
|
-
gem "hoe", "~>3.
|
19
|
+
gem "hoe", "~>3.13", :group => [:development, :test]
|
19
20
|
|
20
21
|
# vim: syntax=ruby
|
data/Rakefile
CHANGED
data/lib/loofah.rb
CHANGED
data/lib/loofah/html5/scrub.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
#encoding: US-ASCII
|
2
2
|
|
3
3
|
require 'cgi'
|
4
|
+
require 'crass'
|
4
5
|
|
5
6
|
module Loofah
|
6
7
|
module HTML5 # :nodoc:
|
7
8
|
module Scrub
|
8
9
|
|
9
10
|
CONTROL_CHARACTERS = /[`\u0000-\u0020\u007f\u0080-\u0101]/
|
11
|
+
CSS_KEYWORDISH = /\A(#[0-9a-f]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|-?\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)\z/
|
12
|
+
CRASS_SEMICOLON = {:node => :semicolon, :raw => ";"}
|
10
13
|
|
11
14
|
class << self
|
12
15
|
|
@@ -61,36 +64,35 @@ module Loofah
|
|
61
64
|
style.value = scrub_css(style.value) if style
|
62
65
|
end
|
63
66
|
|
64
|
-
# lifted nearly verbatim from html5lib
|
65
67
|
def scrub_css style
|
66
|
-
|
67
|
-
|
68
|
+
style_tree = Crass.parse_properties style
|
69
|
+
sanitized_tree = []
|
68
70
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
71
|
+
style_tree.each do |node|
|
72
|
+
next unless node[:node] == :property
|
73
|
+
next if node[:children].any? do |child|
|
74
|
+
[:url, :bad_url, :function].include? child[:node]
|
75
|
+
end
|
76
|
+
name = node[:name].downcase
|
77
|
+
if WhiteList::ALLOWED_CSS_PROPERTIES.include?(name) || WhiteList::ALLOWED_SVG_PROPERTIES.include?(name)
|
78
|
+
sanitized_tree << node << CRASS_SEMICOLON
|
79
|
+
elsif WhiteList::SHORTHAND_CSS_PROPERTIES.include?(name.split('-').first)
|
80
|
+
value = node[:value].split.map do |keyword|
|
81
|
+
if WhiteList::ALLOWED_CSS_KEYWORDS.include?(keyword) || keyword =~ CSS_KEYWORDISH
|
82
|
+
keyword
|
83
|
+
end
|
84
|
+
end.compact
|
85
|
+
unless value.empty?
|
86
|
+
propstring = sprintf "%s:%s", name, value.join(" ")
|
87
|
+
sanitized_node = Crass.parse_properties(propstring).first
|
88
|
+
sanitized_tree << sanitized_node << CRASS_SEMICOLON
|
83
89
|
end
|
84
|
-
elsif WhiteList::ALLOWED_SVG_PROPERTIES.include?(prop)
|
85
|
-
clean << "#{prop}: #{val};"
|
86
90
|
end
|
87
91
|
end
|
88
92
|
|
89
|
-
|
93
|
+
Crass::Parser.stringify sanitized_tree
|
90
94
|
end
|
91
|
-
|
92
95
|
end
|
93
|
-
|
94
96
|
end
|
95
97
|
end
|
96
98
|
end
|
@@ -152,7 +152,7 @@
|
|
152
152
|
{
|
153
153
|
"name": "platypus",
|
154
154
|
"input": "<a href=\"http://www.ragingplatypus.com/\" style=\"display:block; position:absolute; left:0; top:0; width:100%; height:100%; z-index:1; background-color:black; background-image:url(http://www.ragingplatypus.com/i/cam-full.jpg); background-x:center; background-y:center; background-repeat:repeat;\">never trust your upstream platypus</a>",
|
155
|
-
"output": "<a href='http://www.ragingplatypus.com/' style='display:
|
155
|
+
"output": "<a href='http://www.ragingplatypus.com/' style='display:block;width:100%;height:100%;background-color:black;background-x:center;background-y:center;'>never trust your upstream platypus</a>"
|
156
156
|
},
|
157
157
|
|
158
158
|
{
|
@@ -229,14 +229,12 @@ class Html5TestSanitizer < Loofah::TestCase
|
|
229
229
|
end
|
230
230
|
|
231
231
|
def test_css_negative_value_sanitization
|
232
|
-
skip "pending better CSS parsing, see https://github.com/flavorjones/loofah/issues/90"
|
233
232
|
html = "<span style=\"letter-spacing:-0.03em;\">"
|
234
233
|
sane = Nokogiri::HTML(Loofah.scrub_fragment(html, :escape).to_xml)
|
235
234
|
assert_match %r/-0.03em/, sane.inner_html
|
236
235
|
end
|
237
236
|
|
238
237
|
def test_css_negative_value_sanitization_shorthand_css_properties
|
239
|
-
skip "pending better CSS parsing, see https://github.com/flavorjones/loofah/issues/90"
|
240
238
|
html = "<span style=\"margin-left:-0.05em;\">"
|
241
239
|
sane = Nokogiri::HTML(Loofah.scrub_fragment(html, :escape).to_xml)
|
242
240
|
assert_match %r/-0.05em/, sane.inner_html
|
@@ -246,9 +244,34 @@ class Html5TestSanitizer < Loofah::TestCase
|
|
246
244
|
html = %q{<span style="background: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2232%22%20height%3D%2232%22%20viewBox%3D%220%200%2032%2032%22%3E%3Cpath%20fill%3D%22%23D4C8AE%22%20d%3D%22M0%200h32v32h-32z%22%2F%3E%3Cpath%20fill%3D%22%2383604B%22%20d%3D%22M0%200h31.99v11.75h-31.99z%22%2F%3E%3Cpath%20fill%3D%22%233D2319%22%20d%3D%22M0%2011.5h32v.5h-32z%22%2F%3E%3Cpath%20fill%3D%22%23F83651%22%20d%3D%22M5%200h1v10.5h-1z%22%2F%3E%3Cpath%20fill%3D%22%23FCD050%22%20d%3D%22M6%200h1v10.5h-1z%22%2F%3E%3Cpath%20fill%3D%22%2371C797%22%20d%3D%22M7%200h1v10.5h-1z%22%2F%3E%3Cpath%20fill%3D%22%23509CF9%22%20d%3D%22M8%200h1v10.5h-1z%22%2F%3E%3ClinearGradient%20id%3D%22a%22%20gradientUnits%3D%22userSpaceOnUse%22%20x1%3D%2224.996%22%20y1%3D%2210.5%22%20x2%3D%2224.996%22%20y2%3D%224.5%22%3E%3Cstop%20offset%3D%220%22%20stop-color%3D%22%23796055%22%2F%3E%3Cstop%20offset%3D%22.434%22%20stop-color%3D%22%23614C43%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%233D2D28%22%2F%3E%3C%2FlinearGradient%3E%3Cpath%20fill%3D%22url(%23a)%22%20d%3D%22M28%208.5c0%201.1-.9%202-2%202h-2c-1.1%200-2-.9-2-2v-2c0-1.1.9-2%202-2h2c1.1%200%202%20.9%202%202v2z%22%2F%3E%3Cpath%20fill%3D%22%235F402E%22%20d%3D%22M28%208c0%201.1-.9%202-2%202h-2c-1.1%200-2-.9-2-2v-2c0-1.1.9-2%202-2h2c1.1%200%202%20.9%202%202v2z%22%2F%3E%3C');"></span>}
|
247
245
|
|
248
246
|
assert_completes_in_reasonable_time {
|
249
|
-
|
247
|
+
Nokogiri::HTML(Loofah.scrub_fragment(html, :strip).to_html)
|
250
248
|
}
|
251
249
|
end
|
250
|
+
|
251
|
+
def test_upper_case_css_property
|
252
|
+
html = "<div style=\"COLOR: BLUE; NOTAPROPERTY: RED;\">asdf</div>"
|
253
|
+
sane = Nokogiri::HTML(Loofah.scrub_fragment(html, :strip).to_xml)
|
254
|
+
assert_match /COLOR:\s*BLUE/i, sane.at_css("div")["style"]
|
255
|
+
refute_match /NOTAPROPERTY/i, sane.at_css("div")["style"]
|
256
|
+
end
|
257
|
+
|
258
|
+
def test_many_properties_some_allowed
|
259
|
+
html = "<div style=\"background: bold notaproperty center alsonotaproperty 10px;\">asdf</div>"
|
260
|
+
sane = Nokogiri::HTML(Loofah.scrub_fragment(html, :strip).to_xml)
|
261
|
+
assert_match /bold\s+center\s+10px/, sane.at_css("div")["style"]
|
262
|
+
end
|
263
|
+
|
264
|
+
def test_many_properties_non_allowed
|
265
|
+
html = "<div style=\"background: notaproperty alsonotaproperty;\">asdf</div>"
|
266
|
+
sane = Nokogiri::HTML(Loofah.scrub_fragment(html, :strip).to_xml)
|
267
|
+
assert_nil sane.at_css("div")["style"]
|
268
|
+
end
|
269
|
+
|
270
|
+
def test_svg_properties
|
271
|
+
html = "<line style='stroke-width: 10px;'></line>"
|
272
|
+
sane = Nokogiri::HTML(Loofah.scrub_fragment(html, :strip).to_xml)
|
273
|
+
assert_match /stroke-width:\s*10px/, sane.at_css("line")["style"]
|
274
|
+
end
|
252
275
|
end
|
253
276
|
|
254
277
|
# <html5_license>
|
@@ -37,7 +37,7 @@ class IntegrationTestHelpers < Loofah::TestCase
|
|
37
37
|
|
38
38
|
context ".sanitize_css" do
|
39
39
|
it "removes unsafe css properties" do
|
40
|
-
|
40
|
+
assert_match /display:\s*block;\s*background-color:\s*blue;/, Loofah::Helpers.sanitize_css("display:block;background-image:url(http://www.ragingplatypus.com/i/cam-full.jpg);background-color:blue")
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: loofah
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.1.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Dalessio
|
@@ -25,6 +25,20 @@ dependencies:
|
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: 1.5.9
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: crass
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 1.0.2
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 1.0.2
|
28
42
|
- !ruby/object:Gem::Dependency
|
29
43
|
name: rdoc
|
30
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -243,9 +257,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
243
257
|
version: '0'
|
244
258
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
245
259
|
requirements:
|
246
|
-
- - "
|
260
|
+
- - ">"
|
247
261
|
- !ruby/object:Gem::Version
|
248
|
-
version:
|
262
|
+
version: 1.3.1
|
249
263
|
requirements: []
|
250
264
|
rubyforge_project:
|
251
265
|
rubygems_version: 2.4.6
|