rootaccessxvv-bbmarker 0.0.1-security → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rootaccessxvv-bbmarker might be problematic. Click here for more details.
- package/README.md +13 -3
- package/index.js +1 -0
- package/package.json +18 -6
- package/sim/node_modules/.bin/xss +16 -0
- package/sim/node_modules/.bin/xss.cmd +17 -0
- package/sim/node_modules/.bin/xss.ps1 +28 -0
- package/sim/node_modules/.package-lock.json +36 -0
- package/sim/node_modules/commander/CHANGELOG.md +419 -0
- package/sim/node_modules/commander/LICENSE +22 -0
- package/sim/node_modules/commander/Readme.md +428 -0
- package/sim/node_modules/commander/index.js +1224 -0
- package/sim/node_modules/commander/package.json +38 -0
- package/sim/node_modules/commander/typings/index.d.ts +310 -0
- package/sim/node_modules/cssfilter/LICENSE +22 -0
- package/sim/node_modules/cssfilter/README.md +86 -0
- package/sim/node_modules/cssfilter/lib/css.js +110 -0
- package/sim/node_modules/cssfilter/lib/default.js +398 -0
- package/sim/node_modules/cssfilter/lib/index.js +32 -0
- package/sim/node_modules/cssfilter/lib/parser.js +74 -0
- package/sim/node_modules/cssfilter/lib/util.js +35 -0
- package/sim/node_modules/cssfilter/package.json +49 -0
- package/sim/node_modules/xss/CHANGELOG.md +24 -0
- package/sim/node_modules/xss/LICENSE +23 -0
- package/sim/node_modules/xss/README.md +505 -0
- package/sim/node_modules/xss/README.zh.md +491 -0
- package/sim/node_modules/xss/bin/xss +67 -0
- package/sim/node_modules/xss/dist/test.html +15 -0
- package/sim/node_modules/xss/dist/xss.js +1665 -0
- package/sim/node_modules/xss/dist/xss.min.js +1 -0
- package/sim/node_modules/xss/lib/cli.js +45 -0
- package/sim/node_modules/xss/lib/default.js +459 -0
- package/sim/node_modules/xss/lib/index.js +44 -0
- package/sim/node_modules/xss/lib/parser.js +247 -0
- package/sim/node_modules/xss/lib/util.js +34 -0
- package/sim/node_modules/xss/lib/xss.js +211 -0
- package/sim/node_modules/xss/package.json +63 -0
- package/sim/node_modules/xss/typings/xss.d.ts +202 -0
- package/sim/package-lock.json +44 -0
- package/sim/package.json +16 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple HTML Parser
|
|
3
|
+
*
|
|
4
|
+
* @author Zongmin Lei<leizongmin@gmail.com>
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
var _ = require("./util");
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* get tag name
|
|
11
|
+
*
|
|
12
|
+
* @param {String} html e.g. '<a hef="#">'
|
|
13
|
+
* @return {String}
|
|
14
|
+
*/
|
|
15
|
+
function getTagName(html) {
|
|
16
|
+
var i = _.spaceIndex(html);
|
|
17
|
+
if (i === -1) {
|
|
18
|
+
var tagName = html.slice(1, -1);
|
|
19
|
+
} else {
|
|
20
|
+
var tagName = html.slice(1, i + 1);
|
|
21
|
+
}
|
|
22
|
+
tagName = _.trim(tagName).toLowerCase();
|
|
23
|
+
if (tagName.slice(0, 1) === "/") tagName = tagName.slice(1);
|
|
24
|
+
if (tagName.slice(-1) === "/") tagName = tagName.slice(0, -1);
|
|
25
|
+
return tagName;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* is close tag?
|
|
30
|
+
*
|
|
31
|
+
* @param {String} html 如:'<a hef="#">'
|
|
32
|
+
* @return {Boolean}
|
|
33
|
+
*/
|
|
34
|
+
function isClosing(html) {
|
|
35
|
+
return html.slice(0, 2) === "</";
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* parse input html and returns processed html
|
|
40
|
+
*
|
|
41
|
+
* @param {String} html
|
|
42
|
+
* @param {Function} onTag e.g. function (sourcePosition, position, tag, html, isClosing)
|
|
43
|
+
* @param {Function} escapeHtml
|
|
44
|
+
* @return {String}
|
|
45
|
+
*/
|
|
46
|
+
function parseTag(html, onTag, escapeHtml) {
|
|
47
|
+
"use strict";
|
|
48
|
+
|
|
49
|
+
var rethtml = "";
|
|
50
|
+
var lastPos = 0;
|
|
51
|
+
var tagStart = false;
|
|
52
|
+
var quoteStart = false;
|
|
53
|
+
var currentPos = 0;
|
|
54
|
+
var len = html.length;
|
|
55
|
+
var currentTagName = "";
|
|
56
|
+
var currentHtml = "";
|
|
57
|
+
|
|
58
|
+
chariterator: for (currentPos = 0; currentPos < len; currentPos++) {
|
|
59
|
+
var c = html.charAt(currentPos);
|
|
60
|
+
if (tagStart === false) {
|
|
61
|
+
if (c === "<") {
|
|
62
|
+
tagStart = currentPos;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
if (quoteStart === false) {
|
|
67
|
+
if (c === "<") {
|
|
68
|
+
rethtml += escapeHtml(html.slice(lastPos, currentPos));
|
|
69
|
+
tagStart = currentPos;
|
|
70
|
+
lastPos = currentPos;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (c === ">") {
|
|
74
|
+
rethtml += escapeHtml(html.slice(lastPos, tagStart));
|
|
75
|
+
currentHtml = html.slice(tagStart, currentPos + 1);
|
|
76
|
+
currentTagName = getTagName(currentHtml);
|
|
77
|
+
rethtml += onTag(
|
|
78
|
+
tagStart,
|
|
79
|
+
rethtml.length,
|
|
80
|
+
currentTagName,
|
|
81
|
+
currentHtml,
|
|
82
|
+
isClosing(currentHtml)
|
|
83
|
+
);
|
|
84
|
+
lastPos = currentPos + 1;
|
|
85
|
+
tagStart = false;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (c === '"' || c === "'") {
|
|
89
|
+
var i = 1;
|
|
90
|
+
var ic = html.charAt(currentPos - i);
|
|
91
|
+
|
|
92
|
+
while (ic.trim() === "" || ic === "=") {
|
|
93
|
+
if (ic === "=") {
|
|
94
|
+
quoteStart = c;
|
|
95
|
+
continue chariterator;
|
|
96
|
+
}
|
|
97
|
+
ic = html.charAt(currentPos - ++i);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
if (c === quoteStart) {
|
|
102
|
+
quoteStart = false;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (lastPos < html.length) {
|
|
109
|
+
rethtml += escapeHtml(html.substr(lastPos));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return rethtml;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
var REGEXP_ILLEGAL_ATTR_NAME = /[^a-zA-Z0-9_:\.\-]/gim;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* parse input attributes and returns processed attributes
|
|
119
|
+
*
|
|
120
|
+
* @param {String} html e.g. `href="#" target="_blank"`
|
|
121
|
+
* @param {Function} onAttr e.g. `function (name, value)`
|
|
122
|
+
* @return {String}
|
|
123
|
+
*/
|
|
124
|
+
function parseAttr(html, onAttr) {
|
|
125
|
+
"use strict";
|
|
126
|
+
|
|
127
|
+
var lastPos = 0;
|
|
128
|
+
var retAttrs = [];
|
|
129
|
+
var tmpName = false;
|
|
130
|
+
var len = html.length;
|
|
131
|
+
|
|
132
|
+
function addAttr(name, value) {
|
|
133
|
+
name = _.trim(name);
|
|
134
|
+
name = name.replace(REGEXP_ILLEGAL_ATTR_NAME, "").toLowerCase();
|
|
135
|
+
if (name.length < 1) return;
|
|
136
|
+
var ret = onAttr(name, value || "");
|
|
137
|
+
if (ret) retAttrs.push(ret);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// 逐个分析字符
|
|
141
|
+
for (var i = 0; i < len; i++) {
|
|
142
|
+
var c = html.charAt(i);
|
|
143
|
+
var v, j;
|
|
144
|
+
if (tmpName === false && c === "=") {
|
|
145
|
+
tmpName = html.slice(lastPos, i);
|
|
146
|
+
lastPos = i + 1;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (tmpName !== false) {
|
|
150
|
+
if (
|
|
151
|
+
i === lastPos &&
|
|
152
|
+
(c === '"' || c === "'") &&
|
|
153
|
+
html.charAt(i - 1) === "="
|
|
154
|
+
) {
|
|
155
|
+
j = html.indexOf(c, i + 1);
|
|
156
|
+
if (j === -1) {
|
|
157
|
+
break;
|
|
158
|
+
} else {
|
|
159
|
+
v = _.trim(html.slice(lastPos + 1, j));
|
|
160
|
+
addAttr(tmpName, v);
|
|
161
|
+
tmpName = false;
|
|
162
|
+
i = j;
|
|
163
|
+
lastPos = i + 1;
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (/\s|\n|\t/.test(c)) {
|
|
169
|
+
html = html.replace(/\s|\n|\t/g, " ");
|
|
170
|
+
if (tmpName === false) {
|
|
171
|
+
j = findNextEqual(html, i);
|
|
172
|
+
if (j === -1) {
|
|
173
|
+
v = _.trim(html.slice(lastPos, i));
|
|
174
|
+
addAttr(v);
|
|
175
|
+
tmpName = false;
|
|
176
|
+
lastPos = i + 1;
|
|
177
|
+
continue;
|
|
178
|
+
} else {
|
|
179
|
+
i = j - 1;
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
} else {
|
|
183
|
+
j = findBeforeEqual(html, i - 1);
|
|
184
|
+
if (j === -1) {
|
|
185
|
+
v = _.trim(html.slice(lastPos, i));
|
|
186
|
+
v = stripQuoteWrap(v);
|
|
187
|
+
addAttr(tmpName, v);
|
|
188
|
+
tmpName = false;
|
|
189
|
+
lastPos = i + 1;
|
|
190
|
+
continue;
|
|
191
|
+
} else {
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (lastPos < html.length) {
|
|
199
|
+
if (tmpName === false) {
|
|
200
|
+
addAttr(html.slice(lastPos));
|
|
201
|
+
} else {
|
|
202
|
+
addAttr(tmpName, stripQuoteWrap(_.trim(html.slice(lastPos))));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return _.trim(retAttrs.join(" "));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function findNextEqual(str, i) {
|
|
210
|
+
for (; i < str.length; i++) {
|
|
211
|
+
var c = str[i];
|
|
212
|
+
if (c === " ") continue;
|
|
213
|
+
if (c === "=") return i;
|
|
214
|
+
return -1;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function findBeforeEqual(str, i) {
|
|
219
|
+
for (; i > 0; i--) {
|
|
220
|
+
var c = str[i];
|
|
221
|
+
if (c === " ") continue;
|
|
222
|
+
if (c === "=") return i;
|
|
223
|
+
return -1;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function isQuoteWrapString(text) {
|
|
228
|
+
if (
|
|
229
|
+
(text[0] === '"' && text[text.length - 1] === '"') ||
|
|
230
|
+
(text[0] === "'" && text[text.length - 1] === "'")
|
|
231
|
+
) {
|
|
232
|
+
return true;
|
|
233
|
+
} else {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function stripQuoteWrap(text) {
|
|
239
|
+
if (isQuoteWrapString(text)) {
|
|
240
|
+
return text.substr(1, text.length - 2);
|
|
241
|
+
} else {
|
|
242
|
+
return text;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
exports.parseTag = parseTag;
|
|
247
|
+
exports.parseAttr = parseAttr;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
indexOf: function (arr, item) {
|
|
3
|
+
var i, j;
|
|
4
|
+
if (Array.prototype.indexOf) {
|
|
5
|
+
return arr.indexOf(item);
|
|
6
|
+
}
|
|
7
|
+
for (i = 0, j = arr.length; i < j; i++) {
|
|
8
|
+
if (arr[i] === item) {
|
|
9
|
+
return i;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return -1;
|
|
13
|
+
},
|
|
14
|
+
forEach: function (arr, fn, scope) {
|
|
15
|
+
var i, j;
|
|
16
|
+
if (Array.prototype.forEach) {
|
|
17
|
+
return arr.forEach(fn, scope);
|
|
18
|
+
}
|
|
19
|
+
for (i = 0, j = arr.length; i < j; i++) {
|
|
20
|
+
fn.call(scope, arr[i], i, arr);
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
trim: function (str) {
|
|
24
|
+
if (String.prototype.trim) {
|
|
25
|
+
return str.trim();
|
|
26
|
+
}
|
|
27
|
+
return str.replace(/(^\s*)|(\s*$)/g, "");
|
|
28
|
+
},
|
|
29
|
+
spaceIndex: function (str) {
|
|
30
|
+
var reg = /\s|\n|\t/;
|
|
31
|
+
var match = reg.exec(str);
|
|
32
|
+
return match ? match.index : -1;
|
|
33
|
+
},
|
|
34
|
+
};
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* filter xss
|
|
3
|
+
*
|
|
4
|
+
* @author Zongmin Lei<leizongmin@gmail.com>
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
var FilterCSS = require("cssfilter").FilterCSS;
|
|
8
|
+
var DEFAULT = require("./default");
|
|
9
|
+
var parser = require("./parser");
|
|
10
|
+
var parseTag = parser.parseTag;
|
|
11
|
+
var parseAttr = parser.parseAttr;
|
|
12
|
+
var _ = require("./util");
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* returns `true` if the input value is `undefined` or `null`
|
|
16
|
+
*
|
|
17
|
+
* @param {Object} obj
|
|
18
|
+
* @return {Boolean}
|
|
19
|
+
*/
|
|
20
|
+
function isNull(obj) {
|
|
21
|
+
return obj === undefined || obj === null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* get attributes for a tag
|
|
26
|
+
*
|
|
27
|
+
* @param {String} html
|
|
28
|
+
* @return {Object}
|
|
29
|
+
* - {String} html
|
|
30
|
+
* - {Boolean} closing
|
|
31
|
+
*/
|
|
32
|
+
function getAttrs(html) {
|
|
33
|
+
var i = _.spaceIndex(html);
|
|
34
|
+
if (i === -1) {
|
|
35
|
+
return {
|
|
36
|
+
html: "",
|
|
37
|
+
closing: html[html.length - 2] === "/",
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
html = _.trim(html.slice(i + 1, -1));
|
|
41
|
+
var isClosing = html[html.length - 1] === "/";
|
|
42
|
+
if (isClosing) html = _.trim(html.slice(0, -1));
|
|
43
|
+
return {
|
|
44
|
+
html: html,
|
|
45
|
+
closing: isClosing,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* shallow copy
|
|
51
|
+
*
|
|
52
|
+
* @param {Object} obj
|
|
53
|
+
* @return {Object}
|
|
54
|
+
*/
|
|
55
|
+
function shallowCopyObject(obj) {
|
|
56
|
+
var ret = {};
|
|
57
|
+
for (var i in obj) {
|
|
58
|
+
ret[i] = obj[i];
|
|
59
|
+
}
|
|
60
|
+
return ret;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* FilterXSS class
|
|
65
|
+
*
|
|
66
|
+
* @param {Object} options
|
|
67
|
+
* whiteList, onTag, onTagAttr, onIgnoreTag,
|
|
68
|
+
* onIgnoreTagAttr, safeAttrValue, escapeHtml
|
|
69
|
+
* stripIgnoreTagBody, allowCommentTag, stripBlankChar
|
|
70
|
+
* css{whiteList, onAttr, onIgnoreAttr} `css=false` means don't use `cssfilter`
|
|
71
|
+
*/
|
|
72
|
+
function FilterXSS(options) {
|
|
73
|
+
options = shallowCopyObject(options || {});
|
|
74
|
+
|
|
75
|
+
if (options.stripIgnoreTag) {
|
|
76
|
+
if (options.onIgnoreTag) {
|
|
77
|
+
console.error(
|
|
78
|
+
'Notes: cannot use these two options "stripIgnoreTag" and "onIgnoreTag" at the same time'
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
options.onIgnoreTag = DEFAULT.onIgnoreTagStripAll;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
options.whiteList = options.whiteList || DEFAULT.whiteList;
|
|
85
|
+
options.onTag = options.onTag || DEFAULT.onTag;
|
|
86
|
+
options.onTagAttr = options.onTagAttr || DEFAULT.onTagAttr;
|
|
87
|
+
options.onIgnoreTag = options.onIgnoreTag || DEFAULT.onIgnoreTag;
|
|
88
|
+
options.onIgnoreTagAttr = options.onIgnoreTagAttr || DEFAULT.onIgnoreTagAttr;
|
|
89
|
+
options.safeAttrValue = options.safeAttrValue || DEFAULT.safeAttrValue;
|
|
90
|
+
options.escapeHtml = options.escapeHtml || DEFAULT.escapeHtml;
|
|
91
|
+
this.options = options;
|
|
92
|
+
|
|
93
|
+
if (options.css === false) {
|
|
94
|
+
this.cssFilter = false;
|
|
95
|
+
} else {
|
|
96
|
+
options.css = options.css || {};
|
|
97
|
+
this.cssFilter = new FilterCSS(options.css);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* start process and returns result
|
|
103
|
+
*
|
|
104
|
+
* @param {String} html
|
|
105
|
+
* @return {String}
|
|
106
|
+
*/
|
|
107
|
+
FilterXSS.prototype.process = function (html) {
|
|
108
|
+
// compatible with the input
|
|
109
|
+
html = html || "";
|
|
110
|
+
html = html.toString();
|
|
111
|
+
if (!html) return "";
|
|
112
|
+
|
|
113
|
+
var me = this;
|
|
114
|
+
var options = me.options;
|
|
115
|
+
var whiteList = options.whiteList;
|
|
116
|
+
var onTag = options.onTag;
|
|
117
|
+
var onIgnoreTag = options.onIgnoreTag;
|
|
118
|
+
var onTagAttr = options.onTagAttr;
|
|
119
|
+
var onIgnoreTagAttr = options.onIgnoreTagAttr;
|
|
120
|
+
var safeAttrValue = options.safeAttrValue;
|
|
121
|
+
var escapeHtml = options.escapeHtml;
|
|
122
|
+
var cssFilter = me.cssFilter;
|
|
123
|
+
|
|
124
|
+
// remove invisible characters
|
|
125
|
+
if (options.stripBlankChar) {
|
|
126
|
+
html = DEFAULT.stripBlankChar(html);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// remove html comments
|
|
130
|
+
if (!options.allowCommentTag) {
|
|
131
|
+
html = DEFAULT.stripCommentTag(html);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// if enable stripIgnoreTagBody
|
|
135
|
+
var stripIgnoreTagBody = false;
|
|
136
|
+
if (options.stripIgnoreTagBody) {
|
|
137
|
+
var stripIgnoreTagBody = DEFAULT.StripTagBody(
|
|
138
|
+
options.stripIgnoreTagBody,
|
|
139
|
+
onIgnoreTag
|
|
140
|
+
);
|
|
141
|
+
onIgnoreTag = stripIgnoreTagBody.onIgnoreTag;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
var retHtml = parseTag(
|
|
145
|
+
html,
|
|
146
|
+
function (sourcePosition, position, tag, html, isClosing) {
|
|
147
|
+
var info = {
|
|
148
|
+
sourcePosition: sourcePosition,
|
|
149
|
+
position: position,
|
|
150
|
+
isClosing: isClosing,
|
|
151
|
+
isWhite: whiteList.hasOwnProperty(tag),
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
// call `onTag()`
|
|
155
|
+
var ret = onTag(tag, html, info);
|
|
156
|
+
if (!isNull(ret)) return ret;
|
|
157
|
+
|
|
158
|
+
if (info.isWhite) {
|
|
159
|
+
if (info.isClosing) {
|
|
160
|
+
return "</" + tag + ">";
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
var attrs = getAttrs(html);
|
|
164
|
+
var whiteAttrList = whiteList[tag];
|
|
165
|
+
var attrsHtml = parseAttr(attrs.html, function (name, value) {
|
|
166
|
+
// call `onTagAttr()`
|
|
167
|
+
var isWhiteAttr = _.indexOf(whiteAttrList, name) !== -1;
|
|
168
|
+
var ret = onTagAttr(tag, name, value, isWhiteAttr);
|
|
169
|
+
if (!isNull(ret)) return ret;
|
|
170
|
+
|
|
171
|
+
if (isWhiteAttr) {
|
|
172
|
+
// call `safeAttrValue()`
|
|
173
|
+
value = safeAttrValue(tag, name, value, cssFilter);
|
|
174
|
+
if (value) {
|
|
175
|
+
return name + '="' + value + '"';
|
|
176
|
+
} else {
|
|
177
|
+
return name;
|
|
178
|
+
}
|
|
179
|
+
} else {
|
|
180
|
+
// call `onIgnoreTagAttr()`
|
|
181
|
+
var ret = onIgnoreTagAttr(tag, name, value, isWhiteAttr);
|
|
182
|
+
if (!isNull(ret)) return ret;
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// build new tag html
|
|
188
|
+
var html = "<" + tag;
|
|
189
|
+
if (attrsHtml) html += " " + attrsHtml;
|
|
190
|
+
if (attrs.closing) html += " /";
|
|
191
|
+
html += ">";
|
|
192
|
+
return html;
|
|
193
|
+
} else {
|
|
194
|
+
// call `onIgnoreTag()`
|
|
195
|
+
var ret = onIgnoreTag(tag, html, info);
|
|
196
|
+
if (!isNull(ret)) return ret;
|
|
197
|
+
return escapeHtml(html);
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
escapeHtml
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
// if enable stripIgnoreTagBody
|
|
204
|
+
if (stripIgnoreTagBody) {
|
|
205
|
+
retHtml = stripIgnoreTagBody.remove(retHtml);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return retHtml;
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
module.exports = FilterXSS;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "xss",
|
|
3
|
+
"main": "./lib/index.js",
|
|
4
|
+
"typings": "./typings/xss.d.ts",
|
|
5
|
+
"version": "1.0.10",
|
|
6
|
+
"description": "Sanitize untrusted HTML (to prevent XSS) with a configuration specified by a Whitelist",
|
|
7
|
+
"author": "Zongmin Lei <leizongmin@gmail.com> (http://ucdok.com)",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git://github.com/leizongmin/js-xss.git"
|
|
11
|
+
},
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": ">= 0.10.0"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"commander": "^2.20.3",
|
|
17
|
+
"cssfilter": "0.0.10"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"browserify": "^17.0.0",
|
|
21
|
+
"coveralls": "^3.1.0",
|
|
22
|
+
"debug": "^4.1.1",
|
|
23
|
+
"mocha": "^8.3.2",
|
|
24
|
+
"nyc": "^15.1.0",
|
|
25
|
+
"uglify-js": "^3.9.4"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"lib",
|
|
29
|
+
"bin/xss",
|
|
30
|
+
"dist",
|
|
31
|
+
"typings/*.d.ts"
|
|
32
|
+
],
|
|
33
|
+
"bin": {
|
|
34
|
+
"xss": "./bin/xss"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"test": "export DEBUG=xss:* && mocha -t 5000",
|
|
38
|
+
"test-cov": "nyc --reporter=lcov mocha --exit \"test/*.js\" && nyc report",
|
|
39
|
+
"coveralls": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js",
|
|
40
|
+
"build": "./bin/build",
|
|
41
|
+
"prepublish": "npm run test && npm run build"
|
|
42
|
+
},
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/leizongmin/js-xss/issues"
|
|
46
|
+
},
|
|
47
|
+
"homepage": "https://github.com/leizongmin/js-xss",
|
|
48
|
+
"keywords": [
|
|
49
|
+
"sanitization",
|
|
50
|
+
"xss",
|
|
51
|
+
"sanitize",
|
|
52
|
+
"sanitisation",
|
|
53
|
+
"input",
|
|
54
|
+
"security",
|
|
55
|
+
"escape",
|
|
56
|
+
"encode",
|
|
57
|
+
"filter",
|
|
58
|
+
"validator",
|
|
59
|
+
"html",
|
|
60
|
+
"injection",
|
|
61
|
+
"whitelist"
|
|
62
|
+
]
|
|
63
|
+
}
|