UNPKG

13.2 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
70npm install xss
71```
72
73### Bower
74
75```bash
76bower install xss
77```
78
79Or
80
81```bash
82bower 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://rawgit.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://rawgit.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**Notes: please don't use the URL https://rawgit.com/leizongmin/js-xss/master/dist/xss.js in production environment.**
129
130## Command Line Tool
131
132### Process File
133
134You can use the xss command line tool to process a file. Usage:
135
136```bash
137xss -i <input_file> -o <output_file>
138```
139
140Example:
141
142```bash
143xss -i origin.html -o target.html
144```
145
146### Active Test
147
148Run the following command, them you can type HTML
149code in the command-line, and check the filtered output:
150
151```bash
152xss -t
153```
154
155For more details, please run `$ xss -h` to see it.
156
157## Custom filter rules
158
159When using the `xss()` function, the second parameter could be used to specify
160custom rules:
161
162```javascript
163options = {}; // Custom rules
164html = xss('<script>alert("xss");</script>', options);
165```
166
167To avoid passing `options` every time, you can also do it in a faster way by
168creating a `FilterXSS` instance:
169
170```javascript
171options = {}; // Custom rules
172myxss = new xss.FilterXSS(options);
173// then apply myxss.process()
174html = myxss.process('<script>alert("xss");</script>');
175```
176
177Details of parameters in `options` would be described below.
178
179### Whitelist
180
181By specifying a `whiteList`, e.g. `{ 'tagName': [ 'attr-1', 'attr-2' ] }`. Tags
182and attributes not in the whitelist would be filter out. For example:
183
184```javascript
185// only tag a and its attributes href, title, target are allowed
186var options = {
187 whiteList: {
188 a: ["href", "title", "target"]
189 }
190};
191// With the configuration specified above, the following HTML:
192// <a href="#" onclick="hello()"><i>Hello</i></a>
193// would become:
194// <a href="#">Hello</a>
195```
196
197For the default whitelist, please refer `xss.whiteList`.
198
199### Customize the handler function for matched tags
200
201By specifying the handler function with `onTag`:
202
203```javascript
204function onTag(tag, html, options) {
205 // tag is the name of current tag, e.g. 'a' for tag <a>
206 // html is the HTML of this tag, e.g. '<a>' for tag <a>
207 // options is some addition informations:
208 // isWhite boolean, whether the tag is in whitelist
209 // isClosing boolean, whether the tag is a closing tag, e.g. true for </a>
210 // position integer, the position of the tag in output result
211 // sourcePosition integer, the position of the tag in input HTML source
212 // If a string is returned, the current tag would be replaced with the string
213 // If return nothing, the default measure would be taken:
214 // If in whitelist: filter attributes using onTagAttr, as described below
215 // If not in whitelist: handle by onIgnoreTag, as described below
216}
217```
218
219### Customize the handler function for attributes of matched tags
220
221By specifying the handler function with `onTagAttr`:
222
223```javascript
224function onTagAttr(tag, name, value, isWhiteAttr) {
225 // tag is the name of current tag, e.g. 'a' for tag <a>
226 // name is the name of current attribute, e.g. 'href' for href="#"
227 // isWhiteAttr whether the attribute is in whitelist
228 // If a string is returned, the attribute would be replaced with the string
229 // If return nothing, the default measure would be taken:
230 // If in whitelist: filter the value using safeAttrValue as described below
231 // If not in whitelist: handle by onIgnoreTagAttr, as described below
232}
233```
234
235### Customize the handler function for tags not in the whitelist
236
237By specifying the handler function with `onIgnoreTag`:
238
239```javascript
240function onIgnoreTag(tag, html, options) {
241 // Parameters are the same with onTag
242 // If a string is returned, the tag would be replaced with the string
243 // If return nothing, the default measure would be taken (specifies using
244 // escape, as described below)
245}
246```
247
248### Customize the handler function for attributes not in the whitelist
249
250By specifying the handler function with `onIgnoreTagAttr`:
251
252```javascript
253function onIgnoreTagAttr(tag, name, value, isWhiteAttr) {
254 // Parameters are the same with onTagAttr
255 // If a string is returned, the value would be replaced with this string
256 // If return nothing, then keep default (remove the attribute)
257}
258```
259
260### Customize escaping function for HTML
261
262By specifying the handler function with `escapeHtml`. Following is the default
263function **(Modification is not recommended)**:
264
265```javascript
266function escapeHtml(html) {
267 return html.replace(/</g, "&lt;").replace(/>/g, "&gt;");
268}
269```
270
271### Customize escaping function for value of attributes
272
273By specifying the handler function with `safeAttrValue`:
274
275```javascript
276function safeAttrValue(tag, name, value) {
277 // Parameters are the same with onTagAttr (without options)
278 // Return the value as a string
279}
280```
281
282### Customize CSS filter
283
284If 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:
285
286```javascript
287myxss = new xss.FilterXSS({
288 css: {
289 whiteList: {
290 position: /^fixed|relative$/,
291 top: true,
292 left: true
293 }
294 }
295});
296html = myxss.process('<script>alert("xss");</script>');
297```
298
299If you don't want to filter out the `style` content, just specify `false` to the `css` option:
300
301```javascript
302myxss = new xss.FilterXSS({
303 css: false
304});
305```
306
307For more help, please see https://github.com/leizongmin/js-css-filter
308
309### Quick Start
310
311#### Filter out tags not in the whitelist
312
313By using `stripIgnoreTag` parameter:
314
315* `true` filter out tags not in the whitelist
316* `false`: by default: escape the tag using configured `escape` function
317
318Example:
319
320If `stripIgnoreTag = true` is set, the following code:
321
322```html
323code:<script>alert(/xss/);</script>
324```
325
326would output filtered:
327
328```html
329code:alert(/xss/);
330```
331
332#### Filter out tags and tag bodies not in the whitelist
333
334By using `stripIgnoreTagBody` parameter:
335
336* `false|null|undefined` by default: do nothing
337* `'*'|true`: filter out all tags not in the whitelist
338* `['tag1', 'tag2']`: filter out only specified tags not in the whitelist
339
340Example:
341
342If `stripIgnoreTagBody = ['script']` is set, the following code:
343
344```html
345code:<script>alert(/xss/);</script>
346```
347
348would output filtered:
349
350```html
351code:
352```
353
354#### Filter out HTML comments
355
356By using `allowCommentTag` parameter:
357
358* `true`: do nothing
359* `false` by default: filter out HTML comments
360
361Example:
362
363If `allowCommentTag = false` is set, the following code:
364
365```html
366code:<!-- something --> END
367```
368
369would output filtered:
370
371```html
372code: END
373```
374
375## Examples
376
377### Allow attributes of whitelist tags start with `data-`
378
379```javascript
380var source = '<div a="1" b="2" data-a="3" data-b="4">hello</div>';
381var html = xss(source, {
382 onIgnoreTagAttr: function(tag, name, value, isWhiteAttr) {
383 if (name.substr(0, 5) === "data-") {
384 // escape its value using built-in escapeAttrValue function
385 return name + '="' + xss.escapeAttrValue(value) + '"';
386 }
387 }
388});
389
390console.log("%s\nconvert to:\n%s", source, html);
391```
392
393Result:
394
395```html
396<div a="1" b="2" data-a="3" data-b="4">hello</div>
397convert to:
398<div data-a="3" data-b="4">hello</div>
399```
400
401### Allow tags start with `x-`
402
403```javascript
404var source = "<x><x-1>he<x-2 checked></x-2>wwww</x-1><a>";
405var html = xss(source, {
406 onIgnoreTag: function(tag, html, options) {
407 if (tag.substr(0, 2) === "x-") {
408 // do not filter its attributes
409 return html;
410 }
411 }
412});
413
414console.log("%s\nconvert to:\n%s", source, html);
415```
416
417Result:
418
419```html
420<x><x-1>he<x-2 checked></x-2>wwww</x-1><a>
421convert to:
422&lt;x&gt;<x-1>he<x-2 checked></x-2>wwww</x-1><a>
423```
424
425### Parse images in HTML
426
427```javascript
428var source =
429 '<img src="img1">a<img src="img2">b<img src="img3">c<img src="img4">d';
430var list = [];
431var html = xss(source, {
432 onTagAttr: function(tag, name, value, isWhiteAttr) {
433 if (tag === "img" && name === "src") {
434 // Use the built-in friendlyAttrValue function to escape attribute
435 // values. It supports converting entity tags such as &lt; to printable
436 // characters such as <
437 list.push(xss.friendlyAttrValue(value));
438 }
439 // Return nothing, means keep the default handling measure
440 }
441});
442
443console.log("image list:\n%s", list.join(", "));
444```
445
446Result:
447
448```html
449image list:
450img1, img2, img3, img4
451```
452
453### Filter out HTML tags (keeps only plain text)
454
455```javascript
456var source = "<strong>hello</strong><script>alert(/xss/);</script>end";
457var html = xss(source, {
458 whiteList: [], // empty, means filter out all tags
459 stripIgnoreTag: true, // filter out all HTML not in the whilelist
460 stripIgnoreTagBody: ["script"] // the script tag is a special case, we need
461 // to filter out its content
462});
463
464console.log("text: %s", html);
465```
466
467Result:
468
469```html
470text: helloend
471```
472
473## License
474
475```text
476Copyright (c) 2012-2018 Zongmin Lei(雷宗民) <leizongmin@gmail.com>
477http://ucdok.com
478
479The MIT License
480
481Permission is hereby granted, free of charge, to any person obtaining
482a copy of this software and associated documentation files (the
483"Software"), to deal in the Software without restriction, including
484without limitation the rights to use, copy, modify, merge, publish,
485distribute, sublicense, and/or sell copies of the Software, and to
486permit persons to whom the Software is furnished to do so, subject to
487the following conditions:
488
489The above copyright notice and this permission notice shall be
490included in all copies or substantial portions of the Software.
491
492THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
493EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
494MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
495NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
496LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
497OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
498WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
499```