1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
require 'active_support/core_ext/class/attribute'
require 'active_support/deprecation'
require 'action_view/helpers/sanitize_helper/scrubbers'
module ActionView
XPATHS_TO_REMOVE = %w{.//script .//form comment()}
class Sanitizer
# :nodoc:
def sanitize(html, options = {})
raise NotImplementedError, "subclasses must implement"
end
def remove_xpaths(html, xpaths)
if html.respond_to?(:xpath)
xpaths.each { |xpath| html.xpath(xpath).remove }
html.to_s
else
remove_xpaths(Loofah.fragment(html), xpaths)
end
end
end
class FullSanitizer < Sanitizer
def sanitize(html, options = {})
return nil unless html
return html if html.empty?
Loofah.fragment(html).tap do |fragment|
remove_xpaths(fragment, XPATHS_TO_REMOVE)
end.text
end
end
class LinkSanitizer < Sanitizer
def initialize
@link_scrubber = TargetScrubber.new
@link_scrubber.tags = %w(a href)
end
def sanitize(html, options = {})
Loofah.scrub_fragment(html, @link_scrubber).to_s
end
end
class WhiteListSanitizer < Sanitizer
def initialize
@permit_scrubber = PermitScrubber.new
end
def sanitize(html, options = {})
return nil unless html
loofah_fragment = Loofah.fragment(html)
if scrubber = options[:scrubber]
# No duck typing, Loofah ensures subclass of Loofah::Scrubber
loofah_fragment.scrub!(scrubber)
elsif options[:tags] || options[:attributes]
@permit_scrubber.tags = options[:tags]
@permit_scrubber.attributes = options[:attributes]
loofah_fragment.scrub!(@permit_scrubber)
else
remove_xpaths(loofah_fragment, XPATHS_TO_REMOVE)
loofah_fragment.scrub!(:strip)
end
loofah_fragment.to_s
end
def sanitize_css(style_string)
Loofah::HTML5::Scrub.scrub_css style_string
end
def protocol_separator
self.class.protocol_separator
end
def protocol_separator=(value)
self.class.protocol_separator
end
def bad_tags
self.class.bad_tags
end
class << self
def protocol_separator
ActiveSupport::Deprecation.warn('protocol_separator has been deprecated and has no effect.')
end
def protocol_separator=(value)
protocol_separator
end
def bad_tags
ActiveSupport::Deprecation.warn('bad_tags has been deprecated and has no effect. You can still affect the tags being sanitized using ActionView::WhiteListSanitizer.bad_tags= which changes the allowed_tags.')
end
def bad_tags=(tags)
allowed_tags.replace(allowed_tags - tags)
end
end
[:uri_attributes, :allowed_attributes,
:allowed_tags, :allowed_protocols, :allowed_css_properties,
:allowed_css_keywords, :shorthand_css_properties].each do |attr|
class_attribute attr, :instance_writer => false
define_method "#{self}.update_#{attr}" do |arg|
attr.merge arg
end
end
# Constants are from Loofahs source at lib/loofah/html5/whitelist.rb
self.uri_attributes = Loofah::HTML5::WhiteList::ATTR_VAL_IS_URI
self.allowed_tags = Loofah::HTML5::WhiteList::ALLOWED_ELEMENTS
self.bad_tags = Set.new %w(script form)
self.allowed_attributes = Loofah::HTML5::WhiteList::ALLOWED_ATTRIBUTES
self.allowed_css_properties = Loofah::HTML5::WhiteList::ALLOWED_CSS_PROPERTIES
self.allowed_css_keywords = Loofah::HTML5::WhiteList::ALLOWED_CSS_KEYWORDS
self.shorthand_css_properties = Loofah::HTML5::WhiteList::SHORTHAND_CSS_PROPERTIES
self.allowed_protocols = Loofah::HTML5::WhiteList::ALLOWED_PROTOCOLS
end
end
|