rails-sanitize-js 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/Gemfile +2 -0
- data/MIT-LICENSE +21 -0
- data/README.md +307 -0
- data/Rakefile +1 -0
- data/lib/rails-sanitize-js.rb +9 -0
- data/lib/rails-sanitize-js/engine.rb +4 -0
- data/lib/rails-sanitize-js/version.rb +3 -0
- data/rails-sanitize-js.gemspec +19 -0
- data/vendor/assets/javascripts/sanitize.js +260 -0
- data/vendor/assets/javascripts/sanitize/config/basic.js +27 -0
- data/vendor/assets/javascripts/sanitize/config/relaxed.js +35 -0
- data/vendor/assets/javascripts/sanitize/config/restricted.js +7 -0
- metadata +58 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9756b1435f643b1d5d3bb305411d6f6ad00adad4
|
4
|
+
data.tar.gz: de8ad71d18b5b6de5e820210b6895236ea4be0f5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 73e55293f002ff9463c3e8d1a17f623e679d536af0be17c2122560b768d990e54ee1d3a57d81a3c1bc30c9997d3bb6d4fff523543e2ad27b6c8b7209c02251ae
|
7
|
+
data.tar.gz: 3ed15f295f6495a2af55c5449b0078859b2965dc733301cf5e61f09e78adff03ed1408e1f4d7e68b4de8e8a88824525cdcefd208f2a888d3226858f687764dc4
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Nick Chernyshev
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,307 @@
|
|
1
|
+
# rails-sanitize-js
|
2
|
+
|
3
|
+
rails-sanitize-js wraps the [Sanitize.js](https://github.com/gbirke/Sanitize.js) for use in Rails 3.1 and above.
|
4
|
+
|
5
|
+
## Install in Rails
|
6
|
+
|
7
|
+
Add the following to your Gemfile:
|
8
|
+
|
9
|
+
gem 'rails-sanitize-js'
|
10
|
+
|
11
|
+
Add the following to your Rails JavaScript manifest file:
|
12
|
+
|
13
|
+
//= require sanitize
|
14
|
+
|
15
|
+
## Sanitize.js
|
16
|
+
|
17
|
+
Sanitize.js is a whitelist-based HTML sanitizer. Given a list of acceptable
|
18
|
+
elements and attributes, Sanitize.js will remove all unacceptable HTML from a
|
19
|
+
DOM node.
|
20
|
+
|
21
|
+
Using a simple configuration syntax, you can tell Sanitize to allow certain
|
22
|
+
elements, certain attributes within those elements, and even certain URL
|
23
|
+
protocols within attributes that contain URLs. Any HTML elements or attributes
|
24
|
+
that you don't explicitly allow will be removed.
|
25
|
+
|
26
|
+
Because it's working directly with the DOM tree, rather than a bunch of
|
27
|
+
fragile regular expressions, Sanitize.js has no trouble dealing with malformed
|
28
|
+
or maliciously-formed HTML, and will always output valid HTML or XHTML.
|
29
|
+
|
30
|
+
Sanitize.js heavily inspired by the Ruby Sanitize library
|
31
|
+
(http://github.com/rgrove/sanitize). It tries to port it as faithful as
|
32
|
+
possible.
|
33
|
+
|
34
|
+
|
35
|
+
**Author**: Gabriel Birke (mailto:gabriel@lebenplusplus.de)
|
36
|
+
**Version**: 1.0
|
37
|
+
**Copyright**: Copyright (c) 2010 Gabriel Birke. All rights reserved.
|
38
|
+
**License**: MIT License (http://opensource.org/licenses/mit-license.php)
|
39
|
+
**Website**: http://github.com/gbirke/Sanitize.js
|
40
|
+
|
41
|
+
## Usage
|
42
|
+
|
43
|
+
If you don't specify any configuration options, Sanitize will use its
|
44
|
+
strictest settings by default, which means it will strip all HTML and leave
|
45
|
+
only text behind.
|
46
|
+
HTML:
|
47
|
+
|
48
|
+
<p id="para1"><b><a href="http://foo.com/">foo</a></b><img src="http://foo.com/bar.jpg" /></p>
|
49
|
+
|
50
|
+
JavaScript:
|
51
|
+
|
52
|
+
var p = document.getElementById('para1');
|
53
|
+
var s = new Sanitize();
|
54
|
+
alert(s.clean_node(p)); // => 'foo'
|
55
|
+
|
56
|
+
The original node won't be changed, what you get back is a document fragment
|
57
|
+
with the sanitized child nodes (and their complete contents) of the original
|
58
|
+
DOM node.
|
59
|
+
|
60
|
+
## Configuration
|
61
|
+
|
62
|
+
In addition to the ultra-safe default settings that leave just the plain text
|
63
|
+
behind, Sanitize comes with three other built-in modes. The modes reside in
|
64
|
+
separate JavaScript files that must loaded additionally to the sanitize.js
|
65
|
+
file.
|
66
|
+
|
67
|
+
### Sanitize.Config.RESTRICTED
|
68
|
+
|
69
|
+
Allows only very simple inline formatting markup. No links, images, or block
|
70
|
+
elements.
|
71
|
+
|
72
|
+
var s = new Sanitize(Sanitize.Config.RESTRICTED);
|
73
|
+
alert(s.clean_node(p)); // => '<b>foo</b>'
|
74
|
+
|
75
|
+
### Sanitize.Config.BASIC
|
76
|
+
|
77
|
+
Allows a variety of markup including formatting tags, links, and lists. Images
|
78
|
+
and tables are not allowed, links are limited to FTP, HTTP, HTTPS, and mailto
|
79
|
+
protocols, and a `rel="nofollow"` attribute is added to all links to
|
80
|
+
mitigate SEO spam.
|
81
|
+
|
82
|
+
var s = new Sanitize(Sanitize.Config.BASIC);
|
83
|
+
alert(s.clean_node(p));
|
84
|
+
// => '<b><a href="http://foo.com/" rel="nofollow">foo</a></b>'
|
85
|
+
|
86
|
+
### Sanitize.Config.RELAXED
|
87
|
+
|
88
|
+
Allows an even wider variety of markup than BASIC, including images and tables.
|
89
|
+
Links are still limited to FTP, HTTP, HTTPS, and mailto protocols, while images
|
90
|
+
are limited to HTTP and HTTPS. In this mode, `rel="nofollow"` is not
|
91
|
+
added to links.
|
92
|
+
|
93
|
+
var s = new Sanitize(Sanitize.Config.RELAXED);
|
94
|
+
alert(s.clean_node(p));
|
95
|
+
// => '<b><a href="http://foo.com/">foo</a></b><img src="http://foo.com/bar.jpg" />'
|
96
|
+
|
97
|
+
### Configuration object parameters
|
98
|
+
|
99
|
+
If the built-in modes don't meet your needs, you can easily specify a custom
|
100
|
+
configuration:
|
101
|
+
|
102
|
+
var s = new Sanitize({
|
103
|
+
elements: ['a', 'span'],
|
104
|
+
attributes: {
|
105
|
+
a: ['href', 'title'],
|
106
|
+
span: ['class']
|
107
|
+
},
|
108
|
+
protocols: {
|
109
|
+
a: { href: ['http', 'https', 'mailto'] }
|
110
|
+
}
|
111
|
+
});
|
112
|
+
s.clean_node(p);
|
113
|
+
|
114
|
+
|
115
|
+
#### add_attributes (Object)
|
116
|
+
|
117
|
+
Attributes to add to specific elements. If the attribute already exists, it will
|
118
|
+
be replaced with the value specified here. Specify all element names and
|
119
|
+
attributes in lowercase.
|
120
|
+
|
121
|
+
add_attributes: {
|
122
|
+
a: {'rel': 'nofollow'}
|
123
|
+
}
|
124
|
+
|
125
|
+
#### attributes (Object)
|
126
|
+
|
127
|
+
Attributes to allow for specific elements. Specify all element names and
|
128
|
+
attributes in lowercase.
|
129
|
+
|
130
|
+
attributes: {
|
131
|
+
a: ['href', 'title'],
|
132
|
+
blockquote: ['cite'],
|
133
|
+
img: ['alt', 'src', 'title']
|
134
|
+
}
|
135
|
+
|
136
|
+
If you'd like to allow certain attributes on all elements, use the symbol
|
137
|
+
`__ALL__` instead of an element name.
|
138
|
+
|
139
|
+
attributes: {
|
140
|
+
'__ALL__': ['class'],
|
141
|
+
a: ['href', 'title']
|
142
|
+
}
|
143
|
+
|
144
|
+
#### allow_comments (boolean)
|
145
|
+
|
146
|
+
Whether or not to allow HTML comments. Allowing comments is strongly
|
147
|
+
discouraged, since IE allows script execution within conditional comments. The
|
148
|
+
default value is `false`.
|
149
|
+
|
150
|
+
#### dom (DOM document)
|
151
|
+
|
152
|
+
An object that implements a DOM document interface. It is mainly used to
|
153
|
+
create new element, attribute and document fragment nodes.
|
154
|
+
|
155
|
+
If you are using Sanitize in the browser, this will default to the global
|
156
|
+
`document` variable. If you are using it on the server side, you must provide
|
157
|
+
your own DOM implementation.
|
158
|
+
|
159
|
+
#### elements (Array)
|
160
|
+
|
161
|
+
Array of element names to allow. Specify all names in lowercase.
|
162
|
+
|
163
|
+
elements: [
|
164
|
+
'a', 'b', 'blockquote', 'br', 'cite', 'code', 'dd', 'dl', 'dt', 'em',
|
165
|
+
'i', 'li', 'ol', 'p', 'pre', 'q', 'small', 'strike', 'strong', 'sub',
|
166
|
+
'sup', 'u', 'ul'
|
167
|
+
]
|
168
|
+
|
169
|
+
#### protocols (Object)
|
170
|
+
|
171
|
+
URL protocols to allow in specific attributes. If an attribute is listed here
|
172
|
+
and contains a protocol other than those specified (or if it contains no
|
173
|
+
protocol at all), it will be removed.
|
174
|
+
|
175
|
+
protocols: {
|
176
|
+
a: { href: ['ftp', 'http', 'https', 'mailto']},
|
177
|
+
img: { src: ['http', 'https']}
|
178
|
+
}
|
179
|
+
|
180
|
+
If you'd like to allow the use of relative URLs which don't have a protocol,
|
181
|
+
include the variable `Sanitize.RELATIVE` in the protocol array:
|
182
|
+
|
183
|
+
protocols: {
|
184
|
+
a: { href: ['http', 'https', Sanitize.RELATIVE]}
|
185
|
+
}
|
186
|
+
|
187
|
+
Note however, that the HTML parser of Internet Explorer automatically converts
|
188
|
+
relative URLs into absolute URLs with http protocol.
|
189
|
+
|
190
|
+
#### remove_contents (boolean or Array)
|
191
|
+
|
192
|
+
If set to `true`, Sanitize will remove the contents of any non-whitelisted
|
193
|
+
elements in addition to the elements themselves. By default, Sanitize leaves the
|
194
|
+
safe parts of an element's contents behind when the element is removed.
|
195
|
+
|
196
|
+
If set to an Array of element names, then only the contents of the specified
|
197
|
+
elements (when filtered) will be removed, and the contents of all other filtered
|
198
|
+
elements will be left behind.
|
199
|
+
|
200
|
+
The default value is `false`.
|
201
|
+
|
202
|
+
#### transformers (Array)
|
203
|
+
|
204
|
+
See below.
|
205
|
+
|
206
|
+
### Transformers
|
207
|
+
|
208
|
+
Transformers allow you to filter and alter nodes using your own custom logic, on
|
209
|
+
top of (or instead of) Sanitize's core filter. A transformer is a function that
|
210
|
+
returns either `null` or an Object containing certain optional response values.
|
211
|
+
|
212
|
+
To use one or more transformers, pass them to the `transformers` config setting:
|
213
|
+
|
214
|
+
var s = new Sanitize({ transformers: [transformer_one, transformer_two]});
|
215
|
+
|
216
|
+
#### Input
|
217
|
+
|
218
|
+
Each registered transformer function will be called once for
|
219
|
+
each element node in the HTML, and will receive as an argument an environment
|
220
|
+
Object that contains the following items:
|
221
|
+
|
222
|
+
`allowed_elements`
|
223
|
+
: Object with whitelisted element names as keys, to facilitate fast lookups of
|
224
|
+
whitelisted elements.
|
225
|
+
|
226
|
+
`config`
|
227
|
+
: The current Sanitize configuration Hash.
|
228
|
+
|
229
|
+
`dom`
|
230
|
+
: A DOM document object.
|
231
|
+
|
232
|
+
`node`
|
233
|
+
A DOM node object representing an HTML element.
|
234
|
+
|
235
|
+
`node_name`
|
236
|
+
: The name of the current HTML node, always lowercase (e.g. "div" or "span").
|
237
|
+
|
238
|
+
`whitelist_nodes`
|
239
|
+
: Array of DOM nodes that have already been whitelisted by
|
240
|
+
previous transformers, if any.
|
241
|
+
|
242
|
+
#### Processing
|
243
|
+
|
244
|
+
Each transformer has full access to the DOM node that's passed into it and to
|
245
|
+
the rest of the document via the node's DOM methods method. Any changes will
|
246
|
+
be passed on to subsequently-called transformers and to Sanitize itself. A
|
247
|
+
transformer may even call Sanitize internally to perform custom sanitization
|
248
|
+
if needed. Nodes are passed into transformers in the order in which they're
|
249
|
+
traversed.
|
250
|
+
|
251
|
+
Transformers have a tremendous amount of power, including the power to
|
252
|
+
completely bypass Sanitize's built-in filtering. Be careful!
|
253
|
+
|
254
|
+
#### Output
|
255
|
+
|
256
|
+
A transformer may return either `null` or an Object. A return value of `null`
|
257
|
+
indicates that the transformer does not wish to act on the current node in any
|
258
|
+
way. A returned Object may contain the following items, all of which are optional:
|
259
|
+
|
260
|
+
`attr_whitelist`
|
261
|
+
: Array of attribute names to add to the whitelist for the current node, in
|
262
|
+
addition to any whitelisted attributes already defined in the current config.
|
263
|
+
|
264
|
+
`node`
|
265
|
+
: DOM node object that should replace the current node. All
|
266
|
+
subsequent transformers and Sanitize itself will receive this new node.
|
267
|
+
|
268
|
+
`whitelist`
|
269
|
+
: If `true`, the current node (and only the current node) will be whitelisted,
|
270
|
+
regardless of the current Sanitize config.
|
271
|
+
|
272
|
+
`whitelist_nodes`
|
273
|
+
: Array of specific DOM node objects to whitelist, anywhere in the
|
274
|
+
document, regardless of the current Sanitize config.
|
275
|
+
|
276
|
+
## Known Bugs and Limitations
|
277
|
+
* The `style` attribute is always dropped on Internet Explorer 5-7.
|
278
|
+
* Internet Explorer always converts relative URL values to absolute URLs.
|
279
|
+
|
280
|
+
## Contributors
|
281
|
+
|
282
|
+
The following lovely people have contributed to Sanitize in the form of patches
|
283
|
+
or ideas that later became code:
|
284
|
+
|
285
|
+
* Gabriel Birke <gabriel@lebenplusplus.de>
|
286
|
+
* Ryan Grove <ryan@wonko.com> - Original author of the Ruby Sanitize library
|
287
|
+
|
288
|
+
## License
|
289
|
+
|
290
|
+
Copyright (c) 2010 Gabriel Birke <gabriel@lebenplusplus.de>
|
291
|
+
|
292
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
293
|
+
this software and associated documentation files (the 'Software'), to deal in
|
294
|
+
the Software without restriction, including without limitation the rights to
|
295
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
296
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
297
|
+
subject to the following conditions:
|
298
|
+
|
299
|
+
The above copyright notice and this permission notice shall be included in all
|
300
|
+
copies or substantial portions of the Software.
|
301
|
+
|
302
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
303
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
304
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
305
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
306
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
307
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'rails-sanitize-js/version'
|
4
|
+
|
5
|
+
# Describe your gem and declare its dependencies:
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rails-sanitize-js"
|
8
|
+
spec.version = RailsSanitizeJs::VERSION
|
9
|
+
spec.authors = ["Gabriel Birke", "Nick Chernyshev"]
|
10
|
+
spec.email = ["nick.chernyshev@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = "Sanitize.js for rails assets"
|
13
|
+
spec.description = "Add Sanitize.js into your asset pipeline."
|
14
|
+
spec.homepage = "https://github.com/flowerett/rails-sanitize-js"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
end
|
@@ -0,0 +1,260 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2010 by Gabriel Birke
|
3
|
+
*
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
* of this software and associated documentation files (the 'Software'), to deal
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
9
|
+
* furnished to do so, subject to the following conditions:
|
10
|
+
*
|
11
|
+
* The above copyright notice and this permission notice shall be included in all
|
12
|
+
* copies or substantial portions of the Software.
|
13
|
+
*
|
14
|
+
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20
|
+
* SOFTWARE.
|
21
|
+
*/
|
22
|
+
|
23
|
+
function Sanitize(){
|
24
|
+
var i, e, options;
|
25
|
+
options = arguments[0] || {};
|
26
|
+
this.config = {};
|
27
|
+
this.config.elements = options.elements ? options.elements : [];
|
28
|
+
this.config.attributes = options.attributes ? options.attributes : {};
|
29
|
+
this.config.attributes[Sanitize.ALL] = this.config.attributes[Sanitize.ALL] ? this.config.attributes[Sanitize.ALL] : [];
|
30
|
+
this.config.allow_comments = options.allow_comments ? options.allow_comments : false;
|
31
|
+
this.allowed_elements = {};
|
32
|
+
this.config.protocols = options.protocols ? options.protocols : {};
|
33
|
+
this.config.add_attributes = options.add_attributes ? options.add_attributes : {};
|
34
|
+
this.dom = options.dom ? options.dom : document;
|
35
|
+
for(i=0;i<this.config.elements.length;i++) {
|
36
|
+
this.allowed_elements[this.config.elements[i]] = true;
|
37
|
+
}
|
38
|
+
this.config.remove_element_contents = {};
|
39
|
+
this.config.remove_all_contents = false;
|
40
|
+
if(options.remove_contents) {
|
41
|
+
|
42
|
+
if(options.remove_contents instanceof Array) {
|
43
|
+
for(i=0;i<options.remove_contents.length;i++) {
|
44
|
+
this.config.remove_element_contents[options.remove_contents[i]] = true;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
else {
|
48
|
+
this.config.remove_all_contents = true;
|
49
|
+
}
|
50
|
+
}
|
51
|
+
this.transformers = options.transformers ? options.transformers : [];
|
52
|
+
}
|
53
|
+
|
54
|
+
Sanitize.REGEX_PROTOCOL = /^([A-Za-z0-9\+\-\.\&\;\*\s]*?)(?:\:|&*0*58|&*x0*3a)/i;
|
55
|
+
|
56
|
+
// emulate Ruby symbol with string constant
|
57
|
+
Sanitize.RELATIVE = '__RELATIVE__';
|
58
|
+
Sanitize.ALL = '__ALL__';
|
59
|
+
|
60
|
+
Sanitize.prototype.clean_node = function(container) {
|
61
|
+
var fragment = this.dom.createDocumentFragment();
|
62
|
+
this.current_element = fragment;
|
63
|
+
this.whitelist_nodes = [];
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
/**
|
68
|
+
* Utility function to check if an element exists in an array
|
69
|
+
*/
|
70
|
+
function _array_index(needle, haystack) {
|
71
|
+
var i;
|
72
|
+
for(i=0; i < haystack.length; i++) {
|
73
|
+
if(haystack[i] == needle)
|
74
|
+
return i;
|
75
|
+
}
|
76
|
+
return -1;
|
77
|
+
}
|
78
|
+
|
79
|
+
function _merge_arrays_uniq() {
|
80
|
+
var result = [];
|
81
|
+
var uniq_hash = {};
|
82
|
+
var i,j;
|
83
|
+
for(i=0;i<arguments.length;i++) {
|
84
|
+
if(!arguments[i] || !arguments[i].length)
|
85
|
+
continue;
|
86
|
+
for(j=0;j<arguments[i].length;j++) {
|
87
|
+
if(uniq_hash[arguments[i][j]])
|
88
|
+
continue;
|
89
|
+
uniq_hash[arguments[i][j]] = true;
|
90
|
+
result.push(arguments[i][j]);
|
91
|
+
}
|
92
|
+
}
|
93
|
+
return result;
|
94
|
+
}
|
95
|
+
|
96
|
+
/**
|
97
|
+
* Clean function that checks the different node types and cleans them up accordingly
|
98
|
+
* @param elem DOM Node to clean
|
99
|
+
*/
|
100
|
+
function _clean(elem) {
|
101
|
+
var clone;
|
102
|
+
switch(elem.nodeType) {
|
103
|
+
// Element
|
104
|
+
case 1:
|
105
|
+
_clean_element.call(this, elem);
|
106
|
+
break;
|
107
|
+
// Text
|
108
|
+
case 3:
|
109
|
+
clone = elem.cloneNode(false);
|
110
|
+
this.current_element.appendChild(clone);
|
111
|
+
break;
|
112
|
+
// Entity-Reference (normally not used)
|
113
|
+
case 5:
|
114
|
+
clone = elem.cloneNode(false);
|
115
|
+
this.current_element.appendChild(clone);
|
116
|
+
break;
|
117
|
+
// Comment
|
118
|
+
case 8:
|
119
|
+
if(this.config.allow_comments) {
|
120
|
+
clone = elem.cloneNode(false);
|
121
|
+
this.current_element.appendChild(clone);
|
122
|
+
}
|
123
|
+
break;
|
124
|
+
default:
|
125
|
+
if (console && console.log) console.log("unknown node type", elem.nodeType);
|
126
|
+
break;
|
127
|
+
}
|
128
|
+
|
129
|
+
}
|
130
|
+
|
131
|
+
function _clean_element(elem) {
|
132
|
+
var i, j, clone, parent_element, name, allowed_attributes, attr, attr_name, attr_node, protocols, del, attr_ok;
|
133
|
+
var transform = _transform_element.call(this, elem);
|
134
|
+
|
135
|
+
elem = transform.node;
|
136
|
+
name = elem.nodeName.toLowerCase();
|
137
|
+
|
138
|
+
// check if element itself is allowed
|
139
|
+
parent_element = this.current_element;
|
140
|
+
if(this.allowed_elements[name] || transform.whitelist) {
|
141
|
+
this.current_element = this.dom.createElement(elem.nodeName);
|
142
|
+
parent_element.appendChild(this.current_element);
|
143
|
+
|
144
|
+
// clean attributes
|
145
|
+
var attrs = this.config.attributes;
|
146
|
+
allowed_attributes = _merge_arrays_uniq(attrs[name], attrs[Sanitize.ALL], transform.attr_whitelist);
|
147
|
+
for(i=0;i<allowed_attributes.length;i++) {
|
148
|
+
attr_name = allowed_attributes[i];
|
149
|
+
attr = elem.attributes[attr_name];
|
150
|
+
if(attr) {
|
151
|
+
attr_ok = true;
|
152
|
+
// Check protocol attributes for valid protocol
|
153
|
+
if(this.config.protocols[name] && this.config.protocols[name][attr_name]) {
|
154
|
+
protocols = this.config.protocols[name][attr_name];
|
155
|
+
del = attr.value.toLowerCase().match(Sanitize.REGEX_PROTOCOL);
|
156
|
+
if(del) {
|
157
|
+
attr_ok = (_array_index(del[1], protocols) != -1);
|
158
|
+
}
|
159
|
+
else {
|
160
|
+
attr_ok = (_array_index(Sanitize.RELATIVE, protocols) != -1);
|
161
|
+
}
|
162
|
+
}
|
163
|
+
if(attr_ok) {
|
164
|
+
attr_node = document.createAttribute(attr_name);
|
165
|
+
attr_node.value = attr.value;
|
166
|
+
this.current_element.setAttributeNode(attr_node);
|
167
|
+
}
|
168
|
+
}
|
169
|
+
}
|
170
|
+
|
171
|
+
// Add attributes
|
172
|
+
if(this.config.add_attributes[name]) {
|
173
|
+
for(attr_name in this.config.add_attributes[name]) {
|
174
|
+
attr_node = document.createAttribute(attr_name);
|
175
|
+
attr_node.value = this.config.add_attributes[name][attr_name];
|
176
|
+
this.current_element.setAttributeNode(attr_node);
|
177
|
+
}
|
178
|
+
}
|
179
|
+
} // End checking if element is allowed
|
180
|
+
// If this node is in the dynamic whitelist array (built at runtime by
|
181
|
+
// transformers), let it live with all of its attributes intact.
|
182
|
+
else if(_array_index(elem, this.whitelist_nodes) != -1) {
|
183
|
+
this.current_element = elem.cloneNode(true);
|
184
|
+
// Remove child nodes, they will be sanitiazied and added by other code
|
185
|
+
while(this.current_element.childNodes.length > 0) {
|
186
|
+
this.current_element.removeChild(this.current_element.firstChild);
|
187
|
+
}
|
188
|
+
parent_element.appendChild(this.current_element);
|
189
|
+
}
|
190
|
+
|
191
|
+
// iterate over child nodes
|
192
|
+
if(!this.config.remove_all_contents && !this.config.remove_element_contents[name]) {
|
193
|
+
for(i=0;i<elem.childNodes.length;i++) {
|
194
|
+
_clean.call(this, elem.childNodes[i]);
|
195
|
+
}
|
196
|
+
}
|
197
|
+
|
198
|
+
// some versions of IE don't support normalize.
|
199
|
+
if(this.current_element.normalize) {
|
200
|
+
this.current_element.normalize();
|
201
|
+
}
|
202
|
+
this.current_element = parent_element;
|
203
|
+
} // END clean_element function
|
204
|
+
|
205
|
+
function _transform_element(node) {
|
206
|
+
var output = {
|
207
|
+
attr_whitelist:[],
|
208
|
+
node: node,
|
209
|
+
whitelist: false
|
210
|
+
};
|
211
|
+
var i, j, transform;
|
212
|
+
for(i=0;i<this.transformers.length;i++) {
|
213
|
+
transform = this.transformers[i]({
|
214
|
+
allowed_elements: this.allowed_elements,
|
215
|
+
config: this.config,
|
216
|
+
node: node,
|
217
|
+
node_name: node.nodeName.toLowerCase(),
|
218
|
+
whitelist_nodes: this.whitelist_nodes,
|
219
|
+
dom: this.dom
|
220
|
+
});
|
221
|
+
if (transform == null)
|
222
|
+
continue;
|
223
|
+
else if(typeof transform == 'object') {
|
224
|
+
if(transform.whitelist_nodes && transform.whitelist_nodes instanceof Array) {
|
225
|
+
for(j=0;j<transform.whitelist_nodes.length;j++) {
|
226
|
+
if(_array_index(transform.whitelist_nodes[j], this.whitelist_nodes) == -1) {
|
227
|
+
this.whitelist_nodes.push(transform.whitelist_nodes[j]);
|
228
|
+
}
|
229
|
+
}
|
230
|
+
}
|
231
|
+
output.whitelist = transform.whitelist ? true : false;
|
232
|
+
if(transform.attr_whitelist) {
|
233
|
+
output.attr_whitelist = _merge_arrays_uniq(output.attr_whitelist, transform.attr_whitelist);
|
234
|
+
}
|
235
|
+
output.node = transform.node ? transform.node : output.node;
|
236
|
+
}
|
237
|
+
else {
|
238
|
+
throw new Error("transformer output must be an object or null");
|
239
|
+
}
|
240
|
+
}
|
241
|
+
return output;
|
242
|
+
}
|
243
|
+
|
244
|
+
|
245
|
+
|
246
|
+
for(i=0;i<container.childNodes.length;i++) {
|
247
|
+
_clean.call(this, container.childNodes[i]);
|
248
|
+
}
|
249
|
+
|
250
|
+
if(fragment.normalize) {
|
251
|
+
fragment.normalize();
|
252
|
+
}
|
253
|
+
|
254
|
+
return fragment;
|
255
|
+
|
256
|
+
};
|
257
|
+
|
258
|
+
if ( typeof define === "function" ) {
|
259
|
+
define( "sanitize", [], function () { return Sanitize; } );
|
260
|
+
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
if(!Sanitize.Config) {
|
2
|
+
Sanitize.Config = {}
|
3
|
+
}
|
4
|
+
|
5
|
+
Sanitize.Config.BASIC = {
|
6
|
+
elements: [
|
7
|
+
'a', 'b', 'blockquote', 'br', 'cite', 'code', 'dd', 'dl', 'dt', 'em',
|
8
|
+
'i', 'li', 'ol', 'p', 'pre', 'q', 'small', 'strike', 'strong', 'sub',
|
9
|
+
'sup', 'u', 'ul'],
|
10
|
+
|
11
|
+
attributes: {
|
12
|
+
'a' : ['href'],
|
13
|
+
'blockquote': ['cite'],
|
14
|
+
'q' : ['cite']
|
15
|
+
},
|
16
|
+
|
17
|
+
add_attributes: {
|
18
|
+
'a': {'rel': 'nofollow'}
|
19
|
+
},
|
20
|
+
|
21
|
+
protocols: {
|
22
|
+
'a' : {'href': ['ftp', 'http', 'https', 'mailto',
|
23
|
+
Sanitize.RELATIVE]},
|
24
|
+
'blockquote': {'cite': ['http', 'https', Sanitize.RELATIVE]},
|
25
|
+
'q' : {'cite': ['http', 'https', Sanitize.RELATIVE]}
|
26
|
+
}
|
27
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
if(!Sanitize.Config) {
|
2
|
+
Sanitize.Config = {}
|
3
|
+
}
|
4
|
+
|
5
|
+
Sanitize.Config.RELAXED = {
|
6
|
+
elements: [
|
7
|
+
'a', 'b', 'blockquote', 'br', 'caption', 'cite', 'code', 'col',
|
8
|
+
'colgroup', 'dd', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
|
9
|
+
'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'small', 'strike', 'strong',
|
10
|
+
'sub', 'sup', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'u',
|
11
|
+
'ul'],
|
12
|
+
|
13
|
+
attributes: {
|
14
|
+
'a' : ['href', 'title'],
|
15
|
+
'blockquote': ['cite'],
|
16
|
+
'col' : ['span', 'width'],
|
17
|
+
'colgroup' : ['span', 'width'],
|
18
|
+
'img' : ['align', 'alt', 'height', 'src', 'title', 'width'],
|
19
|
+
'ol' : ['start', 'type'],
|
20
|
+
'q' : ['cite'],
|
21
|
+
'table' : ['summary', 'width'],
|
22
|
+
'td' : ['abbr', 'axis', 'colspan', 'rowspan', 'width'],
|
23
|
+
'th' : ['abbr', 'axis', 'colspan', 'rowspan', 'scope',
|
24
|
+
'width'],
|
25
|
+
'ul' : ['type']
|
26
|
+
},
|
27
|
+
|
28
|
+
protocols: {
|
29
|
+
'a' : {'href': ['ftp', 'http', 'https', 'mailto',
|
30
|
+
Sanitize.RELATIVE]},
|
31
|
+
'blockquote': {'cite': ['http', 'https', Sanitize.RELATIVE]},
|
32
|
+
'img' : {'src' : ['http', 'https', Sanitize.RELATIVE]},
|
33
|
+
'q' : {'cite': ['http', 'https', Sanitize.RELATIVE]}
|
34
|
+
}
|
35
|
+
}
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rails-sanitize-js
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gabriel Birke
|
8
|
+
- Nick Chernyshev
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2015-06-19 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Add Sanitize.js into your asset pipeline.
|
15
|
+
email:
|
16
|
+
- nick.chernyshev@gmail.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- ".gitignore"
|
22
|
+
- Gemfile
|
23
|
+
- MIT-LICENSE
|
24
|
+
- README.md
|
25
|
+
- Rakefile
|
26
|
+
- lib/rails-sanitize-js.rb
|
27
|
+
- lib/rails-sanitize-js/engine.rb
|
28
|
+
- lib/rails-sanitize-js/version.rb
|
29
|
+
- rails-sanitize-js.gemspec
|
30
|
+
- vendor/assets/javascripts/sanitize.js
|
31
|
+
- vendor/assets/javascripts/sanitize/config/basic.js
|
32
|
+
- vendor/assets/javascripts/sanitize/config/relaxed.js
|
33
|
+
- vendor/assets/javascripts/sanitize/config/restricted.js
|
34
|
+
homepage: https://github.com/flowerett/rails-sanitize-js
|
35
|
+
licenses:
|
36
|
+
- MIT
|
37
|
+
metadata: {}
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
requirements: []
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 2.4.6
|
55
|
+
signing_key:
|
56
|
+
specification_version: 4
|
57
|
+
summary: Sanitize.js for rails assets
|
58
|
+
test_files: []
|