UNPKG

13.1 kBMarkdownView Raw
1[![NPM version][npm-image]][npm-url]
2[![build status][travis-image]][travis-url]
3[![Test coverage][coveralls-image]][coveralls-url]
4[![David deps][david-image]][david-url]
5[![node version][node-image]][node-url]
6[![npm download][download-image]][download-url]
7[![npm license][license-image]][download-url]
8
9[npm-image]: https://img.shields.io/npm/v/xss.svg?style=flat-square
10[npm-url]: https://npmjs.org/package/xss
11[travis-image]: https://img.shields.io/travis/leizongmin/js-xss.svg?style=flat-square
12[travis-url]: https://travis-ci.org/leizongmin/js-xss
13[coveralls-image]: https://img.shields.io/coveralls/leizongmin/js-xss.svg?style=flat-square
14[coveralls-url]: https://coveralls.io/r/leizongmin/js-xss?branch=master
15[david-image]: https://img.shields.io/david/leizongmin/js-xss.svg?style=flat-square
16[david-url]: https://david-dm.org/leizongmin/js-xss
17[node-image]: https://img.shields.io/badge/node.js-%3E=_0.10-green.svg?style=flat-square
18[node-url]: http://nodejs.org/download/
19[download-image]: https://img.shields.io/npm/dm/xss.svg?style=flat-square
20[download-url]: https://npmjs.org/package/xss
21[license-image]: https://img.shields.io/npm/l/xss.svg
22
23# Sanitize untrusted HTML (to prevent XSS) with a configuration specified by a Whitelist.
24
25[![Greenkeeper badge](https://badges.greenkeeper.io/leizongmin/js-xss.svg)](https://greenkeeper.io/)
26
27![xss](https://nodei.co/npm/xss.png?downloads=true&stars=true)
28
29---
30
31`xss` is a module used to filter input from users to prevent XSS attacks.
32([What is XSS attack?](http://en.wikipedia.org/wiki/Cross-site_scripting))
33
34**Project Homepage:** http://jsxss.com
35
36**Try Online:** http://jsxss.com/en/try.html
37
38**[中文版文档](https://github.com/leizongmin/js-xss/blob/master/README.zh.md)**
39
40---
41
42## Features
43
44* Specifies HTML tags and their attributes allowed with whitelist
45* Handle any tags or attributes using custom function.
46
47## Reference
48
49* [XSS Filter Evasion Cheat Sheet](https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet)
50* [Data URI scheme](http://en.wikipedia.org/wiki/Data_URI_scheme)
51* [XSS with Data URI Scheme](http://hi.baidu.com/badzzzz/item/bdbafe83144619c199255f7b)
52
53## Benchmark (for references only)
54
55* the xss module: 8.2 MB/s
56* `xss()` function from module `validator@0.3.7`: 4.4 MB/s
57
58For test code please refer to `benchmark` directory.
59
60## They are using xss module
61
62* **nodeclub** - A Node.js bbs using MongoDB - https://github.com/cnodejs/nodeclub
63* **cnpmjs.org** - Private npm registry and web for Enterprise - https://github.com/cnpm/cnpmjs.org
64
65## Install
66
67### NPM
68
69```bash
70$ npm install xss
71```
72
73### Bower
74
75```bash
76$ bower install xss
77```
78
79Or
80
81```bash
82$ bower install https://github.com/leizongmin/js-xss.git
83```
84
85## Usages
86
87### On Node.js
88
89```javascript
90var xss = require("xss");
91var html = xss('<script>alert("xss");</script>');
92console.log(html);
93```
94
95### On Browser
96
97Shim mode (reference file `test/test.html`):
98
99```html
100<script src="https://raw.github.com/leizongmin/js-xss/master/dist/xss.js"></script>
101<script>
102// apply function filterXSS in the same way
103var html = filterXSS('<script>alert("xss");</scr' + 'ipt>');
104alert(html);
105</script>
106```
107
108AMD mode - shim:
109
110```html
111<script>
112require.config({
113 baseUrl: './',
114 paths: {
115 xss: 'https://raw.github.com/leizongmin/js-xss/master/dist/xss.js'
116 },
117 shim: {
118 xss: {exports: 'filterXSS'}
119 }
120})
121require(['xss'], function (xss) {
122 var html = xss('<script>alert("xss");</scr' + 'ipt>');
123 alert(html);
124});
125</script>
126```
127
128## Command Line Tool
129
130### Process File
131
132You can use the xss command line tool to process a file. Usage:
133
134```bash
135xss -i <input_file> -o <output_file>
136```
137
138Example:
139
140```bash
141$ xss -i origin.html -o target.html
142```
143
144### Active Test
145
146Run the following command, them you can type HTML
147code in the command-line, and check the filtered output:
148
149```bash
150$ xss -t
151```
152
153For more details, please run `$ xss -h` to see it.
154
155## Custom filter rules
156
157When using the `xss()` function, the second parameter could be used to specify
158custom rules:
159
160```javascript
161options = {}; // Custom rules
162html = xss('<script>alert("xss");</script>', options);
163```
164
165To avoid passing `options` every time, you can also do it in a faster way by
166creating a `FilterXSS` instance:
167
168```javascript
169options = {}; // Custom rules
170myxss = new xss.FilterXSS(options);
171// then apply myxss.process()
172html = myxss.process('<script>alert("xss");</script>');
173```
174
175Details of parameters in `options` would be described below.
176
177### Whitelist
178
179By specifying a `whiteList`, e.g. `{ 'tagName': [ 'attr-1', 'attr-2' ] }`. Tags
180and attributes not in the whitelist would be filter out. For example:
181
182```javascript
183// only tag a and its attributes href, title, target are allowed
184var options = {
185 whiteList: {
186 a: ["href", "title", "target"]
187 }
188};
189// With the configuration specified above, the following HTML:
190// <a href="#" onclick="hello()"><i>Hello</i></a>
191// would become:
192// <a href="#">Hello</a>
193```
194
195For the default whitelist, please refer `xss.whiteList`.
196
197### Customize the handler function for matched tags
198
199By specifying the handler function with `onTag`:
200
201```javascript
202function onTag(tag, html, options) {
203 // tag is the name of current tag, e.g. 'a' for tag <a>
204 // html is the HTML of this tag, e.g. '<a>' for tag <a>
205 // options is some addition informations:
206 // isWhite boolean, whether the tag is in whitelist
207 // isClosing boolean, whether the tag is a closing tag, e.g. true for </a>
208 // position integer, the position of the tag in output result
209 // sourcePosition integer, the position of the tag in input HTML source
210 // If a string is returned, the current tag would be replaced with the string
211 // If return nothing, the default measure would be taken:
212 // If in whitelist: filter attributes using onTagAttr, as described below
213 // If not in whitelist: handle by onIgnoreTag, as described below
214}
215```
216
217### Customize the handler function for attributes of matched tags
218
219By specifying the handler function with `onTagAttr`:
220
221```javascript
222function onTagAttr(tag, name, value, isWhiteAttr) {
223 // tag is the name of current tag, e.g. 'a' for tag <a>
224 // name is the name of current attribute, e.g. 'href' for href="#"
225 // isWhiteAttr whether the attribute is in whitelist
226 // If a string is returned, the attribute would be replaced with the string
227 // If return nothing, the default measure would be taken:
228 // If in whitelist: filter the value using safeAttrValue as described below
229 // If not in whitelist: handle by onIgnoreTagAttr, as described below
230}
231```
232
233### Customize the handler function for tags not in the whitelist
234
235By specifying the handler function with `onIgnoreTag`:
236
237```javascript
238function onIgnoreTag(tag, html, options) {
239 // Parameters are the same with onTag
240 // If a string is returned, the tag would be replaced with the string
241 // If return nothing, the default measure would be taken (specifies using
242 // escape, as described below)
243}
244```
245
246### Customize the handler function for attributes not in the whitelist
247
248By specifying the handler function with `onIgnoreTagAttr`:
249
250```javascript
251function onIgnoreTagAttr(tag, name, value, isWhiteAttr) {
252 // Parameters are the same with onTagAttr
253 // If a string is returned, the value would be replaced with this string
254 // If return nothing, then keep default (remove the attribute)
255}
256```
257
258### Customize escaping function for HTML
259
260By specifying the handler function with `escapeHtml`. Following is the default
261function **(Modification is not recommended)**:
262
263```javascript
264function escapeHtml(html) {
265 return html.replace(/</g, "&lt;").replace(/>/g, "&gt;");
266}
267```
268
269### Customize escaping function for value of attributes
270
271By specifying the handler function with `safeAttrValue`:
272
273```javascript
274function safeAttrValue(tag, name, value) {
275 // Parameters are the same with onTagAttr (without options)
276 // Return the value as a string
277}
278```
279
280### Customize CSS filter
281
282If you allow the attribute `style`, the value will be processed by [cssfilter](https://github.com/leizongmin/js-css-filter) module. The cssfilter module includes a default css whitelist. You can specify the options for cssfilter module like this:
283
284```javascript
285myxss = new xss.FilterXSS({
286 css: {
287 whiteList: {
288 position: /^fixed|relative$/,
289 top: true,
290 left: true
291 }
292 }
293});
294html = myxss.process('<script>alert("xss");</script>');
295```
296
297If you don't want to filter out the `style` content, just specify `false` to the `css` option:
298
299```javascript
300myxss = new xss.FilterXSS({
301 css: false
302});
303```
304
305For more help, please see https://github.com/leizongmin/js-css-filter
306
307### Quick Start
308
309#### Filter out tags not in the whitelist
310
311By using `stripIgnoreTag` parameter:
312
313* `true` filter out tags not in the whitelist
314* `false`: by default: escape the tag using configured `escape` function
315
316Example:
317
318If `stripIgnoreTag = true` is set, the following code:
319
320```html
321code:<script>alert(/xss/);</script>
322```
323
324would output filtered:
325
326```html
327code:alert(/xss/);
328```
329
330#### Filter out tags and tag bodies not in the whitelist
331
332By using `stripIgnoreTagBody` parameter:
333
334* `false|null|undefined` by default: do nothing
335* `'*'|true`: filter out all tags not in the whitelist
336* `['tag1', 'tag2']`: filter out only specified tags not in the whitelist
337
338Example:
339
340If `stripIgnoreTagBody = ['script']` is set, the following code:
341
342```html
343code:<script>alert(/xss/);</script>
344```
345
346would output filtered:
347
348```html
349code:
350```
351
352#### Filter out HTML comments
353
354By using `allowCommentTag` parameter:
355
356* `true`: do nothing
357* `false` by default: filter out HTML comments
358
359Example:
360
361If `allowCommentTag = false` is set, the following code:
362
363```html
364code:<!-- something --> END
365```
366
367would output filtered:
368
369```html
370code: END
371```
372
373## Examples
374
375### Allow attributes of whitelist tags start with `data-`
376
377```javascript
378var source = '<div a="1" b="2" data-a="3" data-b="4">hello</div>';
379var html = xss(source, {
380 onIgnoreTagAttr: function(tag, name, value, isWhiteAttr) {
381 if (name.substr(0, 5) === "data-") {
382 // escape its value using built-in escapeAttrValue function
383 return name + '="' + xss.escapeAttrValue(value) + '"';
384 }
385 }
386});
387
388console.log("%s\nconvert to:\n%s", source, html);
389```
390
391Result:
392
393```html
394<div a="1" b="2" data-a="3" data-b="4">hello</div>
395convert to:
396<div data-a="3" data-b="4">hello</div>
397```
398
399### Allow tags start with `x-`
400
401```javascript
402var source = "<x><x-1>he<x-2 checked></x-2>wwww</x-1><a>";
403var html = xss(source, {
404 onIgnoreTag: function(tag, html, options) {
405 if (tag.substr(0, 2) === "x-") {
406 // do not filter its attributes
407 return html;
408 }
409 }
410});
411
412console.log("%s\nconvert to:\n%s", source, html);
413```
414
415Result:
416
417```html
418<x><x-1>he<x-2 checked></x-2>wwww</x-1><a>
419convert to:
420&lt;x&gt;<x-1>he<x-2 checked></x-2>wwww</x-1><a>
421```
422
423### Parse images in HTML
424
425```javascript
426var source =
427 '<img src="img1">a<img src="img2">b<img src="img3">c<img src="img4">d';
428var list = [];
429var html = xss(source, {
430 onTagAttr: function(tag, name, value, isWhiteAttr) {
431 if (tag === "img" && name === "src") {
432 // Use the built-in friendlyAttrValue function to escape attribute
433 // values. It supports converting entity tags such as &lt; to printable
434 // characters such as <
435 list.push(xss.friendlyAttrValue(value));
436 }
437 // Return nothing, means keep the default handling measure
438 }
439});
440
441console.log("image list:\n%s", list.join(", "));
442```
443
444Result:
445
446```html
447image list:
448img1, img2, img3, img4
449```
450
451### Filter out HTML tags (keeps only plain text)
452
453```javascript
454var source = "<strong>hello</strong><script>alert(/xss/);</script>end";
455var html = xss(source, {
456 whiteList: [], // empty, means filter out all tags
457 stripIgnoreTag: true, // filter out all HTML not in the whilelist
458 stripIgnoreTagBody: ["script"] // the script tag is a special case, we need
459 // to filter out its content
460});
461
462console.log("text: %s", html);
463```
464
465Result:
466
467```html
468text: helloend
469```
470
471## License
472
473```text
474Copyright (c) 2012-2017 Zongmin Lei(雷宗民) <leizongmin@gmail.com>
475http://ucdok.com
476
477The MIT License
478
479Permission is hereby granted, free of charge, to any person obtaining
480a copy of this software and associated documentation files (the
481"Software"), to deal in the Software without restriction, including
482without limitation the rights to use, copy, modify, merge, publish,
483distribute, sublicense, and/or sell copies of the Software, and to
484permit persons to whom the Software is furnished to do so, subject to
485the following conditions:
486
487The above copyright notice and this permission notice shall be
488included in all copies or substantial portions of the Software.
489
490THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
491EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
492MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
493NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
494LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
495OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
496WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
497```