loofah 2.2.3 → 2.6.0
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.md +102 -31
- data/Gemfile +11 -9
- data/Manifest.txt +1 -16
- data/README.md +6 -13
- data/Rakefile +39 -21
- data/benchmark/benchmark.rb +6 -1
- data/benchmark/helper.rb +15 -15
- data/lib/loofah.rb +35 -16
- data/lib/loofah/elements.rb +74 -73
- data/lib/loofah/helpers.rb +18 -7
- data/lib/loofah/html/document.rb +1 -0
- data/lib/loofah/html/document_fragment.rb +4 -2
- data/lib/loofah/html5/libxml2_workarounds.rb +8 -7
- data/lib/loofah/html5/safelist.rb +804 -0
- data/lib/loofah/html5/scrub.rb +28 -30
- data/lib/loofah/instance_methods.rb +5 -3
- data/lib/loofah/metahelpers.rb +2 -1
- data/lib/loofah/scrubber.rb +8 -7
- data/lib/loofah/scrubbers.rb +12 -11
- data/lib/loofah/xml/document.rb +1 -0
- data/lib/loofah/xml/document_fragment.rb +2 -1
- metadata +69 -58
- data/.gemtest +0 -0
- data/lib/loofah/html5/whitelist.rb +0 -186
- data/test/assets/msword.html +0 -63
- data/test/assets/testdata_sanitizer_tests1.dat +0 -502
- data/test/helper.rb +0 -18
- data/test/html5/test_sanitizer.rb +0 -382
- data/test/integration/test_ad_hoc.rb +0 -204
- data/test/integration/test_helpers.rb +0 -43
- data/test/integration/test_html.rb +0 -72
- data/test/integration/test_scrubbers.rb +0 -400
- data/test/integration/test_xml.rb +0 -55
- data/test/unit/test_api.rb +0 -142
- data/test/unit/test_encoding.rb +0 -20
- data/test/unit/test_helpers.rb +0 -62
- data/test/unit/test_scrubber.rb +0 -229
- data/test/unit/test_scrubbers.rb +0 -14
data/lib/loofah/html5/scrub.rb
CHANGED
@@ -1,22 +1,21 @@
|
|
1
|
-
|
2
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "cgi"
|
3
|
+
require "crass"
|
3
4
|
|
4
5
|
module Loofah
|
5
6
|
module HTML5 # :nodoc:
|
6
7
|
module Scrub
|
7
|
-
|
8
8
|
CONTROL_CHARACTERS = /[`\u0000-\u0020\u007f\u0080-\u0101]/
|
9
|
-
CSS_KEYWORDISH = /\A(#[0-9a-
|
10
|
-
CRASS_SEMICOLON = {:node => :semicolon, :raw => ";"}
|
9
|
+
CSS_KEYWORDISH = /\A(#[0-9a-fA-F]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|-?\d{0,3}\.?\d{0,10}(ch|cm|r?em|ex|in|lh|mm|pc|pt|px|Q|vmax|vmin|vw|vh|%|,|\))?)\z/
|
10
|
+
CRASS_SEMICOLON = { :node => :semicolon, :raw => ";" }
|
11
11
|
|
12
12
|
class << self
|
13
|
-
|
14
|
-
|
15
|
-
::Loofah::HTML5::WhiteList::ALLOWED_ELEMENTS_WITH_LIBXML2.include? element_name
|
13
|
+
def allowed_element?(element_name)
|
14
|
+
::Loofah::HTML5::SafeList::ALLOWED_ELEMENTS_WITH_LIBXML2.include? element_name
|
16
15
|
end
|
17
16
|
|
18
17
|
# alternative implementation of the html5lib attribute scrubbing algorithm
|
19
|
-
def scrub_attributes
|
18
|
+
def scrub_attributes(node)
|
20
19
|
node.attribute_nodes.each do |attr_node|
|
21
20
|
attr_name = if attr_node.namespace
|
22
21
|
"#{attr_node.namespace.prefix}:#{attr_node.node_name}"
|
@@ -28,31 +27,31 @@ module Loofah
|
|
28
27
|
next
|
29
28
|
end
|
30
29
|
|
31
|
-
unless
|
30
|
+
unless SafeList::ALLOWED_ATTRIBUTES.include?(attr_name)
|
32
31
|
attr_node.remove
|
33
32
|
next
|
34
33
|
end
|
35
34
|
|
36
|
-
if
|
35
|
+
if SafeList::ATTR_VAL_IS_URI.include?(attr_name)
|
37
36
|
# this block lifted nearly verbatim from HTML5 sanitization
|
38
|
-
val_unescaped = CGI.unescapeHTML(attr_node.value).gsub(CONTROL_CHARACTERS,
|
39
|
-
if val_unescaped =~ /^[a-z0-9][-+.a-z0-9]*:/ && !
|
37
|
+
val_unescaped = CGI.unescapeHTML(attr_node.value).gsub(CONTROL_CHARACTERS, "").downcase
|
38
|
+
if val_unescaped =~ /^[a-z0-9][-+.a-z0-9]*:/ && !SafeList::ALLOWED_PROTOCOLS.include?(val_unescaped.split(SafeList::PROTOCOL_SEPARATOR)[0])
|
40
39
|
attr_node.remove
|
41
40
|
next
|
42
|
-
elsif val_unescaped.split(
|
41
|
+
elsif val_unescaped.split(SafeList::PROTOCOL_SEPARATOR)[0] == "data"
|
43
42
|
# permit only allowed data mediatypes
|
44
|
-
mediatype = val_unescaped.split(
|
45
|
-
mediatype, _ = mediatype.split(
|
46
|
-
if mediatype && !
|
43
|
+
mediatype = val_unescaped.split(SafeList::PROTOCOL_SEPARATOR)[1]
|
44
|
+
mediatype, _ = mediatype.split(";")[0..1] if mediatype
|
45
|
+
if mediatype && !SafeList::ALLOWED_URI_DATA_MEDIATYPES.include?(mediatype)
|
47
46
|
attr_node.remove
|
48
47
|
next
|
49
48
|
end
|
50
49
|
end
|
51
50
|
end
|
52
|
-
if
|
53
|
-
attr_node.value = attr_node.value.gsub(/url\s*\(\s*[^#\s][^)]+?\)/m,
|
51
|
+
if SafeList::SVG_ATTR_VAL_ALLOWS_REF.include?(attr_name)
|
52
|
+
attr_node.value = attr_node.value.gsub(/url\s*\(\s*[^#\s][^)]+?\)/m, " ") if attr_node.value
|
54
53
|
end
|
55
|
-
if
|
54
|
+
if SafeList::SVG_ALLOW_LOCAL_HREF.include?(node.name) && attr_name == "xlink:href" && attr_node.value =~ /^\s*[^#\s].*/m
|
56
55
|
attr_node.remove
|
57
56
|
next
|
58
57
|
end
|
@@ -67,26 +66,26 @@ module Loofah
|
|
67
66
|
force_correct_attribute_escaping! node
|
68
67
|
end
|
69
68
|
|
70
|
-
def scrub_css_attribute
|
71
|
-
style = node.attributes[
|
69
|
+
def scrub_css_attribute(node)
|
70
|
+
style = node.attributes["style"]
|
72
71
|
style.value = scrub_css(style.value) if style
|
73
72
|
end
|
74
73
|
|
75
|
-
def scrub_css
|
74
|
+
def scrub_css(style)
|
76
75
|
style_tree = Crass.parse_properties style
|
77
76
|
sanitized_tree = []
|
78
77
|
|
79
78
|
style_tree.each do |node|
|
80
79
|
next unless node[:node] == :property
|
81
80
|
next if node[:children].any? do |child|
|
82
|
-
[:url, :bad_url].include?(child[:node]) || (child[:node] == :function && !
|
81
|
+
[:url, :bad_url].include?(child[:node]) || (child[:node] == :function && !SafeList::ALLOWED_CSS_FUNCTIONS.include?(child[:name].downcase))
|
83
82
|
end
|
84
83
|
name = node[:name].downcase
|
85
|
-
if
|
84
|
+
if SafeList::ALLOWED_CSS_PROPERTIES.include?(name) || SafeList::ALLOWED_SVG_PROPERTIES.include?(name)
|
86
85
|
sanitized_tree << node << CRASS_SEMICOLON
|
87
|
-
elsif
|
86
|
+
elsif SafeList::SHORTHAND_CSS_PROPERTIES.include?(name.split("-").first)
|
88
87
|
value = node[:value].split.map do |keyword|
|
89
|
-
if
|
88
|
+
if SafeList::ALLOWED_CSS_KEYWORDS.include?(keyword) || keyword =~ CSS_KEYWORDISH
|
90
89
|
keyword
|
91
90
|
end
|
92
91
|
end.compact
|
@@ -106,7 +105,7 @@ module Loofah
|
|
106
105
|
#
|
107
106
|
# see comments about CVE-2018-8048 within the tests for more information
|
108
107
|
#
|
109
|
-
def force_correct_attribute_escaping!
|
108
|
+
def force_correct_attribute_escaping!(node)
|
110
109
|
return unless Nokogiri::VersionInfo.instance.libxml2?
|
111
110
|
|
112
111
|
node.attribute_nodes.each do |attr_node|
|
@@ -122,11 +121,10 @@ module Loofah
|
|
122
121
|
#
|
123
122
|
encoding = attr_node.value.encoding
|
124
123
|
attr_node.value = attr_node.value.gsub(/[ "]/) do |m|
|
125
|
-
|
124
|
+
"%" + m.unpack("H2" * m.bytesize).join("%").upcase
|
126
125
|
end.force_encoding(encoding)
|
127
126
|
end
|
128
127
|
end
|
129
|
-
|
130
128
|
end
|
131
129
|
end
|
132
130
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Loofah
|
2
3
|
#
|
3
4
|
# Mixes +scrub!+ into Document, DocumentFragment, Node and NodeSet.
|
@@ -91,7 +92,7 @@ module Loofah
|
|
91
92
|
# # decidedly not ok for browser:
|
92
93
|
# frag.text(:encode_special_chars => false) # => "<script>alert('EVIL');</script>"
|
93
94
|
#
|
94
|
-
def text(options={})
|
95
|
+
def text(options = {})
|
95
96
|
result = serialize_root.children.inner_text rescue ""
|
96
97
|
if options[:encode_special_chars] == false
|
97
98
|
result # possibly dangerous if rendered in a browser
|
@@ -99,8 +100,9 @@ module Loofah
|
|
99
100
|
encode_special_chars result
|
100
101
|
end
|
101
102
|
end
|
103
|
+
|
102
104
|
alias :inner_text :text
|
103
|
-
alias :to_str
|
105
|
+
alias :to_str :text
|
104
106
|
|
105
107
|
#
|
106
108
|
# Returns a plain-text version of the markup contained by the
|
@@ -112,7 +114,7 @@ module Loofah
|
|
112
114
|
# Loofah.document("<h1>Title</h1><div>Content</div>").to_text
|
113
115
|
# # => "\nTitle\n\nContent\n"
|
114
116
|
#
|
115
|
-
def to_text(options={})
|
117
|
+
def to_text(options = {})
|
116
118
|
Loofah.remove_extraneous_whitespace self.dup.scrub!(:newline_block_elements).text(options)
|
117
119
|
end
|
118
120
|
end
|
data/lib/loofah/metahelpers.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Loofah
|
2
3
|
module MetaHelpers # :nodoc:
|
3
|
-
def self.add_downcased_set_members_to_all_set_constants
|
4
|
+
def self.add_downcased_set_members_to_all_set_constants(mojule)
|
4
5
|
mojule.constants.each do |constant_sym|
|
5
6
|
constant = mojule.const_get constant_sym
|
6
7
|
next unless Set === constant
|
data/lib/loofah/scrubber.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Loofah
|
2
3
|
#
|
3
4
|
# A RuntimeError raised when Loofah could not find an appropriate scrubber.
|
4
5
|
#
|
5
|
-
class ScrubberNotFound < RuntimeError
|
6
|
+
class ScrubberNotFound < RuntimeError; end
|
6
7
|
|
7
8
|
#
|
8
9
|
# A Scrubber wraps up a block (or method) that is run on an HTML node (element):
|
@@ -36,7 +37,7 @@ module Loofah
|
|
36
37
|
CONTINUE = Object.new.freeze
|
37
38
|
|
38
39
|
# Top-down Scrubbers may return STOP to indicate that the subtree should not be traversed.
|
39
|
-
STOP
|
40
|
+
STOP = Object.new.freeze
|
40
41
|
|
41
42
|
# When a scrubber is initialized, the :direction may be specified
|
42
43
|
# as :top_down (the default) or :bottom_up.
|
@@ -64,7 +65,7 @@ module Loofah
|
|
64
65
|
def initialize(options = {}, &block)
|
65
66
|
direction = options[:direction] || :top_down
|
66
67
|
unless [:top_down, :bottom_up].include?(direction)
|
67
|
-
raise ArgumentError, "direction #{direction} must be one of :top_down or :bottom_up"
|
68
|
+
raise ArgumentError, "direction #{direction} must be one of :top_down or :bottom_up"
|
68
69
|
end
|
69
70
|
@direction, @block = direction, block
|
70
71
|
end
|
@@ -91,10 +92,10 @@ module Loofah
|
|
91
92
|
# If the attribute is set, don't overwrite the existing value
|
92
93
|
#
|
93
94
|
def append_attribute(node, attribute, value)
|
94
|
-
current_value = node.get_attribute(attribute) ||
|
95
|
+
current_value = node.get_attribute(attribute) || ""
|
95
96
|
current_values = current_value.split(/\s+/)
|
96
97
|
updated_value = current_values | [value]
|
97
|
-
node.set_attribute(attribute, updated_value.join(
|
98
|
+
node.set_attribute(attribute, updated_value.join(" "))
|
98
99
|
end
|
99
100
|
|
100
101
|
private
|
@@ -118,11 +119,11 @@ module Loofah
|
|
118
119
|
else
|
119
120
|
return if scrub(node) == STOP
|
120
121
|
end
|
121
|
-
node.children.each {|j| traverse_conditionally_top_down(j)}
|
122
|
+
node.children.each { |j| traverse_conditionally_top_down(j) }
|
122
123
|
end
|
123
124
|
|
124
125
|
def traverse_conditionally_bottom_up(node)
|
125
|
-
node.children.each {|j| traverse_conditionally_bottom_up(j)}
|
126
|
+
node.children.each { |j| traverse_conditionally_bottom_up(j) }
|
126
127
|
if block
|
127
128
|
block.call(node)
|
128
129
|
else
|
data/lib/loofah/scrubbers.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Loofah
|
2
3
|
#
|
3
4
|
# Loofah provides some built-in scrubbers for sanitizing with
|
4
|
-
# HTML5lib's
|
5
|
+
# HTML5lib's safelist and for accomplishing some common
|
5
6
|
# transformation tasks.
|
6
7
|
#
|
7
8
|
#
|
@@ -205,8 +206,8 @@ module Loofah
|
|
205
206
|
end
|
206
207
|
|
207
208
|
def scrub(node)
|
208
|
-
return CONTINUE unless (node.type == Nokogiri::XML::Node::ELEMENT_NODE) && (node.name ==
|
209
|
-
append_attribute(node,
|
209
|
+
return CONTINUE unless (node.type == Nokogiri::XML::Node::ELEMENT_NODE) && (node.name == "a")
|
210
|
+
append_attribute(node, "rel", "nofollow")
|
210
211
|
return STOP
|
211
212
|
end
|
212
213
|
end
|
@@ -226,8 +227,8 @@ module Loofah
|
|
226
227
|
end
|
227
228
|
|
228
229
|
def scrub(node)
|
229
|
-
return CONTINUE unless (node.type == Nokogiri::XML::Node::ELEMENT_NODE) && (node.name ==
|
230
|
-
append_attribute(node,
|
230
|
+
return CONTINUE unless (node.type == Nokogiri::XML::Node::ELEMENT_NODE) && (node.name == "a")
|
231
|
+
append_attribute(node, "rel", "noopener")
|
231
232
|
return STOP
|
232
233
|
end
|
233
234
|
end
|
@@ -267,7 +268,7 @@ module Loofah
|
|
267
268
|
|
268
269
|
def scrub(node)
|
269
270
|
if node.type == Nokogiri::XML::Node::TEXT_NODE || node.type == Nokogiri::XML::Node::CDATA_SECTION_NODE
|
270
|
-
node.content = node.content.gsub(/\u2028|\u2029/,
|
271
|
+
node.content = node.content.gsub(/\u2028|\u2029/, "")
|
271
272
|
end
|
272
273
|
CONTINUE
|
273
274
|
end
|
@@ -277,14 +278,14 @@ module Loofah
|
|
277
278
|
# A hash that maps a symbol (like +:prune+) to the appropriate Scrubber (Loofah::Scrubbers::Prune).
|
278
279
|
#
|
279
280
|
MAP = {
|
280
|
-
:escape
|
281
|
-
:prune
|
281
|
+
:escape => Escape,
|
282
|
+
:prune => Prune,
|
282
283
|
:whitewash => Whitewash,
|
283
|
-
:strip
|
284
|
-
:nofollow
|
284
|
+
:strip => Strip,
|
285
|
+
:nofollow => NoFollow,
|
285
286
|
:noopener => NoOpener,
|
286
287
|
:newline_block_elements => NewlineBlockElements,
|
287
|
-
:unprintable => Unprintable
|
288
|
+
:unprintable => Unprintable,
|
288
289
|
}
|
289
290
|
|
290
291
|
#
|
data/lib/loofah/xml/document.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Loofah
|
2
3
|
module XML # :nodoc:
|
3
4
|
#
|
@@ -12,7 +13,7 @@ module Loofah
|
|
12
13
|
# constructor. Applications should use Loofah.fragment to
|
13
14
|
# parse a fragment.
|
14
15
|
#
|
15
|
-
def parse
|
16
|
+
def parse(tags)
|
16
17
|
doc = Loofah::XML::Document.new
|
17
18
|
doc.encoding = tags.encoding.name if tags.respond_to?(:encoding)
|
18
19
|
self.new(doc, tags)
|
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.
|
4
|
+
version: 2.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Dalessio
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-06-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
@@ -43,16 +43,16 @@ dependencies:
|
|
43
43
|
name: rake
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- - "
|
46
|
+
- - "~>"
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: '
|
48
|
+
version: '12.3'
|
49
49
|
type: :development
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
|
-
- - "
|
53
|
+
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: '
|
55
|
+
version: '12.3'
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: minitest
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -85,86 +85,114 @@ dependencies:
|
|
85
85
|
name: json
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
87
87
|
requirements:
|
88
|
-
- - "
|
88
|
+
- - "~>"
|
89
89
|
- !ruby/object:Gem::Version
|
90
|
-
version:
|
90
|
+
version: 2.2.0
|
91
91
|
type: :development
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
|
-
- - "
|
95
|
+
- - "~>"
|
96
96
|
- !ruby/object:Gem::Version
|
97
|
-
version:
|
97
|
+
version: 2.2.0
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
99
|
name: hoe-gemspec
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
|
-
- - "
|
102
|
+
- - "~>"
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version: '0'
|
104
|
+
version: '1.0'
|
105
105
|
type: :development
|
106
106
|
prerelease: false
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
|
-
- - "
|
109
|
+
- - "~>"
|
110
110
|
- !ruby/object:Gem::Version
|
111
|
-
version: '0'
|
111
|
+
version: '1.0'
|
112
112
|
- !ruby/object:Gem::Dependency
|
113
113
|
name: hoe-debugging
|
114
114
|
requirement: !ruby/object:Gem::Requirement
|
115
115
|
requirements:
|
116
|
-
- - "
|
116
|
+
- - "~>"
|
117
117
|
- !ruby/object:Gem::Version
|
118
|
-
version: '0'
|
118
|
+
version: '2.0'
|
119
119
|
type: :development
|
120
120
|
prerelease: false
|
121
121
|
version_requirements: !ruby/object:Gem::Requirement
|
122
122
|
requirements:
|
123
|
-
- - "
|
123
|
+
- - "~>"
|
124
124
|
- !ruby/object:Gem::Version
|
125
|
-
version: '0'
|
125
|
+
version: '2.0'
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
127
|
name: hoe-bundler
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
129
129
|
requirements:
|
130
|
-
- - "
|
130
|
+
- - "~>"
|
131
131
|
- !ruby/object:Gem::Version
|
132
|
-
version: '
|
132
|
+
version: '1.5'
|
133
133
|
type: :development
|
134
134
|
prerelease: false
|
135
135
|
version_requirements: !ruby/object:Gem::Requirement
|
136
136
|
requirements:
|
137
|
-
- - "
|
137
|
+
- - "~>"
|
138
138
|
- !ruby/object:Gem::Version
|
139
|
-
version: '
|
139
|
+
version: '1.5'
|
140
140
|
- !ruby/object:Gem::Dependency
|
141
141
|
name: hoe-git
|
142
|
+
requirement: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - "~>"
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '1.6'
|
147
|
+
type: :development
|
148
|
+
prerelease: false
|
149
|
+
version_requirements: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - "~>"
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '1.6'
|
154
|
+
- !ruby/object:Gem::Dependency
|
155
|
+
name: hoe-markdown
|
156
|
+
requirement: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - "~>"
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '1.2'
|
161
|
+
type: :development
|
162
|
+
prerelease: false
|
163
|
+
version_requirements: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - "~>"
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '1.2'
|
168
|
+
- !ruby/object:Gem::Dependency
|
169
|
+
name: concourse
|
142
170
|
requirement: !ruby/object:Gem::Requirement
|
143
171
|
requirements:
|
144
172
|
- - ">="
|
145
173
|
- !ruby/object:Gem::Version
|
146
|
-
version:
|
174
|
+
version: 0.26.0
|
147
175
|
type: :development
|
148
176
|
prerelease: false
|
149
177
|
version_requirements: !ruby/object:Gem::Requirement
|
150
178
|
requirements:
|
151
179
|
- - ">="
|
152
180
|
- !ruby/object:Gem::Version
|
153
|
-
version:
|
181
|
+
version: 0.26.0
|
154
182
|
- !ruby/object:Gem::Dependency
|
155
|
-
name:
|
183
|
+
name: rubocop
|
156
184
|
requirement: !ruby/object:Gem::Requirement
|
157
185
|
requirements:
|
158
186
|
- - ">="
|
159
187
|
- !ruby/object:Gem::Version
|
160
|
-
version: 0.
|
188
|
+
version: 0.76.0
|
161
189
|
type: :development
|
162
190
|
prerelease: false
|
163
191
|
version_requirements: !ruby/object:Gem::Requirement
|
164
192
|
requirements:
|
165
193
|
- - ">="
|
166
194
|
- !ruby/object:Gem::Version
|
167
|
-
version: 0.
|
195
|
+
version: 0.76.0
|
168
196
|
- !ruby/object:Gem::Dependency
|
169
197
|
name: rdoc
|
170
198
|
requirement: !ruby/object:Gem::Requirement
|
@@ -191,26 +219,20 @@ dependencies:
|
|
191
219
|
requirements:
|
192
220
|
- - "~>"
|
193
221
|
- !ruby/object:Gem::Version
|
194
|
-
version: '3.
|
222
|
+
version: '3.22'
|
195
223
|
type: :development
|
196
224
|
prerelease: false
|
197
225
|
version_requirements: !ruby/object:Gem::Requirement
|
198
226
|
requirements:
|
199
227
|
- - "~>"
|
200
228
|
- !ruby/object:Gem::Version
|
201
|
-
version: '3.
|
229
|
+
version: '3.22'
|
202
230
|
description: |-
|
203
|
-
Loofah is a general library for manipulating and transforming HTML/XML
|
204
|
-
documents and fragments. It's built on top of Nokogiri and libxml2, so
|
205
|
-
it's fast and has a nice API.
|
231
|
+
Loofah is a general library for manipulating and transforming HTML/XML documents and fragments, built on top of Nokogiri.
|
206
232
|
|
207
|
-
Loofah excels at HTML sanitization (XSS prevention). It includes some
|
208
|
-
nice HTML sanitizers, which are based on HTML5lib's whitelist, so it
|
209
|
-
most likely won't make your codes less secure. (These statements have
|
210
|
-
not been evaluated by Netexperts.)
|
233
|
+
Loofah excels at HTML sanitization (XSS prevention). It includes some nice HTML sanitizers, which are based on HTML5lib's safelist, so it most likely won't make your codes less secure. (These statements have not been evaluated by Netexperts.)
|
211
234
|
|
212
|
-
ActiveRecord extensions for sanitization are available in the
|
213
|
-
[`loofah-activerecord` gem](https://github.com/flavorjones/loofah-activerecord).
|
235
|
+
ActiveRecord extensions for sanitization are available in the [`loofah-activerecord` gem](https://github.com/flavorjones/loofah-activerecord).
|
214
236
|
email:
|
215
237
|
- mike.dalessio@gmail.com
|
216
238
|
- bryan@brynary.com
|
@@ -223,7 +245,6 @@ extra_rdoc_files:
|
|
223
245
|
- README.md
|
224
246
|
- SECURITY.md
|
225
247
|
files:
|
226
|
-
- ".gemtest"
|
227
248
|
- CHANGELOG.md
|
228
249
|
- Gemfile
|
229
250
|
- MIT-LICENSE.txt
|
@@ -241,32 +262,23 @@ files:
|
|
241
262
|
- lib/loofah/html/document.rb
|
242
263
|
- lib/loofah/html/document_fragment.rb
|
243
264
|
- lib/loofah/html5/libxml2_workarounds.rb
|
265
|
+
- lib/loofah/html5/safelist.rb
|
244
266
|
- lib/loofah/html5/scrub.rb
|
245
|
-
- lib/loofah/html5/whitelist.rb
|
246
267
|
- lib/loofah/instance_methods.rb
|
247
268
|
- lib/loofah/metahelpers.rb
|
248
269
|
- lib/loofah/scrubber.rb
|
249
270
|
- lib/loofah/scrubbers.rb
|
250
271
|
- lib/loofah/xml/document.rb
|
251
272
|
- lib/loofah/xml/document_fragment.rb
|
252
|
-
- test/assets/msword.html
|
253
|
-
- test/assets/testdata_sanitizer_tests1.dat
|
254
|
-
- test/helper.rb
|
255
|
-
- test/html5/test_sanitizer.rb
|
256
|
-
- test/integration/test_ad_hoc.rb
|
257
|
-
- test/integration/test_helpers.rb
|
258
|
-
- test/integration/test_html.rb
|
259
|
-
- test/integration/test_scrubbers.rb
|
260
|
-
- test/integration/test_xml.rb
|
261
|
-
- test/unit/test_api.rb
|
262
|
-
- test/unit/test_encoding.rb
|
263
|
-
- test/unit/test_helpers.rb
|
264
|
-
- test/unit/test_scrubber.rb
|
265
|
-
- test/unit/test_scrubbers.rb
|
266
273
|
homepage: https://github.com/flavorjones/loofah
|
267
274
|
licenses:
|
268
275
|
- MIT
|
269
|
-
metadata:
|
276
|
+
metadata:
|
277
|
+
homepage_uri: https://github.com/flavorjones/loofah
|
278
|
+
bug_tracker_uri: https://github.com/flavorjones/loofah/issues
|
279
|
+
documentation_uri: https://www.rubydoc.info/gems/loofah/
|
280
|
+
changelog_uri: https://github.com/flavorjones/loofah/blob/master/CHANGELOG.md
|
281
|
+
source_code_uri: https://github.com/flavorjones/loofah
|
270
282
|
post_install_message:
|
271
283
|
rdoc_options:
|
272
284
|
- "--main"
|
@@ -284,10 +296,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
284
296
|
- !ruby/object:Gem::Version
|
285
297
|
version: '0'
|
286
298
|
requirements: []
|
287
|
-
|
288
|
-
rubygems_version: 2.7.7
|
299
|
+
rubygems_version: 3.1.2
|
289
300
|
signing_key:
|
290
301
|
specification_version: 4
|
291
302
|
summary: Loofah is a general library for manipulating and transforming HTML/XML documents
|
292
|
-
and fragments
|
303
|
+
and fragments, built on top of Nokogiri
|
293
304
|
test_files: []
|