sanitize 2.1.1 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sanitize might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/HISTORY.md +93 -14
- data/README.md +346 -134
- data/lib/sanitize.rb +177 -132
- data/lib/sanitize/config.rb +53 -79
- data/lib/sanitize/config/basic.rb +12 -32
- data/lib/sanitize/config/default.rb +103 -0
- data/lib/sanitize/config/relaxed.rb +517 -52
- data/lib/sanitize/config/restricted.rb +3 -23
- data/lib/sanitize/css.rb +218 -0
- data/lib/sanitize/transformers/clean_cdata.rb +3 -3
- data/lib/sanitize/transformers/clean_comment.rb +6 -3
- data/lib/sanitize/transformers/clean_css.rb +57 -0
- data/lib/sanitize/transformers/clean_doctype.rb +13 -0
- data/lib/sanitize/transformers/clean_element.rb +99 -129
- data/lib/sanitize/version.rb +3 -1
- data/test/common.rb +34 -0
- data/test/test_clean_comment.rb +51 -0
- data/test/test_clean_css.rb +66 -0
- data/test/test_clean_doctype.rb +71 -0
- data/test/test_clean_element.rb +399 -0
- data/test/test_config.rb +65 -0
- data/test/test_malicious_css.rb +42 -0
- data/test/test_malicious_html.rb +128 -0
- data/test/test_parser.rb +104 -0
- data/test/test_sanitize.rb +65 -693
- data/test/test_sanitize_css.rb +222 -0
- data/test/test_transformers.rb +144 -0
- data/test/test_unicode.rb +84 -0
- metadata +56 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5d54b7ff5de5e70aa002451d1654015521de8c02
|
4
|
+
data.tar.gz: f326532bce90a02b4ca27664ea97778ffa81f594
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48d4d41b9e4ac666d1c67937e36cdce5ca8e47a4fdf90f478dd7a0f71e01aef03d45294e77fd9676983f20096c31740a5019eb1cb626df608ab20f134143d2cc
|
7
|
+
data.tar.gz: 6b134ba669333ce6715c69207304ca1a73682e8255314933ff78d9d2b8ff08f287c70da23e1d0c707e70c54a2f4833c79271670182f15879452764c3bbeb09ee
|
data/HISTORY.md
CHANGED
@@ -1,25 +1,104 @@
|
|
1
1
|
Sanitize History
|
2
2
|
================================================================================
|
3
3
|
|
4
|
-
Version
|
5
|
-
|
4
|
+
Version 3.0.0 (git)
|
5
|
+
-------------------
|
6
|
+
|
7
|
+
As of this version, Sanitize adheres strictly to the [SemVer 2.0.0][semver]
|
8
|
+
versioning standard. This release contains API and output changes that are
|
9
|
+
incompatible with previous releases, as indicated by the major version
|
10
|
+
increment.
|
11
|
+
|
12
|
+
[semver]:http://semver.org/
|
13
|
+
|
14
|
+
### Backwards-incompatible changes
|
15
|
+
|
16
|
+
* HTML is now parsed using Google's Gumbo HTML5 parser, which adheres to the
|
17
|
+
HTML5 parsing spec and behaves much more like modern browser parsers than the
|
18
|
+
previous libxml2-based parser. As a result, HTML output may differ from that
|
19
|
+
of previous versions of Sanitize.
|
20
|
+
|
21
|
+
* All transformers now traverse the document from the top down, starting with
|
22
|
+
the first node, then its first child, and so on. The `:transformers_breadth`
|
23
|
+
config has been removed, and old bottom-up transformers (the previous default)
|
24
|
+
may need to be rewritten.
|
25
|
+
|
26
|
+
* Sanitize's built-in configs are now deeply frozen to prevent people from
|
27
|
+
modifying them (either accidentally or maliciously). To customize a built-in
|
28
|
+
config, create a new copy using `Sanitize::Config.merge()`, like so:
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
Sanitize.fragment(html, Sanitize::Config.merge(Sanitize::Config::BASIC,
|
32
|
+
:elements => Sanitize::Config::BASIC[:elements] + ['div', 'table'],
|
33
|
+
:remove_contents => true
|
34
|
+
))
|
35
|
+
```
|
36
|
+
|
37
|
+
* The `clean!` and `clean_document!` methods were removed, since they weren't
|
38
|
+
useful and tended to confuse people.
|
39
|
+
|
40
|
+
* The `clean` method was renamed to `fragment` to more clearly indicate that its
|
41
|
+
intended use is to sanitize an HTML fragment.
|
42
|
+
|
43
|
+
* The `clean_document` method was renamed to `document`.
|
44
|
+
|
45
|
+
* The `clean_node!` method was renamed to `node!`.
|
46
|
+
|
47
|
+
* The `document` method now raises a `Sanitize::Error` if the `<html>` element
|
48
|
+
isn't whitelisted, rather than a `RuntimeError`. This error is also now raised
|
49
|
+
regardless of the `:remove_contents` config setting.
|
50
|
+
|
51
|
+
* The `:output` config has been removed. Output is now always HTML, not XHTML.
|
52
|
+
|
53
|
+
* The `:output_encoding` config has been removed. Output is now always UTF-8.
|
54
|
+
|
55
|
+
### Other changes
|
56
|
+
|
57
|
+
* Added advanced CSS sanitization support using [Crass][crass], which is fully
|
58
|
+
compliant with the CSS Syntax Module Level 3 parsing spec. The contents of
|
59
|
+
whitelisted `<style>` elements and `style` attributes in HTML will be
|
60
|
+
sanitized as CSS, or you can use the `Sanitize::CSS` class to manually
|
61
|
+
sanitize CSS stylesheets or properties.
|
62
|
+
|
63
|
+
* Added an `:allow_doctype` setting. When `true`, well-formed doctype
|
64
|
+
definitions will be allowed in documents. When `false` (the default), doctype
|
65
|
+
definitions will be removed from documents. Doctype definitions are never
|
66
|
+
allowed in fragments, regardless of this setting.
|
67
|
+
|
68
|
+
* Added the following elements to the relaxed config, in addition to various
|
69
|
+
attributes: `article`, `aside`, `body`, `data`, `div`, `footer`, `head`,
|
70
|
+
`header`, `html`, `main`, `nav`, `section`, `span`, `style`, `title`.
|
71
|
+
|
72
|
+
* The `:whitespace_elements` config is now a Hash, and allows you to specify the
|
73
|
+
text that should be inserted before and after these elements when they're
|
74
|
+
removed. The old-style Array-based config value is still supported for
|
75
|
+
backwards compatibility. [@alperkokmen - #94][94]
|
76
|
+
|
77
|
+
* Unsuitable Unicode characters are now removed from HTML before it's parsed.
|
78
|
+
[#106][106]
|
6
79
|
|
7
|
-
*
|
8
|
-
|
80
|
+
* Fixed: Non-tag brackets in input like `"1 > 2 and 2 < 1"` are now parsed and
|
81
|
+
escaped correctly in accordance with the HTML5 spec, becoming
|
82
|
+
`"1 > 2 and 2 < 1"`. [#83][83]
|
9
83
|
|
10
|
-
|
11
|
-
|
12
|
-
escaped output, allowing non-whitelisted attributes to be used on whitelisted
|
13
|
-
elements.
|
84
|
+
* Fixed: Siblings added after the current node during traversal are now
|
85
|
+
also traversed. In previous versions they were simply skipped. [#91][91]
|
14
86
|
|
15
|
-
|
16
|
-
|
87
|
+
* Fixed: Nokogiri has been smacked and instructed to stop adding newlines after
|
88
|
+
certain elements, because if people wanted newlines there they'd have put them
|
89
|
+
there, dammit. [#103][103]
|
17
90
|
|
18
|
-
|
19
|
-
|
91
|
+
* Fixed: Added a workaround for a libxml2 bug that caused an undesired
|
92
|
+
content-type meta tag to be added to all documents with `<head>` elements.
|
93
|
+
[Nokogiri #1008][n1008]
|
20
94
|
|
21
|
-
[
|
22
|
-
[
|
95
|
+
[crass]:https://github.com/rgrove/crass
|
96
|
+
[83]:https://github.com/rgrove/sanitize/issues/83
|
97
|
+
[91]:https://github.com/rgrove/sanitize/issues/91
|
98
|
+
[94]:https://github.com/rgrove/sanitize/pull/94/
|
99
|
+
[103]:https://github.com/rgrove/sanitize/issues/103
|
100
|
+
[106]:https://github.com/rgrove/sanitize/issues/106
|
101
|
+
[n1008]:https://github.com/sparklemotion/nokogiri/issues/1008
|
23
102
|
|
24
103
|
|
25
104
|
Version 2.1.0 (2014-01-13)
|
data/README.md
CHANGED
@@ -1,20 +1,36 @@
|
|
1
1
|
Sanitize
|
2
2
|
========
|
3
3
|
|
4
|
-
Sanitize is a whitelist-based HTML sanitizer. Given a list of acceptable
|
5
|
-
elements and
|
6
|
-
string.
|
4
|
+
Sanitize is a whitelist-based HTML and CSS sanitizer. Given a list of acceptable
|
5
|
+
elements, attributes, and CSS properties, Sanitize will remove all unacceptable
|
6
|
+
HTML and/or CSS from a string.
|
7
7
|
|
8
|
-
Using a simple configuration syntax, you can tell Sanitize to allow certain
|
8
|
+
Using a simple configuration syntax, you can tell Sanitize to allow certain HTML
|
9
9
|
elements, certain attributes within those elements, and even certain URL
|
10
|
-
protocols within attributes that contain URLs.
|
11
|
-
|
10
|
+
protocols within attributes that contain URLs. You can also whitelist CSS
|
11
|
+
properties, @ rules, and URL protocols you wish to allow in elements or
|
12
|
+
attributes containing CSS. Any HTML or CSS that you don't explicitly allow will
|
13
|
+
be removed.
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
Sanitize is based on [Google's Gumbo HTML5 parser][gumbo], which parses HTML
|
16
|
+
exactly the same way modern browsers do, and [Crass][crass], which parses CSS
|
17
|
+
exactly the same way modern browsers do. As long as your whitelist config only
|
18
|
+
allows safe markup and CSS, even the most malformed or malicious input will be
|
19
|
+
transformed into safe output.
|
16
20
|
|
17
|
-
[![Build Status](https://travis-ci.org/rgrove/sanitize.
|
21
|
+
[![Build Status](https://travis-ci.org/rgrove/sanitize.svg?branch=master)](https://travis-ci.org/rgrove/sanitize)
|
22
|
+
[![Gem Version](https://badge.fury.io/rb/sanitize.svg)](http://badge.fury.io/rb/sanitize)
|
23
|
+
|
24
|
+
[crass]:https://github.com/rgrove/crass
|
25
|
+
[gumbo]:https://github.com/google/gumbo-parser
|
26
|
+
|
27
|
+
Links
|
28
|
+
-----
|
29
|
+
|
30
|
+
* [Home](https://github.com/rgrove/sanitize/)
|
31
|
+
* [API Docs](http://rubydoc.info/github/rgrove/sanitize/master)
|
32
|
+
* [Issues](https://github.com/rgrove/sanitize/issues)
|
33
|
+
* [Biased comparison of Ruby HTML sanitization libraries](https://github.com/rgrove/sanitize/blob/master/COMPARISON.md)
|
18
34
|
|
19
35
|
Installation
|
20
36
|
-------------
|
@@ -23,63 +39,201 @@ Installation
|
|
23
39
|
gem install sanitize
|
24
40
|
```
|
25
41
|
|
42
|
+
Quick Start
|
43
|
+
-----------
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
require 'sanitize'
|
47
|
+
|
48
|
+
# Clean up an HTML fragment using Sanitize's permissive but safe Relaxed config.
|
49
|
+
# This also sanitizes any CSS in `<style>` elements or `style` attributes.
|
50
|
+
Sanitize.fragment(html, Sanitize::Config::RELAXED)
|
51
|
+
|
52
|
+
# Clean up an HTML document using the Relaxed config.
|
53
|
+
Sanitize.document(html, Sanitize::Config::RELAXED)
|
54
|
+
|
55
|
+
# Clean up a standalone CSS stylesheet using the Relaxed config.
|
56
|
+
Sanitize::CSS.stylesheet(css, Sanitize::Config::RELAXED)
|
57
|
+
|
58
|
+
# Clean up some CSS properties using the Relaxed config.
|
59
|
+
Sanitize::CSS.properties(css, Sanitize::Config::RELAXED)
|
60
|
+
```
|
61
|
+
|
26
62
|
Usage
|
27
63
|
-----
|
28
64
|
|
65
|
+
Sanitize can sanitize the following types of input:
|
66
|
+
|
67
|
+
* HTML fragments
|
68
|
+
* HTML documents
|
69
|
+
* CSS stylesheets inside HTML `<style>` elements
|
70
|
+
* CSS properties inside HTML `style` attributes
|
71
|
+
* Standalone CSS stylesheets
|
72
|
+
* Standalone CSS properties
|
73
|
+
|
74
|
+
### HTML Fragments
|
75
|
+
|
76
|
+
A fragment is a snippet of HTML that doesn't contain a root-level `<html>`
|
77
|
+
element.
|
78
|
+
|
29
79
|
If you don't specify any configuration options, Sanitize will use its strictest
|
30
|
-
settings by default, which means it will strip all HTML and leave only text
|
80
|
+
settings by default, which means it will strip all HTML and leave only safe text
|
31
81
|
behind.
|
32
82
|
|
33
83
|
```ruby
|
34
|
-
|
35
|
-
|
84
|
+
html = '<b><a href="http://foo.com/">foo</a></b><img src="bar.jpg">'
|
85
|
+
Sanitize.fragment(html)
|
86
|
+
# => 'foo'
|
87
|
+
```
|
88
|
+
|
89
|
+
To keep certain elements, add them to the element whitelist.
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
Sanitize.fragment(html, :elements => ['b'])
|
93
|
+
# => '<b>foo</b>'
|
94
|
+
```
|
36
95
|
|
37
|
-
|
96
|
+
### HTML Documents
|
38
97
|
|
39
|
-
|
98
|
+
When sanitizing a document, the `<html>` element must be whitelisted. You can
|
99
|
+
also set `:allow_doctype` to `true` to allow well-formed document type
|
100
|
+
definitions.
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
html = %[
|
104
|
+
<!DOCTYPE html>
|
105
|
+
<html>
|
106
|
+
<b><a href="http://foo.com/">foo</a></b><img src="bar.jpg">
|
107
|
+
</html>
|
108
|
+
]
|
109
|
+
|
110
|
+
Sanitize.document(html,
|
111
|
+
:allow_doctype => true,
|
112
|
+
:elements => ['html']
|
113
|
+
)
|
114
|
+
# => %[
|
115
|
+
# <!DOCTYPE html>
|
116
|
+
# <html>foo
|
117
|
+
#
|
118
|
+
# </html>
|
119
|
+
# ]
|
120
|
+
```
|
121
|
+
|
122
|
+
### CSS in HTML
|
123
|
+
|
124
|
+
To sanitize CSS in an HTML fragment or document, first whitelist the `<style>`
|
125
|
+
element and/or the `style` attribute. Then whitelist the CSS properties,
|
126
|
+
@ rules, and URL protocols you wish to allow. You can also choose whether to
|
127
|
+
allow CSS comments or browser compatibility hacks.
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
html = %[
|
131
|
+
<style>
|
132
|
+
div { color: green; width: 1024px; }
|
133
|
+
</style>
|
134
|
+
|
135
|
+
<div style="height: 100px; width: 100px;"></div>
|
136
|
+
<p>hello!</p>
|
137
|
+
]
|
138
|
+
|
139
|
+
Sanitize.fragment(html,
|
140
|
+
:elements => ['div', 'style'],
|
141
|
+
:attributes => {'div' => ['style']},
|
142
|
+
|
143
|
+
:css => {
|
144
|
+
:properties => ['width']
|
145
|
+
}
|
146
|
+
)
|
147
|
+
#=> %[
|
148
|
+
# <style>
|
149
|
+
# div { width: 1024px; }
|
150
|
+
# </style>
|
151
|
+
#
|
152
|
+
# <div style=" width: 100px;"></div>
|
153
|
+
# hello!
|
154
|
+
# ]
|
155
|
+
```
|
156
|
+
|
157
|
+
### Standalone CSS
|
158
|
+
|
159
|
+
Sanitize will happily clean up a standalone CSS stylesheet or property string
|
160
|
+
without needing to invoke the HTML parser.
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
css = %[
|
164
|
+
@import url(evil.css);
|
165
|
+
|
166
|
+
a { text-decoration: none; }
|
167
|
+
|
168
|
+
a:hover {
|
169
|
+
left: expression(alert('xss!'));
|
170
|
+
text-decoration: underline;
|
171
|
+
}
|
172
|
+
]
|
173
|
+
|
174
|
+
Sanitize::CSS.stylesheet(css, Sanitize::Config::RELAXED)
|
175
|
+
# => %[
|
176
|
+
#
|
177
|
+
#
|
178
|
+
#
|
179
|
+
# a { text-decoration: none; }
|
180
|
+
#
|
181
|
+
# a:hover {
|
182
|
+
#
|
183
|
+
# text-decoration: underline;
|
184
|
+
# }
|
185
|
+
# ]
|
186
|
+
|
187
|
+
Sanitize::CSS.properties(%[
|
188
|
+
left: expression(alert('xss!'));
|
189
|
+
text-decoration: underline;
|
190
|
+
], Sanitize::Config::RELAXED)
|
191
|
+
# => %[
|
192
|
+
#
|
193
|
+
# text-decoration: underline;
|
194
|
+
# ]
|
40
195
|
|
41
|
-
# or sanitize an entire HTML document (example assumes _html_ is whitelisted)
|
42
|
-
html = '<!DOCTYPE html><html><b><a href="http://foo.com/">foo</a></b><img src="http://foo.com/bar.jpg"></html>'
|
43
|
-
Sanitize.clean_document(html) # => '<!DOCTYPE html>\n<html>foo</html>\n'
|
44
196
|
```
|
45
197
|
|
46
198
|
Configuration
|
47
199
|
-------------
|
48
200
|
|
49
201
|
In addition to the ultra-safe default settings, Sanitize comes with three other
|
50
|
-
built-in
|
202
|
+
built-in configurations that you can use out of the box or adapt to meet your
|
203
|
+
needs.
|
51
204
|
|
52
205
|
### Sanitize::Config::RESTRICTED
|
53
206
|
|
54
|
-
Allows only very simple inline
|
55
|
-
elements.
|
207
|
+
Allows only very simple inline markup. No links, images, or block elements.
|
56
208
|
|
57
209
|
```ruby
|
58
|
-
Sanitize.
|
210
|
+
Sanitize.fragment(html, Sanitize::Config::RESTRICTED)
|
211
|
+
# => '<b>foo</b>'
|
59
212
|
```
|
60
213
|
|
61
214
|
### Sanitize::Config::BASIC
|
62
215
|
|
63
|
-
Allows a variety of markup including formatting
|
64
|
-
|
65
|
-
|
216
|
+
Allows a variety of markup including formatting elements, links, and lists.
|
217
|
+
|
218
|
+
Images and tables are not allowed, links are limited to FTP, HTTP, HTTPS, and
|
219
|
+
mailto protocols, and a `rel="nofollow"` attribute is added to all links to
|
66
220
|
mitigate SEO spam.
|
67
221
|
|
68
222
|
```ruby
|
69
|
-
Sanitize.
|
223
|
+
Sanitize.fragment(html, Sanitize::Config::BASIC)
|
70
224
|
# => '<b><a href="http://foo.com/" rel="nofollow">foo</a></b>'
|
71
225
|
```
|
72
226
|
|
73
227
|
### Sanitize::Config::RELAXED
|
74
228
|
|
75
|
-
Allows an even wider variety of markup
|
76
|
-
Links are still limited to FTP, HTTP, HTTPS, and mailto protocols,
|
77
|
-
are limited to HTTP and HTTPS. In this mode, `rel="nofollow"` is
|
78
|
-
links.
|
229
|
+
Allows an even wider variety of markup, including images and tables, as well as
|
230
|
+
safe CSS. Links are still limited to FTP, HTTP, HTTPS, and mailto protocols,
|
231
|
+
while images are limited to HTTP and HTTPS. In this mode, `rel="nofollow"` is
|
232
|
+
not added to links.
|
79
233
|
|
80
234
|
```ruby
|
81
|
-
Sanitize.
|
82
|
-
# => '<b><a href="http://foo.com/">foo</a></b><img src="
|
235
|
+
Sanitize.fragment(html, Sanitize::Config::RELAXED)
|
236
|
+
# => '<b><a href="http://foo.com/">foo</a></b><img src="bar.jpg">'
|
83
237
|
```
|
84
238
|
|
85
239
|
### Custom Configuration
|
@@ -88,11 +242,51 @@ If the built-in modes don't meet your needs, you can easily specify a custom
|
|
88
242
|
configuration:
|
89
243
|
|
90
244
|
```ruby
|
91
|
-
Sanitize.
|
92
|
-
|
93
|
-
|
245
|
+
Sanitize.fragment(html,
|
246
|
+
:elements => ['a', 'span'],
|
247
|
+
|
248
|
+
:attributes => {
|
249
|
+
'a' => ['href', 'title'],
|
250
|
+
'span' => ['class']
|
251
|
+
},
|
252
|
+
|
253
|
+
:protocols => {
|
254
|
+
'a' => {'href' => ['http', 'https', 'mailto']}
|
255
|
+
}
|
256
|
+
)
|
257
|
+
```
|
258
|
+
|
259
|
+
You can also start with one of Sanitize's built-in configurations and then
|
260
|
+
customize it to meet your needs.
|
261
|
+
|
262
|
+
The built-in configs are deeply frozen to prevent people from modifying them
|
263
|
+
(either accidentally or maliciously). To customize a built-in config, create a
|
264
|
+
new copy using `Sanitize::Config.merge()`, like so:
|
265
|
+
|
266
|
+
```ruby
|
267
|
+
# Create a customized copy of the Basic config, adding <div> and <table> to the
|
268
|
+
# existing whitelisted elements.
|
269
|
+
Sanitize.fragment(html, Sanitize::Config.merge(Sanitize::Config::BASIC,
|
270
|
+
:elements => Sanitize::Config::BASIC[:elements] + ['div', 'table'],
|
271
|
+
:remove_contents => true
|
272
|
+
))
|
273
|
+
```
|
274
|
+
|
275
|
+
The example above adds the `<div>` and `<table>` elements to a copy of the
|
276
|
+
existing list of elements in `Sanitize::Config::BASIC`. If you instead want to
|
277
|
+
completely overwrite the elements array with your own, you can omit the `+`
|
278
|
+
operation:
|
279
|
+
|
280
|
+
```ruby
|
281
|
+
# Overwrite :elements instead of creating a copy with new entries.
|
282
|
+
Sanitize.fragment(html, Sanitize::Config.merge(Sanitize::Config::BASIC,
|
283
|
+
:elements => ['div', 'table'],
|
284
|
+
:remove_contents => true
|
285
|
+
))
|
94
286
|
```
|
95
287
|
|
288
|
+
### Config Settings
|
289
|
+
|
96
290
|
#### :add_attributes (Hash)
|
97
291
|
|
98
292
|
Attributes to add to specific elements. If the attribute already exists, it will
|
@@ -111,9 +305,15 @@ Whether or not to allow HTML comments. Allowing comments is strongly
|
|
111
305
|
discouraged, since IE allows script execution within conditional comments. The
|
112
306
|
default value is `false`.
|
113
307
|
|
308
|
+
#### :allow_doctype (boolean)
|
309
|
+
|
310
|
+
Whether or not to allow well-formed HTML doctype declarations such as "<!DOCTYPE
|
311
|
+
html>" when sanitizing a document. This setting is ignored when sanitizing
|
312
|
+
fragments. The default value is `false`.
|
313
|
+
|
114
314
|
#### :attributes (Hash)
|
115
315
|
|
116
|
-
Attributes to allow
|
316
|
+
Attributes to allow on specific elements. Specify all element names and
|
117
317
|
attributes in lowercase.
|
118
318
|
|
119
319
|
```ruby
|
@@ -124,8 +324,8 @@ attributes in lowercase.
|
|
124
324
|
}
|
125
325
|
```
|
126
326
|
|
127
|
-
If you'd like to allow certain attributes on all elements, use the symbol
|
128
|
-
|
327
|
+
If you'd like to allow certain attributes on all elements, use the symbol `:all`
|
328
|
+
instead of an element name.
|
129
329
|
|
130
330
|
```ruby
|
131
331
|
# Allow the class attribute on all elements.
|
@@ -135,8 +335,8 @@ If you'd like to allow certain attributes on all elements, use the symbol
|
|
135
335
|
}
|
136
336
|
```
|
137
337
|
|
138
|
-
To allow arbitrary HTML5 `data-*` attributes, use the symbol
|
139
|
-
|
338
|
+
To allow arbitrary HTML5 `data-*` attributes, use the symbol `:data` in place of
|
339
|
+
an attribute name.
|
140
340
|
|
141
341
|
```ruby
|
142
342
|
# Allow arbitrary HTML5 data-* attributes on <div> elements.
|
@@ -145,9 +345,44 @@ To allow arbitrary HTML5 `data-*` attributes, use the symbol
|
|
145
345
|
}
|
146
346
|
```
|
147
347
|
|
148
|
-
#### :
|
348
|
+
#### :css (Hash)
|
349
|
+
|
350
|
+
Hash of the following CSS config settings to be used when sanitizing CSS (either
|
351
|
+
standalone or embedded in HTML).
|
352
|
+
|
353
|
+
##### :css => :allow_comments (boolean)
|
354
|
+
|
355
|
+
Whether or not to allow CSS comments. The default value is `false`.
|
356
|
+
|
357
|
+
##### :css => :allow_hacks (boolean)
|
358
|
+
|
359
|
+
Whether or not to allow browser compatibility hacks such as the IE `*` and `_`
|
360
|
+
hacks. These are generally harmless, but technically result in invalid CSS. The
|
361
|
+
default is `false`.
|
362
|
+
|
363
|
+
##### :css => :at_rules (Array or Set)
|
364
|
+
|
365
|
+
Names of CSS [@ rules][at-rules] to allow. Names should be specified in
|
366
|
+
lowercase.
|
367
|
+
|
368
|
+
[at-rules]:https://developer.mozilla.org/en-US/docs/Web/CSS/At-rule
|
369
|
+
|
370
|
+
##### :css => :properties (Array or Set)
|
371
|
+
|
372
|
+
Whitelist of CSS property names to allow. Names should be specified in
|
373
|
+
lowercase.
|
374
|
+
|
375
|
+
##### :css => :protocols (Array or Set)
|
376
|
+
|
377
|
+
URL protocols to allow in CSS URLs. Should be specified in lowercase.
|
149
378
|
|
150
|
-
|
379
|
+
If you'd like to allow the use of relative URLs which don't have a protocol,
|
380
|
+
include the symbol `:relative` in the protocol array.
|
381
|
+
|
382
|
+
#### :elements (Array or Set)
|
383
|
+
|
384
|
+
Array of HTML element names to allow. Specify all names in lowercase. Any
|
385
|
+
elements not in this array will be removed.
|
151
386
|
|
152
387
|
```ruby
|
153
388
|
:elements => %w[
|
@@ -156,15 +391,6 @@ Array of element names to allow. Specify all names in lowercase.
|
|
156
391
|
]
|
157
392
|
```
|
158
393
|
|
159
|
-
#### :output (Symbol)
|
160
|
-
|
161
|
-
Output format. Supported formats are `:html` and `:xhtml`,
|
162
|
-
defaulting to `:html`.
|
163
|
-
|
164
|
-
#### :output_encoding (String)
|
165
|
-
|
166
|
-
Character encoding to use for HTML output. Default is `utf-8`.
|
167
|
-
|
168
394
|
#### :protocols (Hash)
|
169
395
|
|
170
396
|
URL protocols to allow in specific attributes. If an attribute is listed here
|
@@ -187,9 +413,9 @@ include the symbol `:relative` in the protocol array:
|
|
187
413
|
}
|
188
414
|
```
|
189
415
|
|
190
|
-
#### :remove_contents (boolean or Array)
|
416
|
+
#### :remove_contents (boolean or Array or Set)
|
191
417
|
|
192
|
-
If set to
|
418
|
+
If set to `true`, Sanitize will remove the contents of any non-whitelisted
|
193
419
|
elements in addition to the elements themselves. By default, Sanitize leaves the
|
194
420
|
safe parts of an element's contents behind when the element is removed.
|
195
421
|
|
@@ -199,49 +425,50 @@ elements will be left behind.
|
|
199
425
|
|
200
426
|
The default value is `false`.
|
201
427
|
|
202
|
-
#### :transformers
|
203
|
-
|
204
|
-
Custom transformer or array of custom transformers to run using depth-first
|
205
|
-
traversal. See the Transformers section below for details.
|
206
|
-
|
207
|
-
#### :transformers_breadth
|
428
|
+
#### :transformers (Array or callable)
|
208
429
|
|
209
|
-
Custom transformer or array of custom transformers
|
210
|
-
|
430
|
+
Custom HTML transformer or array of custom transformers. See the Transformers
|
431
|
+
section below for details.
|
211
432
|
|
212
|
-
#### :whitespace_elements (
|
433
|
+
#### :whitespace_elements (Hash)
|
213
434
|
|
214
|
-
|
215
|
-
|
216
|
-
`foo<div>bar</div>baz` will become
|
217
|
-
`foo bar baz` when the `<div>` is removed.
|
435
|
+
Hash of element names which, when removed, should have their contents surrounded
|
436
|
+
by whitespace to preserve readability.
|
218
437
|
|
219
|
-
|
220
|
-
`:
|
438
|
+
Each element name is a key pointing to another Hash, which provides the specific
|
439
|
+
whitespace that should be inserted `:before` and `:after` the removed element's
|
440
|
+
position. The `:after` value will only be inserted if the removed element has
|
441
|
+
children, in which case it will be inserted after those children.
|
221
442
|
|
222
|
-
```
|
223
|
-
|
224
|
-
|
443
|
+
```ruby
|
444
|
+
:whitespace_elements => {
|
445
|
+
'br' => { :before => "\n", :after => "" },
|
446
|
+
'div' => { :before => "\n", :after => "\n" },
|
447
|
+
'p' => { :before => "\n", :after => "\n" }
|
448
|
+
}
|
225
449
|
```
|
226
450
|
|
227
|
-
|
451
|
+
## Transformers
|
228
452
|
|
229
|
-
Transformers allow you to filter and modify nodes using your own custom
|
230
|
-
on top of (or instead of) Sanitize's core filter. A transformer is any
|
231
|
-
that responds to `call()` (such as a lambda or proc).
|
453
|
+
Transformers allow you to filter and modify HTML nodes using your own custom
|
454
|
+
logic, on top of (or instead of) Sanitize's core filter. A transformer is any
|
455
|
+
object that responds to `call()` (such as a lambda or proc).
|
232
456
|
|
233
|
-
To use one or more transformers, pass them to the `:transformers`
|
234
|
-
|
457
|
+
To use one or more transformers, pass them to the `:transformers` config
|
458
|
+
setting. You may pass a single transformer or an array of transformers.
|
235
459
|
|
236
460
|
```ruby
|
237
|
-
Sanitize.
|
461
|
+
Sanitize.fragment(html, :transformers => [
|
462
|
+
transformer_one,
|
463
|
+
transformer_two
|
464
|
+
])
|
238
465
|
```
|
239
466
|
|
240
|
-
|
467
|
+
### Input
|
241
468
|
|
242
|
-
Each
|
243
|
-
|
244
|
-
|
469
|
+
Each transformer's `call()` method will be called once for each node in the HTML
|
470
|
+
(including elements, text nodes, comments, etc.), and will receive as an
|
471
|
+
argument a Hash that contains the following items:
|
245
472
|
|
246
473
|
* **:config** - The current Sanitize configuration Hash.
|
247
474
|
|
@@ -263,10 +490,7 @@ receive as an argument an environment Hash that contains the following items:
|
|
263
490
|
generally bad form to remove a node that a previous transformer has
|
264
491
|
whitelisted.
|
265
492
|
|
266
|
-
|
267
|
-
depth-first (the default mode) or `:breadth` for breadth-first.
|
268
|
-
|
269
|
-
#### Output
|
493
|
+
### Output
|
270
494
|
|
271
495
|
A transformer doesn't have to return anything, but may optionally return a Hash,
|
272
496
|
which may contain the following items:
|
@@ -279,7 +503,7 @@ which may contain the following items:
|
|
279
503
|
If a transformer returns anything other than a Hash, the return value will be
|
280
504
|
ignored.
|
281
505
|
|
282
|
-
|
506
|
+
### Processing
|
283
507
|
|
284
508
|
Each transformer has full access to the `Nokogiri::XML::Node` that's passed into
|
285
509
|
it and to the rest of the document via the node's `document()` method. Any
|
@@ -288,42 +512,44 @@ in the document and passed on to subsequently called transformers and to
|
|
288
512
|
Sanitize itself. A transformer may even call Sanitize internally to perform
|
289
513
|
custom sanitization if needed.
|
290
514
|
|
291
|
-
Nodes are passed into transformers in the order in which they're traversed.
|
292
|
-
|
293
|
-
|
515
|
+
Nodes are passed into transformers in the order in which they're traversed.
|
516
|
+
Sanitize performs top-down traversal, meaning that nodes are traversed in the
|
517
|
+
same order you'd read them in the HTML, starting at the top node, then its first
|
518
|
+
child, and so on.
|
294
519
|
|
295
520
|
```ruby
|
296
|
-
html
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
521
|
+
html = %[
|
522
|
+
<header>
|
523
|
+
<span>
|
524
|
+
<strong>foo</strong>
|
525
|
+
</span>
|
526
|
+
<p>bar</p>
|
527
|
+
</header>
|
528
|
+
|
529
|
+
<footer></footer>
|
530
|
+
]
|
305
531
|
|
306
|
-
|
307
|
-
|
308
|
-
|
532
|
+
transformer = lambda do |env|
|
533
|
+
puts env[:node_name] if env[:node].element?
|
534
|
+
end
|
309
535
|
|
310
|
-
# Prints "
|
311
|
-
Sanitize.
|
536
|
+
# Prints "header", "span", "strong", "p", "footer".
|
537
|
+
Sanitize.fragment(html, :transformers => transformer)
|
312
538
|
```
|
313
539
|
|
314
540
|
Transformers have a tremendous amount of power, including the power to
|
315
541
|
completely bypass Sanitize's built-in filtering. Be careful! Your safety is in
|
316
542
|
your own hands.
|
317
543
|
|
318
|
-
|
544
|
+
### Example: Transformer to whitelist YouTube video embeds
|
319
545
|
|
320
|
-
The following example demonstrates how to create a
|
321
|
-
|
322
|
-
|
323
|
-
|
546
|
+
The following example demonstrates how to create a transformer that will safely
|
547
|
+
whitelist valid YouTube video embeds without having to blindly allow other kinds
|
548
|
+
of embedded content, which would be the case if you tried to do this by just
|
549
|
+
whitelisting all `<iframe>` elements:
|
324
550
|
|
325
551
|
```ruby
|
326
|
-
lambda do |env|
|
552
|
+
youtube_transformer = lambda do |env|
|
327
553
|
node = env[:node]
|
328
554
|
node_name = env[:node_name]
|
329
555
|
|
@@ -334,12 +560,12 @@ lambda do |env|
|
|
334
560
|
return unless node_name == 'iframe'
|
335
561
|
|
336
562
|
# Verify that the video URL is actually a valid YouTube video URL.
|
337
|
-
return unless node['src'] =~
|
563
|
+
return unless node['src'] =~ %r|\A(?:https?:)?//(?:www\.)?youtube(?:-nocookie)?\.com/|
|
338
564
|
|
339
565
|
# We're now certain that this is a YouTube embed, but we still need to run
|
340
566
|
# it through a special Sanitize step to ensure that no unwanted elements or
|
341
567
|
# attributes that don't belong in a YouTube embed can sneak in.
|
342
|
-
Sanitize.
|
568
|
+
Sanitize.node!(node, {
|
343
569
|
:elements => %w[iframe],
|
344
570
|
|
345
571
|
:attributes => {
|
@@ -352,29 +578,15 @@ lambda do |env|
|
|
352
578
|
# to whitelist the current node.
|
353
579
|
{:node_whitelist => [node]}
|
354
580
|
end
|
355
|
-
```
|
356
581
|
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
* Wilson Bilkovich
|
366
|
-
* Peter Cooper
|
367
|
-
* Gabe da Silveira
|
368
|
-
* Nicholas Evans
|
369
|
-
* Nils Gemeinhardt
|
370
|
-
* Adam Hooper
|
371
|
-
* Mutwin Kraus
|
372
|
-
* Eaden McKee
|
373
|
-
* Dev Purkayastha
|
374
|
-
* David Reese
|
375
|
-
* Ardie Saeidi
|
376
|
-
* Rafael Souza
|
377
|
-
* Ben Wanicur
|
582
|
+
html = %[
|
583
|
+
<iframe width="420" height="315" src="//www.youtube.com/embed/dQw4w9WgXcQ"
|
584
|
+
frameborder="0" allowfullscreen></iframe>
|
585
|
+
]
|
586
|
+
|
587
|
+
Sanitize.fragment(html, :transformers => youtube_transformer)
|
588
|
+
# => '<iframe width="420" height="315" src="//www.youtube.com/embed/dQw4w9WgXcQ" frameborder="0" allowfullscreen=""></iframe>'
|
589
|
+
```
|
378
590
|
|
379
591
|
License
|
380
592
|
-------
|