From 70aa7a5cb9de83c0966985618d6e6d4d4400dd0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=20Luka=20=C5=A0ijanec?= Date: Sun, 9 Feb 2020 00:38:26 +0100 Subject: added images support to messages and removed npm and node modules dependency --- node_modules/xss/LICENSE | 23 - node_modules/xss/README.md | 499 ------------ node_modules/xss/README.zh.md | 485 ----------- node_modules/xss/bin/xss | 67 -- node_modules/xss/dist/test.html | 15 - node_modules/xss/dist/xss.js | 1609 ------------------------------------- node_modules/xss/dist/xss.min.js | 1 - node_modules/xss/lib/cli.js | 45 -- node_modules/xss/lib/default.js | 415 ---------- node_modules/xss/lib/index.js | 40 - node_modules/xss/lib/parser.js | 239 ------ node_modules/xss/lib/util.js | 34 - node_modules/xss/lib/xss.js | 211 ----- node_modules/xss/package.json | 92 --- node_modules/xss/typings/xss.d.ts | 189 ----- 15 files changed, 3964 deletions(-) delete mode 100644 node_modules/xss/LICENSE delete mode 100644 node_modules/xss/README.md delete mode 100644 node_modules/xss/README.zh.md delete mode 100755 node_modules/xss/bin/xss delete mode 100644 node_modules/xss/dist/test.html delete mode 100644 node_modules/xss/dist/xss.js delete mode 100644 node_modules/xss/dist/xss.min.js delete mode 100644 node_modules/xss/lib/cli.js delete mode 100644 node_modules/xss/lib/default.js delete mode 100644 node_modules/xss/lib/index.js delete mode 100644 node_modules/xss/lib/parser.js delete mode 100644 node_modules/xss/lib/util.js delete mode 100644 node_modules/xss/lib/xss.js delete mode 100644 node_modules/xss/package.json delete mode 100644 node_modules/xss/typings/xss.d.ts (limited to 'node_modules/xss') diff --git a/node_modules/xss/LICENSE b/node_modules/xss/LICENSE deleted file mode 100644 index f840eb4..0000000 --- a/node_modules/xss/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -Copyright (c) 2012-2018 Zongmin Lei(雷宗民) -http://ucdok.com - -The MIT License - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/xss/README.md b/node_modules/xss/README.md deleted file mode 100644 index 4f202f1..0000000 --- a/node_modules/xss/README.md +++ /dev/null @@ -1,499 +0,0 @@ -[![NPM version][npm-image]][npm-url] -[![build status][travis-image]][travis-url] -[![Test coverage][coveralls-image]][coveralls-url] -[![David deps][david-image]][david-url] -[![node version][node-image]][node-url] -[![npm download][download-image]][download-url] -[![npm license][license-image]][download-url] - -[npm-image]: https://img.shields.io/npm/v/xss.svg?style=flat-square -[npm-url]: https://npmjs.org/package/xss -[travis-image]: https://img.shields.io/travis/leizongmin/js-xss.svg?style=flat-square -[travis-url]: https://travis-ci.org/leizongmin/js-xss -[coveralls-image]: https://img.shields.io/coveralls/leizongmin/js-xss.svg?style=flat-square -[coveralls-url]: https://coveralls.io/r/leizongmin/js-xss?branch=master -[david-image]: https://img.shields.io/david/leizongmin/js-xss.svg?style=flat-square -[david-url]: https://david-dm.org/leizongmin/js-xss -[node-image]: https://img.shields.io/badge/node.js-%3E=_0.10-green.svg?style=flat-square -[node-url]: http://nodejs.org/download/ -[download-image]: https://img.shields.io/npm/dm/xss.svg?style=flat-square -[download-url]: https://npmjs.org/package/xss -[license-image]: https://img.shields.io/npm/l/xss.svg - -# Sanitize untrusted HTML (to prevent XSS) with a configuration specified by a Whitelist. - -[![Greenkeeper badge](https://badges.greenkeeper.io/leizongmin/js-xss.svg)](https://greenkeeper.io/) - -![xss](https://nodei.co/npm/xss.png?downloads=true&stars=true) - ---- - -`xss` is a module used to filter input from users to prevent XSS attacks. -([What is XSS attack?](http://en.wikipedia.org/wiki/Cross-site_scripting)) - -**Project Homepage:** http://jsxss.com - -**Try Online:** http://jsxss.com/en/try.html - -**[中文版文档](https://github.com/leizongmin/js-xss/blob/master/README.zh.md)** - ---- - -## Features - -* Specifies HTML tags and their attributes allowed with whitelist -* Handle any tags or attributes using custom function. - -## Reference - -* [XSS Filter Evasion Cheat Sheet](https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet) -* [Data URI scheme](http://en.wikipedia.org/wiki/Data_URI_scheme) -* [XSS with Data URI Scheme](http://hi.baidu.com/badzzzz/item/bdbafe83144619c199255f7b) - -## Benchmark (for references only) - -* the xss module: 8.2 MB/s -* `xss()` function from module `validator@0.3.7`: 4.4 MB/s - -For test code please refer to `benchmark` directory. - -## They are using xss module - -* **nodeclub** - A Node.js bbs using MongoDB - https://github.com/cnodejs/nodeclub -* **cnpmjs.org** - Private npm registry and web for Enterprise - https://github.com/cnpm/cnpmjs.org - -## Install - -### NPM - -```bash -npm install xss -``` - -### Bower - -```bash -bower install xss -``` - -Or - -```bash -bower install https://github.com/leizongmin/js-xss.git -``` - -## Usages - -### On Node.js - -```javascript -var xss = require("xss"); -var html = xss(''); -console.log(html); -``` - -### On Browser - -Shim mode (reference file `test/test.html`): - -```html - - -``` - -AMD mode - shim: - -```html - -``` - -**Notes: please don't use the URL https://rawgit.com/leizongmin/js-xss/master/dist/xss.js in production environment.** - -## Command Line Tool - -### Process File - -You can use the xss command line tool to process a file. Usage: - -```bash -xss -i -o -``` - -Example: - -```bash -xss -i origin.html -o target.html -``` - -### Active Test - -Run the following command, them you can type HTML -code in the command-line, and check the filtered output: - -```bash -xss -t -``` - -For more details, please run `$ xss -h` to see it. - -## Custom filter rules - -When using the `xss()` function, the second parameter could be used to specify -custom rules: - -```javascript -options = {}; // Custom rules -html = xss('', options); -``` - -To avoid passing `options` every time, you can also do it in a faster way by -creating a `FilterXSS` instance: - -```javascript -options = {}; // Custom rules -myxss = new xss.FilterXSS(options); -// then apply myxss.process() -html = myxss.process(''); -``` - -Details of parameters in `options` would be described below. - -### Whitelist - -By specifying a `whiteList`, e.g. `{ 'tagName': [ 'attr-1', 'attr-2' ] }`. Tags -and attributes not in the whitelist would be filter out. For example: - -```javascript -// only tag a and its attributes href, title, target are allowed -var options = { - whiteList: { - a: ["href", "title", "target"] - } -}; -// With the configuration specified above, the following HTML: -// Hello -// would become: -// Hello -``` - -For the default whitelist, please refer `xss.whiteList`. - -### Customize the handler function for matched tags - -By specifying the handler function with `onTag`: - -```javascript -function onTag(tag, html, options) { - // tag is the name of current tag, e.g. 'a' for tag - // html is the HTML of this tag, e.g. '' for tag - // options is some addition informations: - // isWhite boolean, whether the tag is in whitelist - // isClosing boolean, whether the tag is a closing tag, e.g. true for - // position integer, the position of the tag in output result - // sourcePosition integer, the position of the tag in input HTML source - // If a string is returned, the current tag would be replaced with the string - // If return nothing, the default measure would be taken: - // If in whitelist: filter attributes using onTagAttr, as described below - // If not in whitelist: handle by onIgnoreTag, as described below -} -``` - -### Customize the handler function for attributes of matched tags - -By specifying the handler function with `onTagAttr`: - -```javascript -function onTagAttr(tag, name, value, isWhiteAttr) { - // tag is the name of current tag, e.g. 'a' for tag - // name is the name of current attribute, e.g. 'href' for href="#" - // isWhiteAttr whether the attribute is in whitelist - // If a string is returned, the attribute would be replaced with the string - // If return nothing, the default measure would be taken: - // If in whitelist: filter the value using safeAttrValue as described below - // If not in whitelist: handle by onIgnoreTagAttr, as described below -} -``` - -### Customize the handler function for tags not in the whitelist - -By specifying the handler function with `onIgnoreTag`: - -```javascript -function onIgnoreTag(tag, html, options) { - // Parameters are the same with onTag - // If a string is returned, the tag would be replaced with the string - // If return nothing, the default measure would be taken (specifies using - // escape, as described below) -} -``` - -### Customize the handler function for attributes not in the whitelist - -By specifying the handler function with `onIgnoreTagAttr`: - -```javascript -function onIgnoreTagAttr(tag, name, value, isWhiteAttr) { - // Parameters are the same with onTagAttr - // If a string is returned, the value would be replaced with this string - // If return nothing, then keep default (remove the attribute) -} -``` - -### Customize escaping function for HTML - -By specifying the handler function with `escapeHtml`. Following is the default -function **(Modification is not recommended)**: - -```javascript -function escapeHtml(html) { - return html.replace(//g, ">"); -} -``` - -### Customize escaping function for value of attributes - -By specifying the handler function with `safeAttrValue`: - -```javascript -function safeAttrValue(tag, name, value) { - // Parameters are the same with onTagAttr (without options) - // Return the value as a string -} -``` - -### Customize CSS filter - -If 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: - -```javascript -myxss = new xss.FilterXSS({ - css: { - whiteList: { - position: /^fixed|relative$/, - top: true, - left: true - } - } -}); -html = myxss.process(''); -``` - -If you don't want to filter out the `style` content, just specify `false` to the `css` option: - -```javascript -myxss = new xss.FilterXSS({ - css: false -}); -``` - -For more help, please see https://github.com/leizongmin/js-css-filter - -### Quick Start - -#### Filter out tags not in the whitelist - -By using `stripIgnoreTag` parameter: - -* `true` filter out tags not in the whitelist -* `false`: by default: escape the tag using configured `escape` function - -Example: - -If `stripIgnoreTag = true` is set, the following code: - -```html -code: -``` - -would output filtered: - -```html -code:alert(/xss/); -``` - -#### Filter out tags and tag bodies not in the whitelist - -By using `stripIgnoreTagBody` parameter: - -* `false|null|undefined` by default: do nothing -* `'*'|true`: filter out all tags not in the whitelist -* `['tag1', 'tag2']`: filter out only specified tags not in the whitelist - -Example: - -If `stripIgnoreTagBody = ['script']` is set, the following code: - -```html -code: -``` - -would output filtered: - -```html -code: -``` - -#### Filter out HTML comments - -By using `allowCommentTag` parameter: - -* `true`: do nothing -* `false` by default: filter out HTML comments - -Example: - -If `allowCommentTag = false` is set, the following code: - -```html -code: END -``` - -would output filtered: - -```html -code: END -``` - -## Examples - -### Allow attributes of whitelist tags start with `data-` - -```javascript -var source = '
hello
'; -var html = xss(source, { - onIgnoreTagAttr: function(tag, name, value, isWhiteAttr) { - if (name.substr(0, 5) === "data-") { - // escape its value using built-in escapeAttrValue function - return name + '="' + xss.escapeAttrValue(value) + '"'; - } - } -}); - -console.log("%s\nconvert to:\n%s", source, html); -``` - -Result: - -```html -
hello
-convert to: -
hello
-``` - -### Allow tags start with `x-` - -```javascript -var source = "hewwww
"; -var html = xss(source, { - onIgnoreTag: function(tag, html, options) { - if (tag.substr(0, 2) === "x-") { - // do not filter its attributes - return html; - } - } -}); - -console.log("%s\nconvert to:\n%s", source, html); -``` - -Result: - -```html -hewwww -convert to: -<x>hewwww -``` - -### Parse images in HTML - -```javascript -var source = - 'abcd'; -var list = []; -var html = xss(source, { - onTagAttr: function(tag, name, value, isWhiteAttr) { - if (tag === "img" && name === "src") { - // Use the built-in friendlyAttrValue function to escape attribute - // values. It supports converting entity tags such as < to printable - // characters such as < - list.push(xss.friendlyAttrValue(value)); - } - // Return nothing, means keep the default handling measure - } -}); - -console.log("image list:\n%s", list.join(", ")); -``` - -Result: - -```html -image list: -img1, img2, img3, img4 -``` - -### Filter out HTML tags (keeps only plain text) - -```javascript -var source = "helloend"; -var html = xss(source, { - whiteList: [], // empty, means filter out all tags - stripIgnoreTag: true, // filter out all HTML not in the whilelist - stripIgnoreTagBody: ["script"] // the script tag is a special case, we need - // to filter out its content -}); - -console.log("text: %s", html); -``` - -Result: - -```html -text: helloend -``` - -## License - -```text -Copyright (c) 2012-2018 Zongmin Lei(雷宗民) -http://ucdok.com - -The MIT License - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -``` diff --git a/node_modules/xss/README.zh.md b/node_modules/xss/README.zh.md deleted file mode 100644 index 2483d4d..0000000 --- a/node_modules/xss/README.zh.md +++ /dev/null @@ -1,485 +0,0 @@ -[![NPM version][npm-image]][npm-url] -[![build status][travis-image]][travis-url] -[![Test coverage][coveralls-image]][coveralls-url] -[![David deps][david-image]][david-url] -[![node version][node-image]][node-url] -[![npm download][download-image]][download-url] -[![npm license][license-image]][download-url] - -[npm-image]: https://img.shields.io/npm/v/xss.svg?style=flat-square -[npm-url]: https://npmjs.org/package/xss -[travis-image]: https://img.shields.io/travis/leizongmin/js-xss.svg?style=flat-square -[travis-url]: https://travis-ci.org/leizongmin/js-xss -[coveralls-image]: https://img.shields.io/coveralls/leizongmin/js-xss.svg?style=flat-square -[coveralls-url]: https://coveralls.io/r/leizongmin/js-xss?branch=master -[david-image]: https://img.shields.io/david/leizongmin/js-xss.svg?style=flat-square -[david-url]: https://david-dm.org/leizongmin/js-xss -[node-image]: https://img.shields.io/badge/node.js-%3E=_0.10-green.svg?style=flat-square -[node-url]: http://nodejs.org/download/ -[download-image]: https://img.shields.io/npm/dm/xss.svg?style=flat-square -[download-url]: https://npmjs.org/package/xss -[license-image]: https://img.shields.io/npm/l/xss.svg - -# 根据白名单过滤 HTML(防止 XSS 攻击) - -![xss](https://nodei.co/npm/xss.png?downloads=true&stars=true) - ---- - -`xss`是一个用于对用户输入的内容进行过滤,以避免遭受 XSS 攻击的模块([什么是 XSS 攻击?](http://baike.baidu.com/view/2161269.htm))。主要用于论坛、博客、网上商店等等一些可允许用户录入页面排版、格式控制相关的 HTML 的场景,`xss`模块通过白名单来控制允许的标签及相关的标签属性,另外还提供了一系列的接口以便用户扩展,比其他同类模块更为灵活。 - -**项目主页:** http://jsxss.com - -**在线测试:** http://jsxss.com/zh/try.html - ---- - -## 特性 - -* 白名单控制允许的 HTML 标签及各标签的属性 -* 通过自定义处理函数,可对任意标签及其属性进行处理 - -## 参考资料 - -* [XSS 与字符编码的那些事儿 ---科普文](http://drops.wooyun.org/tips/689) -* [腾讯实例教程:那些年我们一起学 XSS](http://www.wooyun.org/whitehats/%E5%BF%83%E4%BC%A4%E7%9A%84%E7%98%A6%E5%AD%90) -* [mXSS 攻击的成因及常见种类](http://drops.wooyun.org/tips/956) -* [XSS Filter Evasion Cheat Sheet](https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet) -* [Data URI scheme](http://en.wikipedia.org/wiki/Data_URI_scheme) -* [XSS with Data URI Scheme](http://hi.baidu.com/badzzzz/item/bdbafe83144619c199255f7b) - -## 性能(仅作参考) - -* xss 模块:8.2 MB/s -* validator@0.3.7 模块的 xss()函数:4.4 MB/s - -测试代码参考 benchmark 目录 - -## 安装 - -### NPM - -```bash -npm install xss -``` - -### Bower - -```bash -bower install xss -``` - -或者 - -```bash -bower install https://github.com/leizongmin/js-xss.git -``` - -## 使用方法 - -### 在 Node.js 中使用 - -```javascript -var xss = require("xss"); -var html = xss(''); -console.log(html); -``` - -### 在浏览器端使用 - -Shim 模式(参考文件 `test/test.html`): - -```html - - -``` - -AMD 模式(参考文件 `test/test_amd.html`): - -```html - -``` - -**说明:请勿将 URL https://rawgit.com/leizongmin/js-xss/master/dist/xss.js 用于生产环境。** - -### 使用命令行工具来对文件进行 XSS 处理 - -### 处理文件 - -可通过内置的 `xss` 命令来对输入的文件进行 XSS 处理。使用方法: - -```bash -xss -i <源文件> -o <目标文件> -``` - -例: - -```bash -xss -i origin.html -o target.html -``` - -### 在线测试 - -执行以下命令,可在命令行中输入 HTML 代码,并看到过滤后的代码: - -```bash -xss -t -``` - -详细命令行参数说明,请输入 `$ xss -h` 来查看。 - -## 自定义过滤规则 - -在调用 `xss()` 函数进行过滤时,可通过第二个参数来设置自定义规则: - -```javascript -options = {}; // 自定义规则 -html = xss('', options); -``` - -如果不想每次都传入一个 `options` 参数,可以创建一个 `FilterXSS` 实例(使用这种方法速度更快): - -``` -options = {}; // 自定义规则 -myxss = new xss.FilterXSS(options); -// 以后直接调用 myxss.process() 来处理即可 -html = myxss.process(''); -``` - -`options` 参数的详细说明见下文。 - -### 白名单 - -通过 `whiteList` 来指定,格式为:`{'标签名': ['属性1', '属性2']}`。不在白名单上的标签将被过滤,不在白名单上的属性也会被过滤。以下是示例: - -```javascript -// 只允许a标签,该标签只允许href, title, target这三个属性 -var options = { - whiteList: { - a: ["href", "title", "target"] - } -}; -// 使用以上配置后,下面的HTML -// 大家好 -// 将被过滤为 -// 大家好 -``` - -默认白名单参考 `xss.whiteList`。 - -### 自定义匹配到标签时的处理方法 - -通过 `onTag` 来指定相应的处理函数。以下是详细说明: - -```javascript -function onTag(tag, html, options) { - // tag是当前的标签名称,比如标签,则tag的值是'a' - // html是该标签的HTML,比如标签,则html的值是'' - // options是一些附加的信息,具体如下: - // isWhite boolean类型,表示该标签是否在白名单上 - // isClosing boolean类型,表示该标签是否为闭合标签,比如时为true - // position integer类型,表示当前标签在输出的结果中的起始位置 - // sourcePosition integer类型,表示当前标签在原HTML中的起始位置 - // 如果返回一个字符串,则当前标签将被替换为该字符串 - // 如果不返回任何值,则使用默认的处理方法: - // 在白名单上: 通过onTagAttr来过滤属性,详见下文 - // 不在白名单上:通过onIgnoreTag指定,详见下文 -} -``` - -### 自定义匹配到标签的属性时的处理方法 - -通过 `onTagAttr` 来指定相应的处理函数。以下是详细说明: - -```javascript -function onTagAttr(tag, name, value, isWhiteAttr) { - // tag是当前的标签名称,比如标签,则tag的值是'a' - // name是当前属性的名称,比如href="#",则name的值是'href' - // value是当前属性的值,比如href="#",则value的值是'#' - // isWhiteAttr是否为白名单上的属性 - // 如果返回一个字符串,则当前属性值将被替换为该字符串 - // 如果不返回任何值,则使用默认的处理方法 - // 在白名单上: 调用safeAttrValue来过滤属性值,并输出该属性,详见下文 - // 不在白名单上:通过onIgnoreTagAttr指定,详见下文 -} -``` - -### 自定义匹配到不在白名单上的标签时的处理方法 - -通过 `onIgnoreTag` 来指定相应的处理函数。以下是详细说明: - -```javascript -function onIgnoreTag(tag, html, options) { - // 参数说明与onTag相同 - // 如果返回一个字符串,则当前标签将被替换为该字符串 - // 如果不返回任何值,则使用默认的处理方法(通过escape指定,详见下文) -} -``` - -### 自定义匹配到不在白名单上的属性时的处理方法 - -通过 `onIgnoreTagAttr` 来指定相应的处理函数。以下是详细说明: - -```javascript -function onIgnoreTagAttr(tag, name, value, isWhiteAttr) { - // 参数说明与onTagAttr相同 - // 如果返回一个字符串,则当前属性值将被替换为该字符串 - // 如果不返回任何值,则使用默认的处理方法(删除该属) -} -``` - -### 自定义 HTML 转义函数 - -通过 `escapeHtml` 来指定相应的处理函数。以下是默认代码 **(不建议修改)** : - -```javascript -function escapeHtml(html) { - return html.replace(//g, ">"); -} -``` - -### 自定义标签属性值的转义函数 - -通过 `safeAttrValue` 来指定相应的处理函数。以下是详细说明: - -```javascript -function safeAttrValue(tag, name, value) { - // 参数说明与onTagAttr相同(没有options参数) - // 返回一个字符串表示该属性值 -} -``` - -### 自定义 CSS 过滤器 - -如果配置中允许了标签的 `style` 属性,则它的值会通过[cssfilter](https://github.com/leizongmin/js-css-filter) 模块处理。 -`cssfilter` 模块包含了一个默认的 CSS 白名单,你可以通过以下的方式配置: - -```javascript -myxss = new xss.FilterXSS({ - css: { - whiteList: { - position: /^fixed|relative$/, - top: true, - left: true - } - } -}); -html = myxss.process(''); -``` - -如果不想使用 CSS 过滤器来处理 `style` 属性的内容,可指定 `css` 选项的值为 `false`: - -```javascript -myxss = new xss.FilterXSS({ - css: false -}); -``` - -要获取更多的帮助信息可看这里:https://github.com/leizongmin/js-css-filter - -### 快捷配置 - -#### 去掉不在白名单上的标签 - -通过 `stripIgnoreTag` 来设置: - -* `true`:去掉不在白名单上的标签 -* `false`:(默认),使用配置的`escape`函数对该标签进行转义 - -示例: - -当设置 `stripIgnoreTag = true`时,以下代码 - -```html -code: -``` - -过滤后将输出 - -```html -code:alert(/xss/); -``` - -#### 去掉不在白名单上的标签及标签体 - -通过 `stripIgnoreTagBody` 来设置: - -* `false|null|undefined`:(默认),不特殊处理 -* `'*'|true`:去掉所有不在白名单上的标签 -* `['tag1', 'tag2']`:仅去掉指定的不在白名单上的标签 - -示例: - -当设置 `stripIgnoreTagBody = ['script']`时,以下代码 - -```html -code: -``` - -过滤后将输出 - -```html -code: -``` - -#### 去掉 HTML 备注 - -通过 `allowCommentTag` 来设置: - -* `true`:不处理 -* `false`:(默认),自动去掉 HTML 中的备注 - -示例: - -当设置 `allowCommentTag = false` 时,以下代码 - -```html -code: END -``` - -过滤后将输出 - -```html -code: END -``` - -## 应用实例 - -### 允许标签以 data-开头的属性 - -```javascript -var source = '
hello
'; -var html = xss(source, { - onIgnoreTagAttr: function(tag, name, value, isWhiteAttr) { - if (name.substr(0, 5) === "data-") { - // 通过内置的escapeAttrValue函数来对属性值进行转义 - return name + '="' + xss.escapeAttrValue(value) + '"'; - } - } -}); - -console.log("%s\nconvert to:\n%s", source, html); -``` - -运行结果: - -```html -
hello
-convert to: -
hello
-``` - -### 允许名称以 x-开头的标签 - -```javascript -var source = "hewwww
"; -var html = xss(source, { - onIgnoreTag: function(tag, html, options) { - if (tag.substr(0, 2) === "x-") { - // 不对其属性列表进行过滤 - return html; - } - } -}); - -console.log("%s\nconvert to:\n%s", source, html); -``` - -运行结果: - -```html -hewwww -convert to: -<x>hewwww -``` - -### 分析 HTML 代码中的图片列表 - -```javascript -var source = - 'abcd'; -var list = []; -var html = xss(source, { - onTagAttr: function(tag, name, value, isWhiteAttr) { - if (tag === "img" && name === "src") { - // 使用内置的friendlyAttrValue函数来对属性值进行转义,可将<这类的实体标记转换成打印字符< - list.push(xss.friendlyAttrValue(value)); - } - // 不返回任何值,表示还是按照默认的方法处理 - } -}); - -console.log("image list:\n%s", list.join(", ")); -``` - -运行结果: - -```html -image list: -img1, img2, img3, img4 -``` - -### 去除 HTML 标签(只保留文本内容) - -```javascript -var source = "helloend"; -var html = xss(source, { - whiteList: [], // 白名单为空,表示过滤所有标签 - stripIgnoreTag: true, // 过滤所有非白名单标签的HTML - stripIgnoreTagBody: ["script"] // script标签较特殊,需要过滤标签中间的内容 -}); - -console.log("text: %s", html); -``` - -运行结果: - -```html -text: helloend -``` - -## 授权协议 - -```text -Copyright (c) 2012-2018 Zongmin Lei(雷宗民) -http://ucdok.com - -The MIT License - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -``` diff --git a/node_modules/xss/bin/xss b/node_modules/xss/bin/xss deleted file mode 100755 index 35e902f..0000000 --- a/node_modules/xss/bin/xss +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env node - -/** - * 命令行工具 - * - * @author Zongmin Lei - */ - -var fs = require('fs'); -var path = require('path'); -var program = require('commander'); -var xss = require('../'); -var packageInfo = require('../package.json'); - -program - .version(packageInfo.version) - .option('-t, --test', 'active test') - .option('-i, --input ', 'input file name') - .option('-o, --output ', 'output filename') - .option('-c, --config ', 'load custom config') - .option('-s, --strip-ignore-tag', 'set stripIgnoreTag=true') - .option('-b, --strip-ignore-tag-body', 'set stripIgnoreTagBody=true'); - -program.on('--help', function () { - console.log(' Examples:'); - console.log(''); - console.log(' $ xss -t'); - console.log(' $ xss -i origin.html'); - console.log(' $ xss -i origin.html -o targer.html'); - console.log(' $ xss -i origin.html -c config.js'); - console.log(' $ xss -i origin.html -s'); - console.log(' $ xss -i origin.html -s -b'); - console.log(''); - console.log(' For more details, please see: https://npmjs.org/package/xss') -}); - -program.parse(process.argv); - -if (program.test) { - require('../lib/cli'); - return; -} - -var config = {}; -if (program.config) { - config = require(path.resolve(program.config)); -} -if (program.input) { - var input = fs.readFileSync(program.input, 'utf8'); -} else { - program.help(); -} - -if (program['strip-ignore-tag']) { - config.stripIgnoreTag = true; -} -if (program['strip-ignore-tag-body']) { - config.stripIgnoreTagBody = true; -} - -var output = xss(input, config); - -if (program.output) { - fs.writeFileSync(program.output, output); -} else { - console.log(output); -} diff --git a/node_modules/xss/dist/test.html b/node_modules/xss/dist/test.html deleted file mode 100644 index cae361e..0000000 --- a/node_modules/xss/dist/test.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - 测试 - - - -

-
-
-
-
\ No newline at end of file
diff --git a/node_modules/xss/dist/xss.js b/node_modules/xss/dist/xss.js
deleted file mode 100644
index 9583a6b..0000000
--- a/node_modules/xss/dist/xss.js
+++ /dev/null
@@ -1,1609 +0,0 @@
-(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o
- */
-
-var FilterCSS = require("cssfilter").FilterCSS;
-var getDefaultCSSWhiteList = require("cssfilter").getDefaultWhiteList;
-var _ = require("./util");
-
-function getDefaultWhiteList() {
-  return {
-    a: ["target", "href", "title"],
-    abbr: ["title"],
-    address: [],
-    area: ["shape", "coords", "href", "alt"],
-    article: [],
-    aside: [],
-    audio: ["autoplay", "controls", "loop", "preload", "src"],
-    b: [],
-    bdi: ["dir"],
-    bdo: ["dir"],
-    big: [],
-    blockquote: ["cite"],
-    br: [],
-    caption: [],
-    center: [],
-    cite: [],
-    code: [],
-    col: ["align", "valign", "span", "width"],
-    colgroup: ["align", "valign", "span", "width"],
-    dd: [],
-    del: ["datetime"],
-    details: ["open"],
-    div: [],
-    dl: [],
-    dt: [],
-    em: [],
-    font: ["color", "size", "face"],
-    footer: [],
-    h1: [],
-    h2: [],
-    h3: [],
-    h4: [],
-    h5: [],
-    h6: [],
-    header: [],
-    hr: [],
-    i: [],
-    img: ["src", "alt", "title", "width", "height"],
-    ins: ["datetime"],
-    li: [],
-    mark: [],
-    nav: [],
-    ol: [],
-    p: [],
-    pre: [],
-    s: [],
-    section: [],
-    small: [],
-    span: [],
-    sub: [],
-    sup: [],
-    strong: [],
-    table: ["width", "border", "align", "valign"],
-    tbody: ["align", "valign"],
-    td: ["width", "rowspan", "colspan", "align", "valign"],
-    tfoot: ["align", "valign"],
-    th: ["width", "rowspan", "colspan", "align", "valign"],
-    thead: ["align", "valign"],
-    tr: ["rowspan", "align", "valign"],
-    tt: [],
-    u: [],
-    ul: [],
-    video: ["autoplay", "controls", "loop", "preload", "src", "height", "width"]
-  };
-}
-
-var defaultCSSFilter = new FilterCSS();
-
-/**
- * default onTag function
- *
- * @param {String} tag
- * @param {String} html
- * @param {Object} options
- * @return {String}
- */
-function onTag(tag, html, options) {
-  // do nothing
-}
-
-/**
- * default onIgnoreTag function
- *
- * @param {String} tag
- * @param {String} html
- * @param {Object} options
- * @return {String}
- */
-function onIgnoreTag(tag, html, options) {
-  // do nothing
-}
-
-/**
- * default onTagAttr function
- *
- * @param {String} tag
- * @param {String} name
- * @param {String} value
- * @return {String}
- */
-function onTagAttr(tag, name, value) {
-  // do nothing
-}
-
-/**
- * default onIgnoreTagAttr function
- *
- * @param {String} tag
- * @param {String} name
- * @param {String} value
- * @return {String}
- */
-function onIgnoreTagAttr(tag, name, value) {
-  // do nothing
-}
-
-/**
- * default escapeHtml function
- *
- * @param {String} html
- */
-function escapeHtml(html) {
-  return html.replace(REGEXP_LT, "<").replace(REGEXP_GT, ">");
-}
-
-/**
- * default safeAttrValue function
- *
- * @param {String} tag
- * @param {String} name
- * @param {String} value
- * @param {Object} cssFilter
- * @return {String}
- */
-function safeAttrValue(tag, name, value, cssFilter) {
-  // unescape attribute value firstly
-  value = friendlyAttrValue(value);
-
-  if (name === "href" || name === "src") {
-    // filter `href` and `src` attribute
-    // only allow the value that starts with `http://` | `https://` | `mailto:` | `/` | `#`
-    value = _.trim(value);
-    if (value === "#") return "#";
-    if (
-      !(
-        value.substr(0, 7) === "http://" ||
-        value.substr(0, 8) === "https://" ||
-        value.substr(0, 7) === "mailto:" ||
-        value.substr(0, 4) === "tel:" ||
-        value[0] === "#" ||
-        value[0] === "/"
-      )
-    ) {
-      return "";
-    }
-  } else if (name === "background") {
-    // filter `background` attribute (maybe no use)
-    // `javascript:`
-    REGEXP_DEFAULT_ON_TAG_ATTR_4.lastIndex = 0;
-    if (REGEXP_DEFAULT_ON_TAG_ATTR_4.test(value)) {
-      return "";
-    }
-  } else if (name === "style") {
-    // `expression()`
-    REGEXP_DEFAULT_ON_TAG_ATTR_7.lastIndex = 0;
-    if (REGEXP_DEFAULT_ON_TAG_ATTR_7.test(value)) {
-      return "";
-    }
-    // `url()`
-    REGEXP_DEFAULT_ON_TAG_ATTR_8.lastIndex = 0;
-    if (REGEXP_DEFAULT_ON_TAG_ATTR_8.test(value)) {
-      REGEXP_DEFAULT_ON_TAG_ATTR_4.lastIndex = 0;
-      if (REGEXP_DEFAULT_ON_TAG_ATTR_4.test(value)) {
-        return "";
-      }
-    }
-    if (cssFilter !== false) {
-      cssFilter = cssFilter || defaultCSSFilter;
-      value = cssFilter.process(value);
-    }
-  }
-
-  // escape `<>"` before returns
-  value = escapeAttrValue(value);
-  return value;
-}
-
-// RegExp list
-var REGEXP_LT = //g;
-var REGEXP_QUOTE = /"/g;
-var REGEXP_QUOTE_2 = /"/g;
-var REGEXP_ATTR_VALUE_1 = /&#([a-zA-Z0-9]*);?/gim;
-var REGEXP_ATTR_VALUE_COLON = /:?/gim;
-var REGEXP_ATTR_VALUE_NEWLINE = /&newline;?/gim;
-var REGEXP_DEFAULT_ON_TAG_ATTR_3 = /\/\*|\*\//gm;
-var REGEXP_DEFAULT_ON_TAG_ATTR_4 = /((j\s*a\s*v\s*a|v\s*b|l\s*i\s*v\s*e)\s*s\s*c\s*r\s*i\s*p\s*t\s*|m\s*o\s*c\s*h\s*a)\:/gi;
-var REGEXP_DEFAULT_ON_TAG_ATTR_5 = /^[\s"'`]*(d\s*a\s*t\s*a\s*)\:/gi;
-var REGEXP_DEFAULT_ON_TAG_ATTR_6 = /^[\s"'`]*(d\s*a\s*t\s*a\s*)\:\s*image\//gi;
-var REGEXP_DEFAULT_ON_TAG_ATTR_7 = /e\s*x\s*p\s*r\s*e\s*s\s*s\s*i\s*o\s*n\s*\(.*/gi;
-var REGEXP_DEFAULT_ON_TAG_ATTR_8 = /u\s*r\s*l\s*\(.*/gi;
-
-/**
- * escape doube quote
- *
- * @param {String} str
- * @return {String} str
- */
-function escapeQuote(str) {
-  return str.replace(REGEXP_QUOTE, """);
-}
-
-/**
- * unescape double quote
- *
- * @param {String} str
- * @return {String} str
- */
-function unescapeQuote(str) {
-  return str.replace(REGEXP_QUOTE_2, '"');
-}
-
-/**
- * escape html entities
- *
- * @param {String} str
- * @return {String}
- */
-function escapeHtmlEntities(str) {
-  return str.replace(REGEXP_ATTR_VALUE_1, function replaceUnicode(str, code) {
-    return code[0] === "x" || code[0] === "X"
-      ? String.fromCharCode(parseInt(code.substr(1), 16))
-      : String.fromCharCode(parseInt(code, 10));
-  });
-}
-
-/**
- * escape html5 new danger entities
- *
- * @param {String} str
- * @return {String}
- */
-function escapeDangerHtml5Entities(str) {
-  return str
-    .replace(REGEXP_ATTR_VALUE_COLON, ":")
-    .replace(REGEXP_ATTR_VALUE_NEWLINE, " ");
-}
-
-/**
- * clear nonprintable characters
- *
- * @param {String} str
- * @return {String}
- */
-function clearNonPrintableCharacter(str) {
-  var str2 = "";
-  for (var i = 0, len = str.length; i < len; i++) {
-    str2 += str.charCodeAt(i) < 32 ? " " : str.charAt(i);
-  }
-  return _.trim(str2);
-}
-
-/**
- * get friendly attribute value
- *
- * @param {String} str
- * @return {String}
- */
-function friendlyAttrValue(str) {
-  str = unescapeQuote(str);
-  str = escapeHtmlEntities(str);
-  str = escapeDangerHtml5Entities(str);
-  str = clearNonPrintableCharacter(str);
-  return str;
-}
-
-/**
- * unescape attribute value
- *
- * @param {String} str
- * @return {String}
- */
-function escapeAttrValue(str) {
-  str = escapeQuote(str);
-  str = escapeHtml(str);
-  return str;
-}
-
-/**
- * `onIgnoreTag` function for removing all the tags that are not in whitelist
- */
-function onIgnoreTagStripAll() {
-  return "";
-}
-
-/**
- * remove tag body
- * specify a `tags` list, if the tag is not in the `tags` list then process by the specify function (optional)
- *
- * @param {array} tags
- * @param {function} next
- */
-function StripTagBody(tags, next) {
-  if (typeof next !== "function") {
-    next = function() {};
-  }
-
-  var isRemoveAllTag = !Array.isArray(tags);
-  function isRemoveTag(tag) {
-    if (isRemoveAllTag) return true;
-    return _.indexOf(tags, tag) !== -1;
-  }
-
-  var removeList = [];
-  var posStart = false;
-
-  return {
-    onIgnoreTag: function(tag, html, options) {
-      if (isRemoveTag(tag)) {
-        if (options.isClosing) {
-          var ret = "[/removed]";
-          var end = options.position + ret.length;
-          removeList.push([
-            posStart !== false ? posStart : options.position,
-            end
-          ]);
-          posStart = false;
-          return ret;
-        } else {
-          if (!posStart) {
-            posStart = options.position;
-          }
-          return "[removed]";
-        }
-      } else {
-        return next(tag, html, options);
-      }
-    },
-    remove: function(html) {
-      var rethtml = "";
-      var lastPos = 0;
-      _.forEach(removeList, function(pos) {
-        rethtml += html.slice(lastPos, pos[0]);
-        lastPos = pos[1];
-      });
-      rethtml += html.slice(lastPos);
-      return rethtml;
-    }
-  };
-}
-
-/**
- * remove html comments
- *
- * @param {String} html
- * @return {String}
- */
-function stripCommentTag(html) {
-  return html.replace(STRIP_COMMENT_TAG_REGEXP, "");
-}
-var STRIP_COMMENT_TAG_REGEXP = //g;
-
-/**
- * remove invisible characters
- *
- * @param {String} html
- * @return {String}
- */
-function stripBlankChar(html) {
-  var chars = html.split("");
-  chars = chars.filter(function(char) {
-    var c = char.charCodeAt(0);
-    if (c === 127) return false;
-    if (c <= 31) {
-      if (c === 10 || c === 13) return true;
-      return false;
-    }
-    return true;
-  });
-  return chars.join("");
-}
-
-exports.whiteList = getDefaultWhiteList();
-exports.getDefaultWhiteList = getDefaultWhiteList;
-exports.onTag = onTag;
-exports.onIgnoreTag = onIgnoreTag;
-exports.onTagAttr = onTagAttr;
-exports.onIgnoreTagAttr = onIgnoreTagAttr;
-exports.safeAttrValue = safeAttrValue;
-exports.escapeHtml = escapeHtml;
-exports.escapeQuote = escapeQuote;
-exports.unescapeQuote = unescapeQuote;
-exports.escapeHtmlEntities = escapeHtmlEntities;
-exports.escapeDangerHtml5Entities = escapeDangerHtml5Entities;
-exports.clearNonPrintableCharacter = clearNonPrintableCharacter;
-exports.friendlyAttrValue = friendlyAttrValue;
-exports.escapeAttrValue = escapeAttrValue;
-exports.onIgnoreTagStripAll = onIgnoreTagStripAll;
-exports.StripTagBody = StripTagBody;
-exports.stripCommentTag = stripCommentTag;
-exports.stripBlankChar = stripBlankChar;
-exports.cssFilter = defaultCSSFilter;
-exports.getDefaultCSSWhiteList = getDefaultCSSWhiteList;
-
-},{"./util":4,"cssfilter":8}],2:[function(require,module,exports){
-/**
- * xss
- *
- * @author Zongmin Lei
- */
-
-var DEFAULT = require("./default");
-var parser = require("./parser");
-var FilterXSS = require("./xss");
-
-/**
- * filter xss function
- *
- * @param {String} html
- * @param {Object} options { whiteList, onTag, onTagAttr, onIgnoreTag, onIgnoreTagAttr, safeAttrValue, escapeHtml }
- * @return {String}
- */
-function filterXSS(html, options) {
-  var xss = new FilterXSS(options);
-  return xss.process(html);
-}
-
-exports = module.exports = filterXSS;
-exports.filterXSS = filterXSS;
-exports.FilterXSS = FilterXSS;
-for (var i in DEFAULT) exports[i] = DEFAULT[i];
-for (var i in parser) exports[i] = parser[i];
-
-// using `xss` on the browser, output `filterXSS` to the globals
-if (typeof window !== "undefined") {
-  window.filterXSS = module.exports;
-}
-
-// using `xss` on the WebWorker, output `filterXSS` to the globals
-function isWorkerEnv() {
-  return typeof self !== 'undefined' && typeof DedicatedWorkerGlobalScope !== 'undefined' && self instanceof DedicatedWorkerGlobalScope;
-}
-if (isWorkerEnv()) {
-  self.filterXSS = module.exports;
-}
-
-},{"./default":1,"./parser":3,"./xss":5}],3:[function(require,module,exports){
-/**
- * Simple HTML Parser
- *
- * @author Zongmin Lei
- */
-
-var _ = require("./util");
-
-/**
- * get tag name
- *
- * @param {String} html e.g. '
' - * @return {String} - */ -function getTagName(html) { - var i = _.spaceIndex(html); - if (i === -1) { - var tagName = html.slice(1, -1); - } else { - var tagName = html.slice(1, i + 1); - } - tagName = _.trim(tagName).toLowerCase(); - if (tagName.slice(0, 1) === "/") tagName = tagName.slice(1); - if (tagName.slice(-1) === "/") tagName = tagName.slice(0, -1); - return tagName; -} - -/** - * is close tag? - * - * @param {String} html 如:'' - * @return {Boolean} - */ -function isClosing(html) { - return html.slice(0, 2) === "") { - rethtml += escapeHtml(html.slice(lastPos, tagStart)); - currentHtml = html.slice(tagStart, currentPos + 1); - currentTagName = getTagName(currentHtml); - rethtml += onTag( - tagStart, - rethtml.length, - currentTagName, - currentHtml, - isClosing(currentHtml) - ); - lastPos = currentPos + 1; - tagStart = false; - continue; - } - if ((c === '"' || c === "'") && html.charAt(currentPos - 1) === "=") { - quoteStart = c; - continue; - } - } else { - if (c === quoteStart) { - quoteStart = false; - continue; - } - } - } - } - if (lastPos < html.length) { - rethtml += escapeHtml(html.substr(lastPos)); - } - - return rethtml; -} - -var REGEXP_ILLEGAL_ATTR_NAME = /[^a-zA-Z0-9_:\.\-]/gim; - -/** - * parse input attributes and returns processed attributes - * - * @param {String} html e.g. `href="#" target="_blank"` - * @param {Function} onAttr e.g. `function (name, value)` - * @return {String} - */ -function parseAttr(html, onAttr) { - "user strict"; - - var lastPos = 0; - var retAttrs = []; - var tmpName = false; - var len = html.length; - - function addAttr(name, value) { - name = _.trim(name); - name = name.replace(REGEXP_ILLEGAL_ATTR_NAME, "").toLowerCase(); - if (name.length < 1) return; - var ret = onAttr(name, value || ""); - if (ret) retAttrs.push(ret); - } - - // 逐个分析字符 - for (var i = 0; i < len; i++) { - var c = html.charAt(i); - var v, j; - if (tmpName === false && c === "=") { - tmpName = html.slice(lastPos, i); - lastPos = i + 1; - continue; - } - if (tmpName !== false) { - if ( - i === lastPos && - (c === '"' || c === "'") && - html.charAt(i - 1) === "=" - ) { - j = html.indexOf(c, i + 1); - if (j === -1) { - break; - } else { - v = _.trim(html.slice(lastPos + 1, j)); - addAttr(tmpName, v); - tmpName = false; - i = j; - lastPos = i + 1; - continue; - } - } - } - if (/\s|\n|\t/.test(c)) { - html = html.replace(/\s|\n|\t/g, " "); - if (tmpName === false) { - j = findNextEqual(html, i); - if (j === -1) { - v = _.trim(html.slice(lastPos, i)); - addAttr(v); - tmpName = false; - lastPos = i + 1; - continue; - } else { - i = j - 1; - continue; - } - } else { - j = findBeforeEqual(html, i - 1); - if (j === -1) { - v = _.trim(html.slice(lastPos, i)); - v = stripQuoteWrap(v); - addAttr(tmpName, v); - tmpName = false; - lastPos = i + 1; - continue; - } else { - continue; - } - } - } - } - - if (lastPos < html.length) { - if (tmpName === false) { - addAttr(html.slice(lastPos)); - } else { - addAttr(tmpName, stripQuoteWrap(_.trim(html.slice(lastPos)))); - } - } - - return _.trim(retAttrs.join(" ")); -} - -function findNextEqual(str, i) { - for (; i < str.length; i++) { - var c = str[i]; - if (c === " ") continue; - if (c === "=") return i; - return -1; - } -} - -function findBeforeEqual(str, i) { - for (; i > 0; i--) { - var c = str[i]; - if (c === " ") continue; - if (c === "=") return i; - return -1; - } -} - -function isQuoteWrapString(text) { - if ( - (text[0] === '"' && text[text.length - 1] === '"') || - (text[0] === "'" && text[text.length - 1] === "'") - ) { - return true; - } else { - return false; - } -} - -function stripQuoteWrap(text) { - if (isQuoteWrapString(text)) { - return text.substr(1, text.length - 2); - } else { - return text; - } -} - -exports.parseTag = parseTag; -exports.parseAttr = parseAttr; - -},{"./util":4}],4:[function(require,module,exports){ -module.exports = { - indexOf: function(arr, item) { - var i, j; - if (Array.prototype.indexOf) { - return arr.indexOf(item); - } - for (i = 0, j = arr.length; i < j; i++) { - if (arr[i] === item) { - return i; - } - } - return -1; - }, - forEach: function(arr, fn, scope) { - var i, j; - if (Array.prototype.forEach) { - return arr.forEach(fn, scope); - } - for (i = 0, j = arr.length; i < j; i++) { - fn.call(scope, arr[i], i, arr); - } - }, - trim: function(str) { - if (String.prototype.trim) { - return str.trim(); - } - return str.replace(/(^\s*)|(\s*$)/g, ""); - }, - spaceIndex: function(str) { - var reg = /\s|\n|\t/; - var match = reg.exec(str); - return match ? match.index : -1; - } -}; - -},{}],5:[function(require,module,exports){ -/** - * filter xss - * - * @author Zongmin Lei - */ - -var FilterCSS = require("cssfilter").FilterCSS; -var DEFAULT = require("./default"); -var parser = require("./parser"); -var parseTag = parser.parseTag; -var parseAttr = parser.parseAttr; -var _ = require("./util"); - -/** - * returns `true` if the input value is `undefined` or `null` - * - * @param {Object} obj - * @return {Boolean} - */ -function isNull(obj) { - return obj === undefined || obj === null; -} - -/** - * get attributes for a tag - * - * @param {String} html - * @return {Object} - * - {String} html - * - {Boolean} closing - */ -function getAttrs(html) { - var i = _.spaceIndex(html); - if (i === -1) { - return { - html: "", - closing: html[html.length - 2] === "/" - }; - } - html = _.trim(html.slice(i + 1, -1)); - var isClosing = html[html.length - 1] === "/"; - if (isClosing) html = _.trim(html.slice(0, -1)); - return { - html: html, - closing: isClosing - }; -} - -/** - * shallow copy - * - * @param {Object} obj - * @return {Object} - */ -function shallowCopyObject(obj) { - var ret = {}; - for (var i in obj) { - ret[i] = obj[i]; - } - return ret; -} - -/** - * FilterXSS class - * - * @param {Object} options - * whiteList, onTag, onTagAttr, onIgnoreTag, - * onIgnoreTagAttr, safeAttrValue, escapeHtml - * stripIgnoreTagBody, allowCommentTag, stripBlankChar - * css{whiteList, onAttr, onIgnoreAttr} `css=false` means don't use `cssfilter` - */ -function FilterXSS(options) { - options = shallowCopyObject(options || {}); - - if (options.stripIgnoreTag) { - if (options.onIgnoreTag) { - console.error( - 'Notes: cannot use these two options "stripIgnoreTag" and "onIgnoreTag" at the same time' - ); - } - options.onIgnoreTag = DEFAULT.onIgnoreTagStripAll; - } - - options.whiteList = options.whiteList || DEFAULT.whiteList; - options.onTag = options.onTag || DEFAULT.onTag; - options.onTagAttr = options.onTagAttr || DEFAULT.onTagAttr; - options.onIgnoreTag = options.onIgnoreTag || DEFAULT.onIgnoreTag; - options.onIgnoreTagAttr = options.onIgnoreTagAttr || DEFAULT.onIgnoreTagAttr; - options.safeAttrValue = options.safeAttrValue || DEFAULT.safeAttrValue; - options.escapeHtml = options.escapeHtml || DEFAULT.escapeHtml; - this.options = options; - - if (options.css === false) { - this.cssFilter = false; - } else { - options.css = options.css || {}; - this.cssFilter = new FilterCSS(options.css); - } -} - -/** - * start process and returns result - * - * @param {String} html - * @return {String} - */ -FilterXSS.prototype.process = function(html) { - // compatible with the input - html = html || ""; - html = html.toString(); - if (!html) return ""; - - var me = this; - var options = me.options; - var whiteList = options.whiteList; - var onTag = options.onTag; - var onIgnoreTag = options.onIgnoreTag; - var onTagAttr = options.onTagAttr; - var onIgnoreTagAttr = options.onIgnoreTagAttr; - var safeAttrValue = options.safeAttrValue; - var escapeHtml = options.escapeHtml; - var cssFilter = me.cssFilter; - - // remove invisible characters - if (options.stripBlankChar) { - html = DEFAULT.stripBlankChar(html); - } - - // remove html comments - if (!options.allowCommentTag) { - html = DEFAULT.stripCommentTag(html); - } - - // if enable stripIgnoreTagBody - var stripIgnoreTagBody = false; - if (options.stripIgnoreTagBody) { - var stripIgnoreTagBody = DEFAULT.StripTagBody( - options.stripIgnoreTagBody, - onIgnoreTag - ); - onIgnoreTag = stripIgnoreTagBody.onIgnoreTag; - } - - var retHtml = parseTag( - html, - function(sourcePosition, position, tag, html, isClosing) { - var info = { - sourcePosition: sourcePosition, - position: position, - isClosing: isClosing, - isWhite: whiteList.hasOwnProperty(tag) - }; - - // call `onTag()` - var ret = onTag(tag, html, info); - if (!isNull(ret)) return ret; - - if (info.isWhite) { - if (info.isClosing) { - return ""; - } - - var attrs = getAttrs(html); - var whiteAttrList = whiteList[tag]; - var attrsHtml = parseAttr(attrs.html, function(name, value) { - // call `onTagAttr()` - var isWhiteAttr = _.indexOf(whiteAttrList, name) !== -1; - var ret = onTagAttr(tag, name, value, isWhiteAttr); - if (!isNull(ret)) return ret; - - if (isWhiteAttr) { - // call `safeAttrValue()` - value = safeAttrValue(tag, name, value, cssFilter); - if (value) { - return name + '="' + value + '"'; - } else { - return name; - } - } else { - // call `onIgnoreTagAttr()` - var ret = onIgnoreTagAttr(tag, name, value, isWhiteAttr); - if (!isNull(ret)) return ret; - return; - } - }); - - // build new tag html - var html = "<" + tag; - if (attrsHtml) html += " " + attrsHtml; - if (attrs.closing) html += " /"; - html += ">"; - return html; - } else { - // call `onIgnoreTag()` - var ret = onIgnoreTag(tag, html, info); - if (!isNull(ret)) return ret; - return escapeHtml(html); - } - }, - escapeHtml - ); - - // if enable stripIgnoreTagBody - if (stripIgnoreTagBody) { - retHtml = stripIgnoreTagBody.remove(retHtml); - } - - return retHtml; -}; - -module.exports = FilterXSS; - -},{"./default":1,"./parser":3,"./util":4,"cssfilter":8}],6:[function(require,module,exports){ -/** - * cssfilter - * - * @author 老雷 - */ - -var DEFAULT = require('./default'); -var parseStyle = require('./parser'); -var _ = require('./util'); - - -/** - * 返回值是否为空 - * - * @param {Object} obj - * @return {Boolean} - */ -function isNull (obj) { - return (obj === undefined || obj === null); -} - -/** - * 浅拷贝对象 - * - * @param {Object} obj - * @return {Object} - */ -function shallowCopyObject (obj) { - var ret = {}; - for (var i in obj) { - ret[i] = obj[i]; - } - return ret; -} - -/** - * 创建CSS过滤器 - * - * @param {Object} options - * - {Object} whiteList - * - {Function} onAttr - * - {Function} onIgnoreAttr - * - {Function} safeAttrValue - */ -function FilterCSS (options) { - options = shallowCopyObject(options || {}); - options.whiteList = options.whiteList || DEFAULT.whiteList; - options.onAttr = options.onAttr || DEFAULT.onAttr; - options.onIgnoreAttr = options.onIgnoreAttr || DEFAULT.onIgnoreAttr; - options.safeAttrValue = options.safeAttrValue || DEFAULT.safeAttrValue; - this.options = options; -} - -FilterCSS.prototype.process = function (css) { - // 兼容各种奇葩输入 - css = css || ''; - css = css.toString(); - if (!css) return ''; - - var me = this; - var options = me.options; - var whiteList = options.whiteList; - var onAttr = options.onAttr; - var onIgnoreAttr = options.onIgnoreAttr; - var safeAttrValue = options.safeAttrValue; - - var retCSS = parseStyle(css, function (sourcePosition, position, name, value, source) { - - var check = whiteList[name]; - var isWhite = false; - if (check === true) isWhite = check; - else if (typeof check === 'function') isWhite = check(value); - else if (check instanceof RegExp) isWhite = check.test(value); - if (isWhite !== true) isWhite = false; - - // 如果过滤后 value 为空则直接忽略 - value = safeAttrValue(name, value); - if (!value) return; - - var opts = { - position: position, - sourcePosition: sourcePosition, - source: source, - isWhite: isWhite - }; - - if (isWhite) { - - var ret = onAttr(name, value, opts); - if (isNull(ret)) { - return name + ':' + value; - } else { - return ret; - } - - } else { - - var ret = onIgnoreAttr(name, value, opts); - if (!isNull(ret)) { - return ret; - } - - } - }); - - return retCSS; -}; - - -module.exports = FilterCSS; - -},{"./default":7,"./parser":9,"./util":10}],7:[function(require,module,exports){ -/** - * cssfilter - * - * @author 老雷 - */ - -function getDefaultWhiteList () { - // 白名单值说明: - // true: 允许该属性 - // Function: function (val) { } 返回true表示允许该属性,其他值均表示不允许 - // RegExp: regexp.test(val) 返回true表示允许该属性,其他值均表示不允许 - // 除上面列出的值外均表示不允许 - var whiteList = {}; - - whiteList['align-content'] = false; // default: auto - whiteList['align-items'] = false; // default: auto - whiteList['align-self'] = false; // default: auto - whiteList['alignment-adjust'] = false; // default: auto - whiteList['alignment-baseline'] = false; // default: baseline - whiteList['all'] = false; // default: depending on individual properties - whiteList['anchor-point'] = false; // default: none - whiteList['animation'] = false; // default: depending on individual properties - whiteList['animation-delay'] = false; // default: 0 - whiteList['animation-direction'] = false; // default: normal - whiteList['animation-duration'] = false; // default: 0 - whiteList['animation-fill-mode'] = false; // default: none - whiteList['animation-iteration-count'] = false; // default: 1 - whiteList['animation-name'] = false; // default: none - whiteList['animation-play-state'] = false; // default: running - whiteList['animation-timing-function'] = false; // default: ease - whiteList['azimuth'] = false; // default: center - whiteList['backface-visibility'] = false; // default: visible - whiteList['background'] = true; // default: depending on individual properties - whiteList['background-attachment'] = true; // default: scroll - whiteList['background-clip'] = true; // default: border-box - whiteList['background-color'] = true; // default: transparent - whiteList['background-image'] = true; // default: none - whiteList['background-origin'] = true; // default: padding-box - whiteList['background-position'] = true; // default: 0% 0% - whiteList['background-repeat'] = true; // default: repeat - whiteList['background-size'] = true; // default: auto - whiteList['baseline-shift'] = false; // default: baseline - whiteList['binding'] = false; // default: none - whiteList['bleed'] = false; // default: 6pt - whiteList['bookmark-label'] = false; // default: content() - whiteList['bookmark-level'] = false; // default: none - whiteList['bookmark-state'] = false; // default: open - whiteList['border'] = true; // default: depending on individual properties - whiteList['border-bottom'] = true; // default: depending on individual properties - whiteList['border-bottom-color'] = true; // default: current color - whiteList['border-bottom-left-radius'] = true; // default: 0 - whiteList['border-bottom-right-radius'] = true; // default: 0 - whiteList['border-bottom-style'] = true; // default: none - whiteList['border-bottom-width'] = true; // default: medium - whiteList['border-collapse'] = true; // default: separate - whiteList['border-color'] = true; // default: depending on individual properties - whiteList['border-image'] = true; // default: none - whiteList['border-image-outset'] = true; // default: 0 - whiteList['border-image-repeat'] = true; // default: stretch - whiteList['border-image-slice'] = true; // default: 100% - whiteList['border-image-source'] = true; // default: none - whiteList['border-image-width'] = true; // default: 1 - whiteList['border-left'] = true; // default: depending on individual properties - whiteList['border-left-color'] = true; // default: current color - whiteList['border-left-style'] = true; // default: none - whiteList['border-left-width'] = true; // default: medium - whiteList['border-radius'] = true; // default: 0 - whiteList['border-right'] = true; // default: depending on individual properties - whiteList['border-right-color'] = true; // default: current color - whiteList['border-right-style'] = true; // default: none - whiteList['border-right-width'] = true; // default: medium - whiteList['border-spacing'] = true; // default: 0 - whiteList['border-style'] = true; // default: depending on individual properties - whiteList['border-top'] = true; // default: depending on individual properties - whiteList['border-top-color'] = true; // default: current color - whiteList['border-top-left-radius'] = true; // default: 0 - whiteList['border-top-right-radius'] = true; // default: 0 - whiteList['border-top-style'] = true; // default: none - whiteList['border-top-width'] = true; // default: medium - whiteList['border-width'] = true; // default: depending on individual properties - whiteList['bottom'] = false; // default: auto - whiteList['box-decoration-break'] = true; // default: slice - whiteList['box-shadow'] = true; // default: none - whiteList['box-sizing'] = true; // default: content-box - whiteList['box-snap'] = true; // default: none - whiteList['box-suppress'] = true; // default: show - whiteList['break-after'] = true; // default: auto - whiteList['break-before'] = true; // default: auto - whiteList['break-inside'] = true; // default: auto - whiteList['caption-side'] = false; // default: top - whiteList['chains'] = false; // default: none - whiteList['clear'] = true; // default: none - whiteList['clip'] = false; // default: auto - whiteList['clip-path'] = false; // default: none - whiteList['clip-rule'] = false; // default: nonzero - whiteList['color'] = true; // default: implementation dependent - whiteList['color-interpolation-filters'] = true; // default: auto - whiteList['column-count'] = false; // default: auto - whiteList['column-fill'] = false; // default: balance - whiteList['column-gap'] = false; // default: normal - whiteList['column-rule'] = false; // default: depending on individual properties - whiteList['column-rule-color'] = false; // default: current color - whiteList['column-rule-style'] = false; // default: medium - whiteList['column-rule-width'] = false; // default: medium - whiteList['column-span'] = false; // default: none - whiteList['column-width'] = false; // default: auto - whiteList['columns'] = false; // default: depending on individual properties - whiteList['contain'] = false; // default: none - whiteList['content'] = false; // default: normal - whiteList['counter-increment'] = false; // default: none - whiteList['counter-reset'] = false; // default: none - whiteList['counter-set'] = false; // default: none - whiteList['crop'] = false; // default: auto - whiteList['cue'] = false; // default: depending on individual properties - whiteList['cue-after'] = false; // default: none - whiteList['cue-before'] = false; // default: none - whiteList['cursor'] = false; // default: auto - whiteList['direction'] = false; // default: ltr - whiteList['display'] = true; // default: depending on individual properties - whiteList['display-inside'] = true; // default: auto - whiteList['display-list'] = true; // default: none - whiteList['display-outside'] = true; // default: inline-level - whiteList['dominant-baseline'] = false; // default: auto - whiteList['elevation'] = false; // default: level - whiteList['empty-cells'] = false; // default: show - whiteList['filter'] = false; // default: none - whiteList['flex'] = false; // default: depending on individual properties - whiteList['flex-basis'] = false; // default: auto - whiteList['flex-direction'] = false; // default: row - whiteList['flex-flow'] = false; // default: depending on individual properties - whiteList['flex-grow'] = false; // default: 0 - whiteList['flex-shrink'] = false; // default: 1 - whiteList['flex-wrap'] = false; // default: nowrap - whiteList['float'] = false; // default: none - whiteList['float-offset'] = false; // default: 0 0 - whiteList['flood-color'] = false; // default: black - whiteList['flood-opacity'] = false; // default: 1 - whiteList['flow-from'] = false; // default: none - whiteList['flow-into'] = false; // default: none - whiteList['font'] = true; // default: depending on individual properties - whiteList['font-family'] = true; // default: implementation dependent - whiteList['font-feature-settings'] = true; // default: normal - whiteList['font-kerning'] = true; // default: auto - whiteList['font-language-override'] = true; // default: normal - whiteList['font-size'] = true; // default: medium - whiteList['font-size-adjust'] = true; // default: none - whiteList['font-stretch'] = true; // default: normal - whiteList['font-style'] = true; // default: normal - whiteList['font-synthesis'] = true; // default: weight style - whiteList['font-variant'] = true; // default: normal - whiteList['font-variant-alternates'] = true; // default: normal - whiteList['font-variant-caps'] = true; // default: normal - whiteList['font-variant-east-asian'] = true; // default: normal - whiteList['font-variant-ligatures'] = true; // default: normal - whiteList['font-variant-numeric'] = true; // default: normal - whiteList['font-variant-position'] = true; // default: normal - whiteList['font-weight'] = true; // default: normal - whiteList['grid'] = false; // default: depending on individual properties - whiteList['grid-area'] = false; // default: depending on individual properties - whiteList['grid-auto-columns'] = false; // default: auto - whiteList['grid-auto-flow'] = false; // default: none - whiteList['grid-auto-rows'] = false; // default: auto - whiteList['grid-column'] = false; // default: depending on individual properties - whiteList['grid-column-end'] = false; // default: auto - whiteList['grid-column-start'] = false; // default: auto - whiteList['grid-row'] = false; // default: depending on individual properties - whiteList['grid-row-end'] = false; // default: auto - whiteList['grid-row-start'] = false; // default: auto - whiteList['grid-template'] = false; // default: depending on individual properties - whiteList['grid-template-areas'] = false; // default: none - whiteList['grid-template-columns'] = false; // default: none - whiteList['grid-template-rows'] = false; // default: none - whiteList['hanging-punctuation'] = false; // default: none - whiteList['height'] = true; // default: auto - whiteList['hyphens'] = false; // default: manual - whiteList['icon'] = false; // default: auto - whiteList['image-orientation'] = false; // default: auto - whiteList['image-resolution'] = false; // default: normal - whiteList['ime-mode'] = false; // default: auto - whiteList['initial-letters'] = false; // default: normal - whiteList['inline-box-align'] = false; // default: last - whiteList['justify-content'] = false; // default: auto - whiteList['justify-items'] = false; // default: auto - whiteList['justify-self'] = false; // default: auto - whiteList['left'] = false; // default: auto - whiteList['letter-spacing'] = true; // default: normal - whiteList['lighting-color'] = true; // default: white - whiteList['line-box-contain'] = false; // default: block inline replaced - whiteList['line-break'] = false; // default: auto - whiteList['line-grid'] = false; // default: match-parent - whiteList['line-height'] = false; // default: normal - whiteList['line-snap'] = false; // default: none - whiteList['line-stacking'] = false; // default: depending on individual properties - whiteList['line-stacking-ruby'] = false; // default: exclude-ruby - whiteList['line-stacking-shift'] = false; // default: consider-shifts - whiteList['line-stacking-strategy'] = false; // default: inline-line-height - whiteList['list-style'] = true; // default: depending on individual properties - whiteList['list-style-image'] = true; // default: none - whiteList['list-style-position'] = true; // default: outside - whiteList['list-style-type'] = true; // default: disc - whiteList['margin'] = true; // default: depending on individual properties - whiteList['margin-bottom'] = true; // default: 0 - whiteList['margin-left'] = true; // default: 0 - whiteList['margin-right'] = true; // default: 0 - whiteList['margin-top'] = true; // default: 0 - whiteList['marker-offset'] = false; // default: auto - whiteList['marker-side'] = false; // default: list-item - whiteList['marks'] = false; // default: none - whiteList['mask'] = false; // default: border-box - whiteList['mask-box'] = false; // default: see individual properties - whiteList['mask-box-outset'] = false; // default: 0 - whiteList['mask-box-repeat'] = false; // default: stretch - whiteList['mask-box-slice'] = false; // default: 0 fill - whiteList['mask-box-source'] = false; // default: none - whiteList['mask-box-width'] = false; // default: auto - whiteList['mask-clip'] = false; // default: border-box - whiteList['mask-image'] = false; // default: none - whiteList['mask-origin'] = false; // default: border-box - whiteList['mask-position'] = false; // default: center - whiteList['mask-repeat'] = false; // default: no-repeat - whiteList['mask-size'] = false; // default: border-box - whiteList['mask-source-type'] = false; // default: auto - whiteList['mask-type'] = false; // default: luminance - whiteList['max-height'] = true; // default: none - whiteList['max-lines'] = false; // default: none - whiteList['max-width'] = true; // default: none - whiteList['min-height'] = true; // default: 0 - whiteList['min-width'] = true; // default: 0 - whiteList['move-to'] = false; // default: normal - whiteList['nav-down'] = false; // default: auto - whiteList['nav-index'] = false; // default: auto - whiteList['nav-left'] = false; // default: auto - whiteList['nav-right'] = false; // default: auto - whiteList['nav-up'] = false; // default: auto - whiteList['object-fit'] = false; // default: fill - whiteList['object-position'] = false; // default: 50% 50% - whiteList['opacity'] = false; // default: 1 - whiteList['order'] = false; // default: 0 - whiteList['orphans'] = false; // default: 2 - whiteList['outline'] = false; // default: depending on individual properties - whiteList['outline-color'] = false; // default: invert - whiteList['outline-offset'] = false; // default: 0 - whiteList['outline-style'] = false; // default: none - whiteList['outline-width'] = false; // default: medium - whiteList['overflow'] = false; // default: depending on individual properties - whiteList['overflow-wrap'] = false; // default: normal - whiteList['overflow-x'] = false; // default: visible - whiteList['overflow-y'] = false; // default: visible - whiteList['padding'] = true; // default: depending on individual properties - whiteList['padding-bottom'] = true; // default: 0 - whiteList['padding-left'] = true; // default: 0 - whiteList['padding-right'] = true; // default: 0 - whiteList['padding-top'] = true; // default: 0 - whiteList['page'] = false; // default: auto - whiteList['page-break-after'] = false; // default: auto - whiteList['page-break-before'] = false; // default: auto - whiteList['page-break-inside'] = false; // default: auto - whiteList['page-policy'] = false; // default: start - whiteList['pause'] = false; // default: implementation dependent - whiteList['pause-after'] = false; // default: implementation dependent - whiteList['pause-before'] = false; // default: implementation dependent - whiteList['perspective'] = false; // default: none - whiteList['perspective-origin'] = false; // default: 50% 50% - whiteList['pitch'] = false; // default: medium - whiteList['pitch-range'] = false; // default: 50 - whiteList['play-during'] = false; // default: auto - whiteList['position'] = false; // default: static - whiteList['presentation-level'] = false; // default: 0 - whiteList['quotes'] = false; // default: text - whiteList['region-fragment'] = false; // default: auto - whiteList['resize'] = false; // default: none - whiteList['rest'] = false; // default: depending on individual properties - whiteList['rest-after'] = false; // default: none - whiteList['rest-before'] = false; // default: none - whiteList['richness'] = false; // default: 50 - whiteList['right'] = false; // default: auto - whiteList['rotation'] = false; // default: 0 - whiteList['rotation-point'] = false; // default: 50% 50% - whiteList['ruby-align'] = false; // default: auto - whiteList['ruby-merge'] = false; // default: separate - whiteList['ruby-position'] = false; // default: before - whiteList['shape-image-threshold'] = false; // default: 0.0 - whiteList['shape-outside'] = false; // default: none - whiteList['shape-margin'] = false; // default: 0 - whiteList['size'] = false; // default: auto - whiteList['speak'] = false; // default: auto - whiteList['speak-as'] = false; // default: normal - whiteList['speak-header'] = false; // default: once - whiteList['speak-numeral'] = false; // default: continuous - whiteList['speak-punctuation'] = false; // default: none - whiteList['speech-rate'] = false; // default: medium - whiteList['stress'] = false; // default: 50 - whiteList['string-set'] = false; // default: none - whiteList['tab-size'] = false; // default: 8 - whiteList['table-layout'] = false; // default: auto - whiteList['text-align'] = true; // default: start - whiteList['text-align-last'] = true; // default: auto - whiteList['text-combine-upright'] = true; // default: none - whiteList['text-decoration'] = true; // default: none - whiteList['text-decoration-color'] = true; // default: currentColor - whiteList['text-decoration-line'] = true; // default: none - whiteList['text-decoration-skip'] = true; // default: objects - whiteList['text-decoration-style'] = true; // default: solid - whiteList['text-emphasis'] = true; // default: depending on individual properties - whiteList['text-emphasis-color'] = true; // default: currentColor - whiteList['text-emphasis-position'] = true; // default: over right - whiteList['text-emphasis-style'] = true; // default: none - whiteList['text-height'] = true; // default: auto - whiteList['text-indent'] = true; // default: 0 - whiteList['text-justify'] = true; // default: auto - whiteList['text-orientation'] = true; // default: mixed - whiteList['text-overflow'] = true; // default: clip - whiteList['text-shadow'] = true; // default: none - whiteList['text-space-collapse'] = true; // default: collapse - whiteList['text-transform'] = true; // default: none - whiteList['text-underline-position'] = true; // default: auto - whiteList['text-wrap'] = true; // default: normal - whiteList['top'] = false; // default: auto - whiteList['transform'] = false; // default: none - whiteList['transform-origin'] = false; // default: 50% 50% 0 - whiteList['transform-style'] = false; // default: flat - whiteList['transition'] = false; // default: depending on individual properties - whiteList['transition-delay'] = false; // default: 0s - whiteList['transition-duration'] = false; // default: 0s - whiteList['transition-property'] = false; // default: all - whiteList['transition-timing-function'] = false; // default: ease - whiteList['unicode-bidi'] = false; // default: normal - whiteList['vertical-align'] = false; // default: baseline - whiteList['visibility'] = false; // default: visible - whiteList['voice-balance'] = false; // default: center - whiteList['voice-duration'] = false; // default: auto - whiteList['voice-family'] = false; // default: implementation dependent - whiteList['voice-pitch'] = false; // default: medium - whiteList['voice-range'] = false; // default: medium - whiteList['voice-rate'] = false; // default: normal - whiteList['voice-stress'] = false; // default: normal - whiteList['voice-volume'] = false; // default: medium - whiteList['volume'] = false; // default: medium - whiteList['white-space'] = false; // default: normal - whiteList['widows'] = false; // default: 2 - whiteList['width'] = true; // default: auto - whiteList['will-change'] = false; // default: auto - whiteList['word-break'] = true; // default: normal - whiteList['word-spacing'] = true; // default: normal - whiteList['word-wrap'] = true; // default: normal - whiteList['wrap-flow'] = false; // default: auto - whiteList['wrap-through'] = false; // default: wrap - whiteList['writing-mode'] = false; // default: horizontal-tb - whiteList['z-index'] = false; // default: auto - - return whiteList; -} - - -/** - * 匹配到白名单上的一个属性时 - * - * @param {String} name - * @param {String} value - * @param {Object} options - * @return {String} - */ -function onAttr (name, value, options) { - // do nothing -} - -/** - * 匹配到不在白名单上的一个属性时 - * - * @param {String} name - * @param {String} value - * @param {Object} options - * @return {String} - */ -function onIgnoreAttr (name, value, options) { - // do nothing -} - -var REGEXP_URL_JAVASCRIPT = /javascript\s*\:/img; - -/** - * 过滤属性值 - * - * @param {String} name - * @param {String} value - * @return {String} - */ -function safeAttrValue(name, value) { - if (REGEXP_URL_JAVASCRIPT.test(value)) return ''; - return value; -} - - -exports.whiteList = getDefaultWhiteList(); -exports.getDefaultWhiteList = getDefaultWhiteList; -exports.onAttr = onAttr; -exports.onIgnoreAttr = onIgnoreAttr; -exports.safeAttrValue = safeAttrValue; - -},{}],8:[function(require,module,exports){ -/** - * cssfilter - * - * @author 老雷 - */ - -var DEFAULT = require('./default'); -var FilterCSS = require('./css'); - - -/** - * XSS过滤 - * - * @param {String} css 要过滤的CSS代码 - * @param {Object} options 选项:whiteList, onAttr, onIgnoreAttr - * @return {String} - */ -function filterCSS (html, options) { - var xss = new FilterCSS(options); - return xss.process(html); -} - - -// 输出 -exports = module.exports = filterCSS; -exports.FilterCSS = FilterCSS; -for (var i in DEFAULT) exports[i] = DEFAULT[i]; - -// 在浏览器端使用 -if (typeof window !== 'undefined') { - window.filterCSS = module.exports; -} - -},{"./css":6,"./default":7}],9:[function(require,module,exports){ -/** - * cssfilter - * - * @author 老雷 - */ - -var _ = require('./util'); - - -/** - * 解析style - * - * @param {String} css - * @param {Function} onAttr 处理属性的函数 - * 参数格式: function (sourcePosition, position, name, value, source) - * @return {String} - */ -function parseStyle (css, onAttr) { - css = _.trimRight(css); - if (css[css.length - 1] !== ';') css += ';'; - var cssLength = css.length; - var isParenthesisOpen = false; - var lastPos = 0; - var i = 0; - var retCSS = ''; - - function addNewAttr () { - // 如果没有正常的闭合圆括号,则直接忽略当前属性 - if (!isParenthesisOpen) { - var source = _.trim(css.slice(lastPos, i)); - var j = source.indexOf(':'); - if (j !== -1) { - var name = _.trim(source.slice(0, j)); - var value = _.trim(source.slice(j + 1)); - // 必须有属性名称 - if (name) { - var ret = onAttr(lastPos, retCSS.length, name, value, source); - if (ret) retCSS += ret + '; '; - } - } - } - lastPos = i + 1; - } - - for (; i < cssLength; i++) { - var c = css[i]; - if (c === '/' && css[i + 1] === '*') { - // 备注开始 - var j = css.indexOf('*/', i + 2); - // 如果没有正常的备注结束,则后面的部分全部跳过 - if (j === -1) break; - // 直接将当前位置调到备注结尾,并且初始化状态 - i = j + 1; - lastPos = i + 1; - isParenthesisOpen = false; - } else if (c === '(') { - isParenthesisOpen = true; - } else if (c === ')') { - isParenthesisOpen = false; - } else if (c === ';') { - if (isParenthesisOpen) { - // 在圆括号里面,忽略 - } else { - addNewAttr(); - } - } else if (c === '\n') { - addNewAttr(); - } - } - - return _.trim(retCSS); -} - -module.exports = parseStyle; - -},{"./util":10}],10:[function(require,module,exports){ -module.exports = { - indexOf: function (arr, item) { - var i, j; - if (Array.prototype.indexOf) { - return arr.indexOf(item); - } - for (i = 0, j = arr.length; i < j; i++) { - if (arr[i] === item) { - return i; - } - } - return -1; - }, - forEach: function (arr, fn, scope) { - var i, j; - if (Array.prototype.forEach) { - return arr.forEach(fn, scope); - } - for (i = 0, j = arr.length; i < j; i++) { - fn.call(scope, arr[i], i, arr); - } - }, - trim: function (str) { - if (String.prototype.trim) { - return str.trim(); - } - return str.replace(/(^\s*)|(\s*$)/g, ''); - }, - trimRight: function (str) { - if (String.prototype.trimRight) { - return str.trimRight(); - } - return str.replace(/(\s*$)/g, ''); - } -}; - -},{}]},{},[2]); diff --git a/node_modules/xss/dist/xss.min.js b/node_modules/xss/dist/xss.min.js deleted file mode 100644 index b2c3878..0000000 --- a/node_modules/xss/dist/xss.min.js +++ /dev/null @@ -1 +0,0 @@ -(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o/g;var REGEXP_QUOTE=/"/g;var REGEXP_QUOTE_2=/"/g;var REGEXP_ATTR_VALUE_1=/&#([a-zA-Z0-9]*);?/gim;var REGEXP_ATTR_VALUE_COLON=/:?/gim;var REGEXP_ATTR_VALUE_NEWLINE=/&newline;?/gim;var REGEXP_DEFAULT_ON_TAG_ATTR_3=/\/\*|\*\//gm;var REGEXP_DEFAULT_ON_TAG_ATTR_4=/((j\s*a\s*v\s*a|v\s*b|l\s*i\s*v\s*e)\s*s\s*c\s*r\s*i\s*p\s*t\s*|m\s*o\s*c\s*h\s*a)\:/gi;var REGEXP_DEFAULT_ON_TAG_ATTR_5=/^[\s"'`]*(d\s*a\s*t\s*a\s*)\:/gi;var REGEXP_DEFAULT_ON_TAG_ATTR_6=/^[\s"'`]*(d\s*a\s*t\s*a\s*)\:\s*image\//gi;var REGEXP_DEFAULT_ON_TAG_ATTR_7=/e\s*x\s*p\s*r\s*e\s*s\s*s\s*i\s*o\s*n\s*\(.*/gi;var REGEXP_DEFAULT_ON_TAG_ATTR_8=/u\s*r\s*l\s*\(.*/gi;function escapeQuote(str){return str.replace(REGEXP_QUOTE,""")}function unescapeQuote(str){return str.replace(REGEXP_QUOTE_2,'"')}function escapeHtmlEntities(str){return str.replace(REGEXP_ATTR_VALUE_1,function replaceUnicode(str,code){return code[0]==="x"||code[0]==="X"?String.fromCharCode(parseInt(code.substr(1),16)):String.fromCharCode(parseInt(code,10))})}function escapeDangerHtml5Entities(str){return str.replace(REGEXP_ATTR_VALUE_COLON,":").replace(REGEXP_ATTR_VALUE_NEWLINE," ")}function clearNonPrintableCharacter(str){var str2="";for(var i=0,len=str.length;i/g;function stripBlankChar(html){var chars=html.split("");chars=chars.filter(function(char){var c=char.charCodeAt(0);if(c===127)return false;if(c<=31){if(c===10||c===13)return true;return false}return true});return chars.join("")}exports.whiteList=getDefaultWhiteList();exports.getDefaultWhiteList=getDefaultWhiteList;exports.onTag=onTag;exports.onIgnoreTag=onIgnoreTag;exports.onTagAttr=onTagAttr;exports.onIgnoreTagAttr=onIgnoreTagAttr;exports.safeAttrValue=safeAttrValue;exports.escapeHtml=escapeHtml;exports.escapeQuote=escapeQuote;exports.unescapeQuote=unescapeQuote;exports.escapeHtmlEntities=escapeHtmlEntities;exports.escapeDangerHtml5Entities=escapeDangerHtml5Entities;exports.clearNonPrintableCharacter=clearNonPrintableCharacter;exports.friendlyAttrValue=friendlyAttrValue;exports.escapeAttrValue=escapeAttrValue;exports.onIgnoreTagStripAll=onIgnoreTagStripAll;exports.StripTagBody=StripTagBody;exports.stripCommentTag=stripCommentTag;exports.stripBlankChar=stripBlankChar;exports.cssFilter=defaultCSSFilter;exports.getDefaultCSSWhiteList=getDefaultCSSWhiteList},{"./util":4,cssfilter:8}],2:[function(require,module,exports){var DEFAULT=require("./default");var parser=require("./parser");var FilterXSS=require("./xss");function filterXSS(html,options){var xss=new FilterXSS(options);return xss.process(html)}exports=module.exports=filterXSS;exports.filterXSS=filterXSS;exports.FilterXSS=FilterXSS;for(var i in DEFAULT)exports[i]=DEFAULT[i];for(var i in parser)exports[i]=parser[i];if(typeof window!=="undefined"){window.filterXSS=module.exports}function isWorkerEnv(){return typeof self!=="undefined"&&typeof DedicatedWorkerGlobalScope!=="undefined"&&self instanceof DedicatedWorkerGlobalScope}if(isWorkerEnv()){self.filterXSS=module.exports}},{"./default":1,"./parser":3,"./xss":5}],3:[function(require,module,exports){var _=require("./util");function getTagName(html){var i=_.spaceIndex(html);if(i===-1){var tagName=html.slice(1,-1)}else{var tagName=html.slice(1,i+1)}tagName=_.trim(tagName).toLowerCase();if(tagName.slice(0,1)==="/")tagName=tagName.slice(1);if(tagName.slice(-1)==="/")tagName=tagName.slice(0,-1);return tagName}function isClosing(html){return html.slice(0,2)===""){rethtml+=escapeHtml(html.slice(lastPos,tagStart));currentHtml=html.slice(tagStart,currentPos+1);currentTagName=getTagName(currentHtml);rethtml+=onTag(tagStart,rethtml.length,currentTagName,currentHtml,isClosing(currentHtml));lastPos=currentPos+1;tagStart=false;continue}if((c==='"'||c==="'")&&html.charAt(currentPos-1)==="="){quoteStart=c;continue}}else{if(c===quoteStart){quoteStart=false;continue}}}}if(lastPos0;i--){var c=str[i];if(c===" ")continue;if(c==="=")return i;return-1}}function isQuoteWrapString(text){if(text[0]==='"'&&text[text.length-1]==='"'||text[0]==="'"&&text[text.length-1]==="'"){return true}else{return false}}function stripQuoteWrap(text){if(isQuoteWrapString(text)){return text.substr(1,text.length-2)}else{return text}}exports.parseTag=parseTag;exports.parseAttr=parseAttr},{"./util":4}],4:[function(require,module,exports){module.exports={indexOf:function(arr,item){var i,j;if(Array.prototype.indexOf){return arr.indexOf(item)}for(i=0,j=arr.length;i"}var attrs=getAttrs(html);var whiteAttrList=whiteList[tag];var attrsHtml=parseAttr(attrs.html,function(name,value){var isWhiteAttr=_.indexOf(whiteAttrList,name)!==-1;var ret=onTagAttr(tag,name,value,isWhiteAttr);if(!isNull(ret))return ret;if(isWhiteAttr){value=safeAttrValue(tag,name,value,cssFilter);if(value){return name+'="'+value+'"'}else{return name}}else{var ret=onIgnoreTagAttr(tag,name,value,isWhiteAttr);if(!isNull(ret))return ret;return}});var html="<"+tag;if(attrsHtml)html+=" "+attrsHtml;if(attrs.closing)html+=" /";html+=">";return html}else{var ret=onIgnoreTag(tag,html,info);if(!isNull(ret))return ret;return escapeHtml(html)}},escapeHtml);if(stripIgnoreTagBody){retHtml=stripIgnoreTagBody.remove(retHtml)}return retHtml};module.exports=FilterXSS},{"./default":1,"./parser":3,"./util":4,cssfilter:8}],6:[function(require,module,exports){var DEFAULT=require("./default");var parseStyle=require("./parser");var _=require("./util");function isNull(obj){return obj===undefined||obj===null}function shallowCopyObject(obj){var ret={};for(var i in obj){ret[i]=obj[i]}return ret}function FilterCSS(options){options=shallowCopyObject(options||{});options.whiteList=options.whiteList||DEFAULT.whiteList;options.onAttr=options.onAttr||DEFAULT.onAttr;options.onIgnoreAttr=options.onIgnoreAttr||DEFAULT.onIgnoreAttr;options.safeAttrValue=options.safeAttrValue||DEFAULT.safeAttrValue;this.options=options}FilterCSS.prototype.process=function(css){css=css||"";css=css.toString();if(!css)return"";var me=this;var options=me.options;var whiteList=options.whiteList;var onAttr=options.onAttr;var onIgnoreAttr=options.onIgnoreAttr;var safeAttrValue=options.safeAttrValue;var retCSS=parseStyle(css,function(sourcePosition,position,name,value,source){var check=whiteList[name];var isWhite=false;if(check===true)isWhite=check;else if(typeof check==="function")isWhite=check(value);else if(check instanceof RegExp)isWhite=check.test(value);if(isWhite!==true)isWhite=false;value=safeAttrValue(name,value);if(!value)return;var opts={position:position,sourcePosition:sourcePosition,source:source,isWhite:isWhite};if(isWhite){var ret=onAttr(name,value,opts);if(isNull(ret)){return name+":"+value}else{return ret}}else{var ret=onIgnoreAttr(name,value,opts);if(!isNull(ret)){return ret}}});return retCSS};module.exports=FilterCSS},{"./default":7,"./parser":9,"./util":10}],7:[function(require,module,exports){function getDefaultWhiteList(){var whiteList={};whiteList["align-content"]=false;whiteList["align-items"]=false;whiteList["align-self"]=false;whiteList["alignment-adjust"]=false;whiteList["alignment-baseline"]=false;whiteList["all"]=false;whiteList["anchor-point"]=false;whiteList["animation"]=false;whiteList["animation-delay"]=false;whiteList["animation-direction"]=false;whiteList["animation-duration"]=false;whiteList["animation-fill-mode"]=false;whiteList["animation-iteration-count"]=false;whiteList["animation-name"]=false;whiteList["animation-play-state"]=false;whiteList["animation-timing-function"]=false;whiteList["azimuth"]=false;whiteList["backface-visibility"]=false;whiteList["background"]=true;whiteList["background-attachment"]=true;whiteList["background-clip"]=true;whiteList["background-color"]=true;whiteList["background-image"]=true;whiteList["background-origin"]=true;whiteList["background-position"]=true;whiteList["background-repeat"]=true;whiteList["background-size"]=true;whiteList["baseline-shift"]=false;whiteList["binding"]=false;whiteList["bleed"]=false;whiteList["bookmark-label"]=false;whiteList["bookmark-level"]=false;whiteList["bookmark-state"]=false;whiteList["border"]=true;whiteList["border-bottom"]=true;whiteList["border-bottom-color"]=true;whiteList["border-bottom-left-radius"]=true;whiteList["border-bottom-right-radius"]=true;whiteList["border-bottom-style"]=true;whiteList["border-bottom-width"]=true;whiteList["border-collapse"]=true;whiteList["border-color"]=true;whiteList["border-image"]=true;whiteList["border-image-outset"]=true;whiteList["border-image-repeat"]=true;whiteList["border-image-slice"]=true;whiteList["border-image-source"]=true;whiteList["border-image-width"]=true;whiteList["border-left"]=true;whiteList["border-left-color"]=true;whiteList["border-left-style"]=true;whiteList["border-left-width"]=true;whiteList["border-radius"]=true;whiteList["border-right"]=true;whiteList["border-right-color"]=true;whiteList["border-right-style"]=true;whiteList["border-right-width"]=true;whiteList["border-spacing"]=true;whiteList["border-style"]=true;whiteList["border-top"]=true;whiteList["border-top-color"]=true;whiteList["border-top-left-radius"]=true;whiteList["border-top-right-radius"]=true;whiteList["border-top-style"]=true;whiteList["border-top-width"]=true;whiteList["border-width"]=true;whiteList["bottom"]=false;whiteList["box-decoration-break"]=true;whiteList["box-shadow"]=true;whiteList["box-sizing"]=true;whiteList["box-snap"]=true;whiteList["box-suppress"]=true;whiteList["break-after"]=true;whiteList["break-before"]=true;whiteList["break-inside"]=true;whiteList["caption-side"]=false;whiteList["chains"]=false;whiteList["clear"]=true;whiteList["clip"]=false;whiteList["clip-path"]=false;whiteList["clip-rule"]=false;whiteList["color"]=true;whiteList["color-interpolation-filters"]=true;whiteList["column-count"]=false;whiteList["column-fill"]=false;whiteList["column-gap"]=false;whiteList["column-rule"]=false;whiteList["column-rule-color"]=false;whiteList["column-rule-style"]=false;whiteList["column-rule-width"]=false;whiteList["column-span"]=false;whiteList["column-width"]=false;whiteList["columns"]=false;whiteList["contain"]=false;whiteList["content"]=false;whiteList["counter-increment"]=false;whiteList["counter-reset"]=false;whiteList["counter-set"]=false;whiteList["crop"]=false;whiteList["cue"]=false;whiteList["cue-after"]=false;whiteList["cue-before"]=false;whiteList["cursor"]=false;whiteList["direction"]=false;whiteList["display"]=true;whiteList["display-inside"]=true;whiteList["display-list"]=true;whiteList["display-outside"]=true;whiteList["dominant-baseline"]=false;whiteList["elevation"]=false;whiteList["empty-cells"]=false;whiteList["filter"]=false;whiteList["flex"]=false;whiteList["flex-basis"]=false;whiteList["flex-direction"]=false;whiteList["flex-flow"]=false;whiteList["flex-grow"]=false;whiteList["flex-shrink"]=false;whiteList["flex-wrap"]=false;whiteList["float"]=false;whiteList["float-offset"]=false;whiteList["flood-color"]=false;whiteList["flood-opacity"]=false;whiteList["flow-from"]=false;whiteList["flow-into"]=false;whiteList["font"]=true;whiteList["font-family"]=true;whiteList["font-feature-settings"]=true;whiteList["font-kerning"]=true;whiteList["font-language-override"]=true;whiteList["font-size"]=true;whiteList["font-size-adjust"]=true;whiteList["font-stretch"]=true;whiteList["font-style"]=true;whiteList["font-synthesis"]=true;whiteList["font-variant"]=true;whiteList["font-variant-alternates"]=true;whiteList["font-variant-caps"]=true;whiteList["font-variant-east-asian"]=true;whiteList["font-variant-ligatures"]=true;whiteList["font-variant-numeric"]=true;whiteList["font-variant-position"]=true;whiteList["font-weight"]=true;whiteList["grid"]=false;whiteList["grid-area"]=false;whiteList["grid-auto-columns"]=false;whiteList["grid-auto-flow"]=false;whiteList["grid-auto-rows"]=false;whiteList["grid-column"]=false;whiteList["grid-column-end"]=false;whiteList["grid-column-start"]=false;whiteList["grid-row"]=false;whiteList["grid-row-end"]=false;whiteList["grid-row-start"]=false;whiteList["grid-template"]=false;whiteList["grid-template-areas"]=false;whiteList["grid-template-columns"]=false;whiteList["grid-template-rows"]=false;whiteList["hanging-punctuation"]=false;whiteList["height"]=true;whiteList["hyphens"]=false;whiteList["icon"]=false;whiteList["image-orientation"]=false;whiteList["image-resolution"]=false;whiteList["ime-mode"]=false;whiteList["initial-letters"]=false;whiteList["inline-box-align"]=false;whiteList["justify-content"]=false;whiteList["justify-items"]=false;whiteList["justify-self"]=false;whiteList["left"]=false;whiteList["letter-spacing"]=true;whiteList["lighting-color"]=true;whiteList["line-box-contain"]=false;whiteList["line-break"]=false;whiteList["line-grid"]=false;whiteList["line-height"]=false;whiteList["line-snap"]=false;whiteList["line-stacking"]=false;whiteList["line-stacking-ruby"]=false;whiteList["line-stacking-shift"]=false;whiteList["line-stacking-strategy"]=false;whiteList["list-style"]=true;whiteList["list-style-image"]=true;whiteList["list-style-position"]=true;whiteList["list-style-type"]=true;whiteList["margin"]=true;whiteList["margin-bottom"]=true;whiteList["margin-left"]=true;whiteList["margin-right"]=true;whiteList["margin-top"]=true;whiteList["marker-offset"]=false;whiteList["marker-side"]=false;whiteList["marks"]=false;whiteList["mask"]=false;whiteList["mask-box"]=false;whiteList["mask-box-outset"]=false;whiteList["mask-box-repeat"]=false;whiteList["mask-box-slice"]=false;whiteList["mask-box-source"]=false;whiteList["mask-box-width"]=false;whiteList["mask-clip"]=false;whiteList["mask-image"]=false;whiteList["mask-origin"]=false;whiteList["mask-position"]=false;whiteList["mask-repeat"]=false;whiteList["mask-size"]=false;whiteList["mask-source-type"]=false;whiteList["mask-type"]=false;whiteList["max-height"]=true;whiteList["max-lines"]=false;whiteList["max-width"]=true;whiteList["min-height"]=true;whiteList["min-width"]=true;whiteList["move-to"]=false;whiteList["nav-down"]=false;whiteList["nav-index"]=false;whiteList["nav-left"]=false;whiteList["nav-right"]=false;whiteList["nav-up"]=false;whiteList["object-fit"]=false;whiteList["object-position"]=false;whiteList["opacity"]=false;whiteList["order"]=false;whiteList["orphans"]=false;whiteList["outline"]=false;whiteList["outline-color"]=false;whiteList["outline-offset"]=false;whiteList["outline-style"]=false;whiteList["outline-width"]=false;whiteList["overflow"]=false;whiteList["overflow-wrap"]=false;whiteList["overflow-x"]=false;whiteList["overflow-y"]=false;whiteList["padding"]=true;whiteList["padding-bottom"]=true;whiteList["padding-left"]=true;whiteList["padding-right"]=true;whiteList["padding-top"]=true;whiteList["page"]=false;whiteList["page-break-after"]=false;whiteList["page-break-before"]=false;whiteList["page-break-inside"]=false;whiteList["page-policy"]=false;whiteList["pause"]=false;whiteList["pause-after"]=false;whiteList["pause-before"]=false;whiteList["perspective"]=false;whiteList["perspective-origin"]=false;whiteList["pitch"]=false;whiteList["pitch-range"]=false;whiteList["play-during"]=false;whiteList["position"]=false;whiteList["presentation-level"]=false;whiteList["quotes"]=false;whiteList["region-fragment"]=false;whiteList["resize"]=false;whiteList["rest"]=false;whiteList["rest-after"]=false;whiteList["rest-before"]=false;whiteList["richness"]=false;whiteList["right"]=false;whiteList["rotation"]=false;whiteList["rotation-point"]=false;whiteList["ruby-align"]=false;whiteList["ruby-merge"]=false;whiteList["ruby-position"]=false;whiteList["shape-image-threshold"]=false;whiteList["shape-outside"]=false;whiteList["shape-margin"]=false;whiteList["size"]=false;whiteList["speak"]=false;whiteList["speak-as"]=false;whiteList["speak-header"]=false;whiteList["speak-numeral"]=false;whiteList["speak-punctuation"]=false;whiteList["speech-rate"]=false;whiteList["stress"]=false;whiteList["string-set"]=false;whiteList["tab-size"]=false;whiteList["table-layout"]=false;whiteList["text-align"]=true;whiteList["text-align-last"]=true;whiteList["text-combine-upright"]=true;whiteList["text-decoration"]=true;whiteList["text-decoration-color"]=true;whiteList["text-decoration-line"]=true;whiteList["text-decoration-skip"]=true;whiteList["text-decoration-style"]=true;whiteList["text-emphasis"]=true;whiteList["text-emphasis-color"]=true;whiteList["text-emphasis-position"]=true;whiteList["text-emphasis-style"]=true;whiteList["text-height"]=true;whiteList["text-indent"]=true;whiteList["text-justify"]=true;whiteList["text-orientation"]=true;whiteList["text-overflow"]=true;whiteList["text-shadow"]=true;whiteList["text-space-collapse"]=true;whiteList["text-transform"]=true;whiteList["text-underline-position"]=true;whiteList["text-wrap"]=true;whiteList["top"]=false;whiteList["transform"]=false;whiteList["transform-origin"]=false;whiteList["transform-style"]=false;whiteList["transition"]=false;whiteList["transition-delay"]=false;whiteList["transition-duration"]=false;whiteList["transition-property"]=false;whiteList["transition-timing-function"]=false;whiteList["unicode-bidi"]=false;whiteList["vertical-align"]=false;whiteList["visibility"]=false;whiteList["voice-balance"]=false;whiteList["voice-duration"]=false;whiteList["voice-family"]=false;whiteList["voice-pitch"]=false;whiteList["voice-range"]=false;whiteList["voice-rate"]=false;whiteList["voice-stress"]=false;whiteList["voice-volume"]=false;whiteList["volume"]=false;whiteList["white-space"]=false;whiteList["widows"]=false;whiteList["width"]=true;whiteList["will-change"]=false;whiteList["word-break"]=true;whiteList["word-spacing"]=true;whiteList["word-wrap"]=true;whiteList["wrap-flow"]=false;whiteList["wrap-through"]=false;whiteList["writing-mode"]=false;whiteList["z-index"]=false;return whiteList}function onAttr(name,value,options){}function onIgnoreAttr(name,value,options){}var REGEXP_URL_JAVASCRIPT=/javascript\s*\:/gim;function safeAttrValue(name,value){if(REGEXP_URL_JAVASCRIPT.test(value))return"";return value}exports.whiteList=getDefaultWhiteList();exports.getDefaultWhiteList=getDefaultWhiteList;exports.onAttr=onAttr;exports.onIgnoreAttr=onIgnoreAttr;exports.safeAttrValue=safeAttrValue},{}],8:[function(require,module,exports){var DEFAULT=require("./default");var FilterCSS=require("./css");function filterCSS(html,options){var xss=new FilterCSS(options);return xss.process(html)}exports=module.exports=filterCSS;exports.FilterCSS=FilterCSS;for(var i in DEFAULT)exports[i]=DEFAULT[i];if(typeof window!=="undefined"){window.filterCSS=module.exports}},{"./css":6,"./default":7}],9:[function(require,module,exports){var _=require("./util");function parseStyle(css,onAttr){css=_.trimRight(css);if(css[css.length-1]!==";")css+=";";var cssLength=css.length;var isParenthesisOpen=false;var lastPos=0;var i=0;var retCSS="";function addNewAttr(){if(!isParenthesisOpen){var source=_.trim(css.slice(lastPos,i));var j=source.indexOf(":");if(j!==-1){var name=_.trim(source.slice(0,j));var value=_.trim(source.slice(j+1));if(name){var ret=onAttr(lastPos,retCSS.length,name,value,source);if(ret)retCSS+=ret+"; "}}}lastPos=i+1}for(;i - */ - -var xss = require("./"); -var readline = require("readline"); - -var rl = readline.createInterface({ - input: process.stdin, - output: process.stdout -}); - -console.log('Enter a blank line to do xss(), enter "@quit" to exit.\n'); - -function take(c, n) { - var ret = ""; - for (var i = 0; i < n; i++) { - ret += c; - } - return ret; -} - -function setPrompt(line) { - line = line.toString(); - rl.setPrompt("[" + line + "]" + take(" ", 5 - line.length)); - rl.prompt(); -} - -setPrompt(1); - -var html = []; -rl.on("line", function(line) { - if (line === "@quit") return process.exit(); - if (line === "") { - console.log(""); - console.log(xss(html.join("\r\n"))); - console.log(""); - html = []; - } else { - html.push(line); - } - setPrompt(html.length + 1); -}); diff --git a/node_modules/xss/lib/default.js b/node_modules/xss/lib/default.js deleted file mode 100644 index 1452ed3..0000000 --- a/node_modules/xss/lib/default.js +++ /dev/null @@ -1,415 +0,0 @@ -/** - * default settings - * - * @author Zongmin Lei - */ - -var FilterCSS = require("cssfilter").FilterCSS; -var getDefaultCSSWhiteList = require("cssfilter").getDefaultWhiteList; -var _ = require("./util"); - -function getDefaultWhiteList() { - return { - a: ["target", "href", "title"], - abbr: ["title"], - address: [], - area: ["shape", "coords", "href", "alt"], - article: [], - aside: [], - audio: ["autoplay", "controls", "loop", "preload", "src"], - b: [], - bdi: ["dir"], - bdo: ["dir"], - big: [], - blockquote: ["cite"], - br: [], - caption: [], - center: [], - cite: [], - code: [], - col: ["align", "valign", "span", "width"], - colgroup: ["align", "valign", "span", "width"], - dd: [], - del: ["datetime"], - details: ["open"], - div: [], - dl: [], - dt: [], - em: [], - font: ["color", "size", "face"], - footer: [], - h1: [], - h2: [], - h3: [], - h4: [], - h5: [], - h6: [], - header: [], - hr: [], - i: [], - img: ["src", "alt", "title", "width", "height"], - ins: ["datetime"], - li: [], - mark: [], - nav: [], - ol: [], - p: [], - pre: [], - s: [], - section: [], - small: [], - span: [], - sub: [], - sup: [], - strong: [], - table: ["width", "border", "align", "valign"], - tbody: ["align", "valign"], - td: ["width", "rowspan", "colspan", "align", "valign"], - tfoot: ["align", "valign"], - th: ["width", "rowspan", "colspan", "align", "valign"], - thead: ["align", "valign"], - tr: ["rowspan", "align", "valign"], - tt: [], - u: [], - ul: [], - video: ["autoplay", "controls", "loop", "preload", "src", "height", "width"] - }; -} - -var defaultCSSFilter = new FilterCSS(); - -/** - * default onTag function - * - * @param {String} tag - * @param {String} html - * @param {Object} options - * @return {String} - */ -function onTag(tag, html, options) { - // do nothing -} - -/** - * default onIgnoreTag function - * - * @param {String} tag - * @param {String} html - * @param {Object} options - * @return {String} - */ -function onIgnoreTag(tag, html, options) { - // do nothing -} - -/** - * default onTagAttr function - * - * @param {String} tag - * @param {String} name - * @param {String} value - * @return {String} - */ -function onTagAttr(tag, name, value) { - // do nothing -} - -/** - * default onIgnoreTagAttr function - * - * @param {String} tag - * @param {String} name - * @param {String} value - * @return {String} - */ -function onIgnoreTagAttr(tag, name, value) { - // do nothing -} - -/** - * default escapeHtml function - * - * @param {String} html - */ -function escapeHtml(html) { - return html.replace(REGEXP_LT, "<").replace(REGEXP_GT, ">"); -} - -/** - * default safeAttrValue function - * - * @param {String} tag - * @param {String} name - * @param {String} value - * @param {Object} cssFilter - * @return {String} - */ -function safeAttrValue(tag, name, value, cssFilter) { - // unescape attribute value firstly - value = friendlyAttrValue(value); - - if (name === "href" || name === "src") { - // filter `href` and `src` attribute - // only allow the value that starts with `http://` | `https://` | `mailto:` | `/` | `#` - value = _.trim(value); - if (value === "#") return "#"; - if ( - !( - value.substr(0, 7) === "http://" || - value.substr(0, 8) === "https://" || - value.substr(0, 7) === "mailto:" || - value.substr(0, 4) === "tel:" || - value[0] === "#" || - value[0] === "/" - ) - ) { - return ""; - } - } else if (name === "background") { - // filter `background` attribute (maybe no use) - // `javascript:` - REGEXP_DEFAULT_ON_TAG_ATTR_4.lastIndex = 0; - if (REGEXP_DEFAULT_ON_TAG_ATTR_4.test(value)) { - return ""; - } - } else if (name === "style") { - // `expression()` - REGEXP_DEFAULT_ON_TAG_ATTR_7.lastIndex = 0; - if (REGEXP_DEFAULT_ON_TAG_ATTR_7.test(value)) { - return ""; - } - // `url()` - REGEXP_DEFAULT_ON_TAG_ATTR_8.lastIndex = 0; - if (REGEXP_DEFAULT_ON_TAG_ATTR_8.test(value)) { - REGEXP_DEFAULT_ON_TAG_ATTR_4.lastIndex = 0; - if (REGEXP_DEFAULT_ON_TAG_ATTR_4.test(value)) { - return ""; - } - } - if (cssFilter !== false) { - cssFilter = cssFilter || defaultCSSFilter; - value = cssFilter.process(value); - } - } - - // escape `<>"` before returns - value = escapeAttrValue(value); - return value; -} - -// RegExp list -var REGEXP_LT = //g; -var REGEXP_QUOTE = /"/g; -var REGEXP_QUOTE_2 = /"/g; -var REGEXP_ATTR_VALUE_1 = /&#([a-zA-Z0-9]*);?/gim; -var REGEXP_ATTR_VALUE_COLON = /:?/gim; -var REGEXP_ATTR_VALUE_NEWLINE = /&newline;?/gim; -var REGEXP_DEFAULT_ON_TAG_ATTR_3 = /\/\*|\*\//gm; -var REGEXP_DEFAULT_ON_TAG_ATTR_4 = /((j\s*a\s*v\s*a|v\s*b|l\s*i\s*v\s*e)\s*s\s*c\s*r\s*i\s*p\s*t\s*|m\s*o\s*c\s*h\s*a)\:/gi; -var REGEXP_DEFAULT_ON_TAG_ATTR_5 = /^[\s"'`]*(d\s*a\s*t\s*a\s*)\:/gi; -var REGEXP_DEFAULT_ON_TAG_ATTR_6 = /^[\s"'`]*(d\s*a\s*t\s*a\s*)\:\s*image\//gi; -var REGEXP_DEFAULT_ON_TAG_ATTR_7 = /e\s*x\s*p\s*r\s*e\s*s\s*s\s*i\s*o\s*n\s*\(.*/gi; -var REGEXP_DEFAULT_ON_TAG_ATTR_8 = /u\s*r\s*l\s*\(.*/gi; - -/** - * escape doube quote - * - * @param {String} str - * @return {String} str - */ -function escapeQuote(str) { - return str.replace(REGEXP_QUOTE, """); -} - -/** - * unescape double quote - * - * @param {String} str - * @return {String} str - */ -function unescapeQuote(str) { - return str.replace(REGEXP_QUOTE_2, '"'); -} - -/** - * escape html entities - * - * @param {String} str - * @return {String} - */ -function escapeHtmlEntities(str) { - return str.replace(REGEXP_ATTR_VALUE_1, function replaceUnicode(str, code) { - return code[0] === "x" || code[0] === "X" - ? String.fromCharCode(parseInt(code.substr(1), 16)) - : String.fromCharCode(parseInt(code, 10)); - }); -} - -/** - * escape html5 new danger entities - * - * @param {String} str - * @return {String} - */ -function escapeDangerHtml5Entities(str) { - return str - .replace(REGEXP_ATTR_VALUE_COLON, ":") - .replace(REGEXP_ATTR_VALUE_NEWLINE, " "); -} - -/** - * clear nonprintable characters - * - * @param {String} str - * @return {String} - */ -function clearNonPrintableCharacter(str) { - var str2 = ""; - for (var i = 0, len = str.length; i < len; i++) { - str2 += str.charCodeAt(i) < 32 ? " " : str.charAt(i); - } - return _.trim(str2); -} - -/** - * get friendly attribute value - * - * @param {String} str - * @return {String} - */ -function friendlyAttrValue(str) { - str = unescapeQuote(str); - str = escapeHtmlEntities(str); - str = escapeDangerHtml5Entities(str); - str = clearNonPrintableCharacter(str); - return str; -} - -/** - * unescape attribute value - * - * @param {String} str - * @return {String} - */ -function escapeAttrValue(str) { - str = escapeQuote(str); - str = escapeHtml(str); - return str; -} - -/** - * `onIgnoreTag` function for removing all the tags that are not in whitelist - */ -function onIgnoreTagStripAll() { - return ""; -} - -/** - * remove tag body - * specify a `tags` list, if the tag is not in the `tags` list then process by the specify function (optional) - * - * @param {array} tags - * @param {function} next - */ -function StripTagBody(tags, next) { - if (typeof next !== "function") { - next = function() {}; - } - - var isRemoveAllTag = !Array.isArray(tags); - function isRemoveTag(tag) { - if (isRemoveAllTag) return true; - return _.indexOf(tags, tag) !== -1; - } - - var removeList = []; - var posStart = false; - - return { - onIgnoreTag: function(tag, html, options) { - if (isRemoveTag(tag)) { - if (options.isClosing) { - var ret = "[/removed]"; - var end = options.position + ret.length; - removeList.push([ - posStart !== false ? posStart : options.position, - end - ]); - posStart = false; - return ret; - } else { - if (!posStart) { - posStart = options.position; - } - return "[removed]"; - } - } else { - return next(tag, html, options); - } - }, - remove: function(html) { - var rethtml = ""; - var lastPos = 0; - _.forEach(removeList, function(pos) { - rethtml += html.slice(lastPos, pos[0]); - lastPos = pos[1]; - }); - rethtml += html.slice(lastPos); - return rethtml; - } - }; -} - -/** - * remove html comments - * - * @param {String} html - * @return {String} - */ -function stripCommentTag(html) { - return html.replace(STRIP_COMMENT_TAG_REGEXP, ""); -} -var STRIP_COMMENT_TAG_REGEXP = //g; - -/** - * remove invisible characters - * - * @param {String} html - * @return {String} - */ -function stripBlankChar(html) { - var chars = html.split(""); - chars = chars.filter(function(char) { - var c = char.charCodeAt(0); - if (c === 127) return false; - if (c <= 31) { - if (c === 10 || c === 13) return true; - return false; - } - return true; - }); - return chars.join(""); -} - -exports.whiteList = getDefaultWhiteList(); -exports.getDefaultWhiteList = getDefaultWhiteList; -exports.onTag = onTag; -exports.onIgnoreTag = onIgnoreTag; -exports.onTagAttr = onTagAttr; -exports.onIgnoreTagAttr = onIgnoreTagAttr; -exports.safeAttrValue = safeAttrValue; -exports.escapeHtml = escapeHtml; -exports.escapeQuote = escapeQuote; -exports.unescapeQuote = unescapeQuote; -exports.escapeHtmlEntities = escapeHtmlEntities; -exports.escapeDangerHtml5Entities = escapeDangerHtml5Entities; -exports.clearNonPrintableCharacter = clearNonPrintableCharacter; -exports.friendlyAttrValue = friendlyAttrValue; -exports.escapeAttrValue = escapeAttrValue; -exports.onIgnoreTagStripAll = onIgnoreTagStripAll; -exports.StripTagBody = StripTagBody; -exports.stripCommentTag = stripCommentTag; -exports.stripBlankChar = stripBlankChar; -exports.cssFilter = defaultCSSFilter; -exports.getDefaultCSSWhiteList = getDefaultCSSWhiteList; diff --git a/node_modules/xss/lib/index.js b/node_modules/xss/lib/index.js deleted file mode 100644 index e0c1a06..0000000 --- a/node_modules/xss/lib/index.js +++ /dev/null @@ -1,40 +0,0 @@ -/** - * xss - * - * @author Zongmin Lei - */ - -var DEFAULT = require("./default"); -var parser = require("./parser"); -var FilterXSS = require("./xss"); - -/** - * filter xss function - * - * @param {String} html - * @param {Object} options { whiteList, onTag, onTagAttr, onIgnoreTag, onIgnoreTagAttr, safeAttrValue, escapeHtml } - * @return {String} - */ -function filterXSS(html, options) { - var xss = new FilterXSS(options); - return xss.process(html); -} - -exports = module.exports = filterXSS; -exports.filterXSS = filterXSS; -exports.FilterXSS = FilterXSS; -for (var i in DEFAULT) exports[i] = DEFAULT[i]; -for (var i in parser) exports[i] = parser[i]; - -// using `xss` on the browser, output `filterXSS` to the globals -if (typeof window !== "undefined") { - window.filterXSS = module.exports; -} - -// using `xss` on the WebWorker, output `filterXSS` to the globals -function isWorkerEnv() { - return typeof self !== 'undefined' && typeof DedicatedWorkerGlobalScope !== 'undefined' && self instanceof DedicatedWorkerGlobalScope; -} -if (isWorkerEnv()) { - self.filterXSS = module.exports; -} diff --git a/node_modules/xss/lib/parser.js b/node_modules/xss/lib/parser.js deleted file mode 100644 index 7c15def..0000000 --- a/node_modules/xss/lib/parser.js +++ /dev/null @@ -1,239 +0,0 @@ -/** - * Simple HTML Parser - * - * @author Zongmin Lei - */ - -var _ = require("./util"); - -/** - * get tag name - * - * @param {String} html e.g. '' - * @return {String} - */ -function getTagName(html) { - var i = _.spaceIndex(html); - if (i === -1) { - var tagName = html.slice(1, -1); - } else { - var tagName = html.slice(1, i + 1); - } - tagName = _.trim(tagName).toLowerCase(); - if (tagName.slice(0, 1) === "/") tagName = tagName.slice(1); - if (tagName.slice(-1) === "/") tagName = tagName.slice(0, -1); - return tagName; -} - -/** - * is close tag? - * - * @param {String} html 如:'' - * @return {Boolean} - */ -function isClosing(html) { - return html.slice(0, 2) === "") { - rethtml += escapeHtml(html.slice(lastPos, tagStart)); - currentHtml = html.slice(tagStart, currentPos + 1); - currentTagName = getTagName(currentHtml); - rethtml += onTag( - tagStart, - rethtml.length, - currentTagName, - currentHtml, - isClosing(currentHtml) - ); - lastPos = currentPos + 1; - tagStart = false; - continue; - } - if ((c === '"' || c === "'") && html.charAt(currentPos - 1) === "=") { - quoteStart = c; - continue; - } - } else { - if (c === quoteStart) { - quoteStart = false; - continue; - } - } - } - } - if (lastPos < html.length) { - rethtml += escapeHtml(html.substr(lastPos)); - } - - return rethtml; -} - -var REGEXP_ILLEGAL_ATTR_NAME = /[^a-zA-Z0-9_:\.\-]/gim; - -/** - * parse input attributes and returns processed attributes - * - * @param {String} html e.g. `href="#" target="_blank"` - * @param {Function} onAttr e.g. `function (name, value)` - * @return {String} - */ -function parseAttr(html, onAttr) { - "user strict"; - - var lastPos = 0; - var retAttrs = []; - var tmpName = false; - var len = html.length; - - function addAttr(name, value) { - name = _.trim(name); - name = name.replace(REGEXP_ILLEGAL_ATTR_NAME, "").toLowerCase(); - if (name.length < 1) return; - var ret = onAttr(name, value || ""); - if (ret) retAttrs.push(ret); - } - - // 逐个分析字符 - for (var i = 0; i < len; i++) { - var c = html.charAt(i); - var v, j; - if (tmpName === false && c === "=") { - tmpName = html.slice(lastPos, i); - lastPos = i + 1; - continue; - } - if (tmpName !== false) { - if ( - i === lastPos && - (c === '"' || c === "'") && - html.charAt(i - 1) === "=" - ) { - j = html.indexOf(c, i + 1); - if (j === -1) { - break; - } else { - v = _.trim(html.slice(lastPos + 1, j)); - addAttr(tmpName, v); - tmpName = false; - i = j; - lastPos = i + 1; - continue; - } - } - } - if (/\s|\n|\t/.test(c)) { - html = html.replace(/\s|\n|\t/g, " "); - if (tmpName === false) { - j = findNextEqual(html, i); - if (j === -1) { - v = _.trim(html.slice(lastPos, i)); - addAttr(v); - tmpName = false; - lastPos = i + 1; - continue; - } else { - i = j - 1; - continue; - } - } else { - j = findBeforeEqual(html, i - 1); - if (j === -1) { - v = _.trim(html.slice(lastPos, i)); - v = stripQuoteWrap(v); - addAttr(tmpName, v); - tmpName = false; - lastPos = i + 1; - continue; - } else { - continue; - } - } - } - } - - if (lastPos < html.length) { - if (tmpName === false) { - addAttr(html.slice(lastPos)); - } else { - addAttr(tmpName, stripQuoteWrap(_.trim(html.slice(lastPos)))); - } - } - - return _.trim(retAttrs.join(" ")); -} - -function findNextEqual(str, i) { - for (; i < str.length; i++) { - var c = str[i]; - if (c === " ") continue; - if (c === "=") return i; - return -1; - } -} - -function findBeforeEqual(str, i) { - for (; i > 0; i--) { - var c = str[i]; - if (c === " ") continue; - if (c === "=") return i; - return -1; - } -} - -function isQuoteWrapString(text) { - if ( - (text[0] === '"' && text[text.length - 1] === '"') || - (text[0] === "'" && text[text.length - 1] === "'") - ) { - return true; - } else { - return false; - } -} - -function stripQuoteWrap(text) { - if (isQuoteWrapString(text)) { - return text.substr(1, text.length - 2); - } else { - return text; - } -} - -exports.parseTag = parseTag; -exports.parseAttr = parseAttr; diff --git a/node_modules/xss/lib/util.js b/node_modules/xss/lib/util.js deleted file mode 100644 index 1dcd7fa..0000000 --- a/node_modules/xss/lib/util.js +++ /dev/null @@ -1,34 +0,0 @@ -module.exports = { - indexOf: function(arr, item) { - var i, j; - if (Array.prototype.indexOf) { - return arr.indexOf(item); - } - for (i = 0, j = arr.length; i < j; i++) { - if (arr[i] === item) { - return i; - } - } - return -1; - }, - forEach: function(arr, fn, scope) { - var i, j; - if (Array.prototype.forEach) { - return arr.forEach(fn, scope); - } - for (i = 0, j = arr.length; i < j; i++) { - fn.call(scope, arr[i], i, arr); - } - }, - trim: function(str) { - if (String.prototype.trim) { - return str.trim(); - } - return str.replace(/(^\s*)|(\s*$)/g, ""); - }, - spaceIndex: function(str) { - var reg = /\s|\n|\t/; - var match = reg.exec(str); - return match ? match.index : -1; - } -}; diff --git a/node_modules/xss/lib/xss.js b/node_modules/xss/lib/xss.js deleted file mode 100644 index 74d2e42..0000000 --- a/node_modules/xss/lib/xss.js +++ /dev/null @@ -1,211 +0,0 @@ -/** - * filter xss - * - * @author Zongmin Lei - */ - -var FilterCSS = require("cssfilter").FilterCSS; -var DEFAULT = require("./default"); -var parser = require("./parser"); -var parseTag = parser.parseTag; -var parseAttr = parser.parseAttr; -var _ = require("./util"); - -/** - * returns `true` if the input value is `undefined` or `null` - * - * @param {Object} obj - * @return {Boolean} - */ -function isNull(obj) { - return obj === undefined || obj === null; -} - -/** - * get attributes for a tag - * - * @param {String} html - * @return {Object} - * - {String} html - * - {Boolean} closing - */ -function getAttrs(html) { - var i = _.spaceIndex(html); - if (i === -1) { - return { - html: "", - closing: html[html.length - 2] === "/" - }; - } - html = _.trim(html.slice(i + 1, -1)); - var isClosing = html[html.length - 1] === "/"; - if (isClosing) html = _.trim(html.slice(0, -1)); - return { - html: html, - closing: isClosing - }; -} - -/** - * shallow copy - * - * @param {Object} obj - * @return {Object} - */ -function shallowCopyObject(obj) { - var ret = {}; - for (var i in obj) { - ret[i] = obj[i]; - } - return ret; -} - -/** - * FilterXSS class - * - * @param {Object} options - * whiteList, onTag, onTagAttr, onIgnoreTag, - * onIgnoreTagAttr, safeAttrValue, escapeHtml - * stripIgnoreTagBody, allowCommentTag, stripBlankChar - * css{whiteList, onAttr, onIgnoreAttr} `css=false` means don't use `cssfilter` - */ -function FilterXSS(options) { - options = shallowCopyObject(options || {}); - - if (options.stripIgnoreTag) { - if (options.onIgnoreTag) { - console.error( - 'Notes: cannot use these two options "stripIgnoreTag" and "onIgnoreTag" at the same time' - ); - } - options.onIgnoreTag = DEFAULT.onIgnoreTagStripAll; - } - - options.whiteList = options.whiteList || DEFAULT.whiteList; - options.onTag = options.onTag || DEFAULT.onTag; - options.onTagAttr = options.onTagAttr || DEFAULT.onTagAttr; - options.onIgnoreTag = options.onIgnoreTag || DEFAULT.onIgnoreTag; - options.onIgnoreTagAttr = options.onIgnoreTagAttr || DEFAULT.onIgnoreTagAttr; - options.safeAttrValue = options.safeAttrValue || DEFAULT.safeAttrValue; - options.escapeHtml = options.escapeHtml || DEFAULT.escapeHtml; - this.options = options; - - if (options.css === false) { - this.cssFilter = false; - } else { - options.css = options.css || {}; - this.cssFilter = new FilterCSS(options.css); - } -} - -/** - * start process and returns result - * - * @param {String} html - * @return {String} - */ -FilterXSS.prototype.process = function(html) { - // compatible with the input - html = html || ""; - html = html.toString(); - if (!html) return ""; - - var me = this; - var options = me.options; - var whiteList = options.whiteList; - var onTag = options.onTag; - var onIgnoreTag = options.onIgnoreTag; - var onTagAttr = options.onTagAttr; - var onIgnoreTagAttr = options.onIgnoreTagAttr; - var safeAttrValue = options.safeAttrValue; - var escapeHtml = options.escapeHtml; - var cssFilter = me.cssFilter; - - // remove invisible characters - if (options.stripBlankChar) { - html = DEFAULT.stripBlankChar(html); - } - - // remove html comments - if (!options.allowCommentTag) { - html = DEFAULT.stripCommentTag(html); - } - - // if enable stripIgnoreTagBody - var stripIgnoreTagBody = false; - if (options.stripIgnoreTagBody) { - var stripIgnoreTagBody = DEFAULT.StripTagBody( - options.stripIgnoreTagBody, - onIgnoreTag - ); - onIgnoreTag = stripIgnoreTagBody.onIgnoreTag; - } - - var retHtml = parseTag( - html, - function(sourcePosition, position, tag, html, isClosing) { - var info = { - sourcePosition: sourcePosition, - position: position, - isClosing: isClosing, - isWhite: whiteList.hasOwnProperty(tag) - }; - - // call `onTag()` - var ret = onTag(tag, html, info); - if (!isNull(ret)) return ret; - - if (info.isWhite) { - if (info.isClosing) { - return ""; - } - - var attrs = getAttrs(html); - var whiteAttrList = whiteList[tag]; - var attrsHtml = parseAttr(attrs.html, function(name, value) { - // call `onTagAttr()` - var isWhiteAttr = _.indexOf(whiteAttrList, name) !== -1; - var ret = onTagAttr(tag, name, value, isWhiteAttr); - if (!isNull(ret)) return ret; - - if (isWhiteAttr) { - // call `safeAttrValue()` - value = safeAttrValue(tag, name, value, cssFilter); - if (value) { - return name + '="' + value + '"'; - } else { - return name; - } - } else { - // call `onIgnoreTagAttr()` - var ret = onIgnoreTagAttr(tag, name, value, isWhiteAttr); - if (!isNull(ret)) return ret; - return; - } - }); - - // build new tag html - var html = "<" + tag; - if (attrsHtml) html += " " + attrsHtml; - if (attrs.closing) html += " /"; - html += ">"; - return html; - } else { - // call `onIgnoreTag()` - var ret = onIgnoreTag(tag, html, info); - if (!isNull(ret)) return ret; - return escapeHtml(html); - } - }, - escapeHtml - ); - - // if enable stripIgnoreTagBody - if (stripIgnoreTagBody) { - retHtml = stripIgnoreTagBody.remove(retHtml); - } - - return retHtml; -}; - -module.exports = FilterXSS; diff --git a/node_modules/xss/package.json b/node_modules/xss/package.json deleted file mode 100644 index 8caf468..0000000 --- a/node_modules/xss/package.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "_from": "xss", - "_id": "xss@1.0.6", - "_inBundle": false, - "_integrity": "sha512-6Q9TPBeNyoTRxgZFk5Ggaepk/4vUOYdOsIUYvLehcsIZTFjaavbVnsuAkLA5lIFuug5hw8zxcB9tm01gsjph2A==", - "_location": "/xss", - "_phantomChildren": {}, - "_requested": { - "type": "tag", - "registry": true, - "raw": "xss", - "name": "xss", - "escapedName": "xss", - "rawSpec": "", - "saveSpec": null, - "fetchSpec": "latest" - }, - "_requiredBy": [ - "#USER", - "/" - ], - "_resolved": "https://registry.npmjs.org/xss/-/xss-1.0.6.tgz", - "_shasum": "eaf11e9fc476e3ae289944a1009efddd8a124b51", - "_spec": "xss", - "_where": "/home/cargova/projects/beziapp.github.io", - "author": { - "name": "Zongmin Lei", - "email": "leizongmin@gmail.com", - "url": "http://ucdok.com" - }, - "bin": { - "xss": "./bin/xss" - }, - "bugs": { - "url": "https://github.com/leizongmin/js-xss/issues" - }, - "bundleDependencies": false, - "dependencies": { - "commander": "^2.9.0", - "cssfilter": "0.0.10" - }, - "deprecated": false, - "description": "Sanitize untrusted HTML (to prevent XSS) with a configuration specified by a Whitelist", - "devDependencies": { - "browserify": "^14.1.0", - "coveralls": "^3.0.0", - "debug": "^3.1.0", - "istanbul": "^0.4.3", - "mocha": "^4.0.1", - "uglify-js": "^3.0.14" - }, - "engines": { - "node": ">= 0.10.0" - }, - "files": [ - "lib", - "bin/xss", - "dist", - "typings/*.d.ts" - ], - "homepage": "https://github.com/leizongmin/js-xss", - "keywords": [ - "sanitization", - "xss", - "sanitize", - "sanitisation", - "input", - "security", - "escape", - "encode", - "filter", - "validator", - "html", - "injection", - "whitelist" - ], - "license": "MIT", - "main": "./lib/index.js", - "name": "xss", - "repository": { - "type": "git", - "url": "git://github.com/leizongmin/js-xss.git" - }, - "scripts": { - "build": "./bin/build", - "prepublish": "npm run test && npm run build", - "test": "export DEBUG=xss:* && mocha -t 5000", - "test-cov": "export DEBUG=xss:* && istanbul cover _mocha --report lcovonly -- -t 5000 -R spec && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage" - }, - "typings": "./typings/xss.d.ts", - "version": "1.0.6" -} diff --git a/node_modules/xss/typings/xss.d.ts b/node_modules/xss/typings/xss.d.ts deleted file mode 100644 index 1f6f2ca..0000000 --- a/node_modules/xss/typings/xss.d.ts +++ /dev/null @@ -1,189 +0,0 @@ -/** - * xss - * - * @author Zongmin Lei - */ - -declare global { - function filterXSS(html: string, options?: IFilterXSSOptions): string; - - namespace XSS { - export interface IFilterXSSOptions { - whiteList?: IWhiteList; - onTag?: OnTagHandler; - onTagAttr?: OnTagAttrHandler; - onIgnoreTag?: OnTagHandler; - onIgnoreTagAttr?: OnTagAttrHandler; - safeAttrValue?: SafeAttrValueHandler; - escapeHtml?: EscapeHandler; - stripIgnoreTag?: boolean; - stripIgnoreTagBody?: boolean | string[]; - allowCommentTag?: boolean; - stripBlankChar?: boolean; - css?: {} | boolean; - } - - interface IWhiteList { - a?: string[]; - abbr?: string[]; - address?: string[]; - area?: string[]; - article?: string[]; - aside?: string[]; - audio?: string[]; - b?: string[]; - bdi?: string[]; - bdo?: string[]; - big?: string[]; - blockquote?: string[]; - br?: string[]; - caption?: string[]; - center?: string[]; - cite?: string[]; - code?: string[]; - col?: string[]; - colgroup?: string[]; - dd?: string[]; - del?: string[]; - details?: string[]; - div?: string[]; - dl?: string[]; - dt?: string[]; - em?: string[]; - font?: string[]; - footer?: string[]; - h1?: string[]; - h2?: string[]; - h3?: string[]; - h4?: string[]; - h5?: string[]; - h6?: string[]; - header?: string[]; - hr?: string[]; - i?: string[]; - img?: string[]; - ins?: string[]; - li?: string[]; - mark?: string[]; - nav?: string[]; - ol?: string[]; - p?: string[]; - pre?: string[]; - s?: string[]; - section?: string[]; - small?: string[]; - span?: string[]; - sub?: string[]; - sup?: string[]; - strong?: string[]; - table?: string[]; - tbody?: string[]; - td?: string[]; - tfoot?: string[]; - th?: string[]; - thead?: string[]; - tr?: string[]; - tt?: string[]; - u?: string[]; - ul?: string[]; - video?: string[]; - } - - type OnTagHandler = ( - tag: string, - html: string, - options: {} - ) => string | void; - - type OnTagAttrHandler = ( - tag: string, - name: string, - value: string, - isWhiteAttr: boolean - ) => string | void; - - type SafeAttrValueHandler = ( - tag: string, - name: string, - value: string, - cssFilter: ICSSFilter - ) => string; - - type EscapeHandler = (str: string) => string; - - interface ICSSFilter { - process(value: string): string; - } - } -} - -export interface IFilterXSSOptions extends XSS.IFilterXSSOptions {} - -export interface IWhiteList extends XSS.IWhiteList {} - -export type OnTagHandler = XSS.OnTagHandler; - -export type OnTagAttrHandler = XSS.OnTagAttrHandler; - -export type SafeAttrValueHandler = XSS.SafeAttrValueHandler; - -export type EscapeHandler = XSS.EscapeHandler; - -export interface ICSSFilter extends XSS.ICSSFilter {} - -export function StripTagBody( - tags: string[], - next: () => void -): { - onIgnoreTag( - tag: string, - html: string, - options: { - position: number; - isClosing: boolean; - } - ): string; - remove(html: string): string; -}; - -export class FilterXSS { - constructor(options?: IFilterXSSOptions); - process(html: string): string; -} - -export function filterXSS(html: string, options?: IFilterXSSOptions): string; -export function parseTag( - html: string, - onTag: ( - sourcePosition: number, - position: number, - tag: string, - html: string, - isClosing: boolean - ) => string, - escapeHtml: EscapeHandler -): string; -export function parseAttr( - html: string, - onAttr: (name: string, value: string) => string -): string; -export const whiteList: IWhiteList; -export function getDefaultWhiteList(): IWhiteList; -export const onTag: OnTagHandler; -export const onIgnoreTag: OnTagHandler; -export const onTagAttr: OnTagAttrHandler; -export const onIgnoreTagAttr: OnTagAttrHandler; -export const safeAttrValue: SafeAttrValueHandler; -export const escapeHtml: EscapeHandler; -export const escapeQuote: EscapeHandler; -export const unescapeQuote: EscapeHandler; -export const escapeHtmlEntities: EscapeHandler; -export const escapeDangerHtml5Entities: EscapeHandler; -export const clearNonPrintableCharacter: EscapeHandler; -export const friendlyAttrValue: EscapeHandler; -export const escapeAttrValue: EscapeHandler; -export function onIgnoreTagStripAll(): string; -export const stripCommentTag: EscapeHandler; -export const stripBlankChar: EscapeHandler; -export const cssFilter: ICSSFilter; -export function getDefaultCSSWhiteList(): ICSSFilter; -- cgit v1.2.3