Skip to content

Commit 1255447

Browse files
committed
fixed xss bug
1 parent 98e698b commit 1255447

7 files changed

Lines changed: 165 additions & 6 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
node_modules
22
dist
3-
asp/upload
3+
asp/upload
4+
.vscode

_examples/editor_api.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
'plugins/autosave.js',
4040
'plugins/autoupload.js',
4141
'plugins/formula.js',
42+
'plugins/xssFilter.js',
4243
'ui/widget.js',
4344
'ui/button.js',
4445
'ui/toolbar.js',

_src/plugins/link.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ UM.plugins['link'] = function(){
5757

5858
this.addOutputRule(function(root){
5959
$.each(root.getNodesByTagName('a'),function(i,a){
60-
var _href = utils.html(a.getAttr('_href'));
60+
var _href = a.getAttr('_href');
6161
if(!/^(ftp|https?|\/|file)/.test(_href)){
6262
_href = 'http://' + _href;
6363
}
@@ -70,21 +70,23 @@ UM.plugins['link'] = function(){
7070
});
7171
this.addInputRule(function(root){
7272
$.each(root.getNodesByTagName('a'),function(i,a){
73-
a.setAttr('_href', utils.html(a.getAttr('href')));
73+
a.setAttr('_href', a.getAttr('href'));
7474
})
7575
});
7676
me.commands['link'] = {
7777
execCommand : function( cmdName, opt ) {
7878

7979
var me = this;
8080
var rng = me.selection.getRange();
81+
opt._href && (opt._href = utils.unhtml(opt._href, /[<">'](?:(amp|lt|quot|gt|#39|nbsp);)?/g));
82+
opt.href && (opt.href = utils.unhtml(opt.href, /[<">'](?:(amp|lt|quot|gt|#39|nbsp);)?/g));
8183
if(rng.collapsed){
8284
var start = rng.startContainer;
8385
if(start = domUtils.findParentByTagName(start,'a',true)){
8486
$(start).attr(opt);
8587
rng.selectNode(start).select()
8688
}else{
87-
rng.insertNode($('<a>' +opt.href+'</a>').attr(opt)[0]).select()
89+
rng.insertNode($('<a>' + opt.href +'</a>').attr(opt)[0]).select()
8890

8991
}
9092

_src/plugins/video.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ UM.plugins['video'] = function (){
5252
var html = [],id = 'tmpVedio';
5353
for(var i=0,vi,len = videoObjs.length;i<len;i++){
5454
vi = videoObjs[i];
55+
vi.url = utils.unhtml(vi.url, /[<">'](?:(amp|lt|quot|gt|#39|nbsp);)?/g);
5556
html.push(creatInsertStr( vi.url, vi.width || 420, vi.height || 280, id + i,vi.align,false));
5657
}
5758
me.execCommand("inserthtml",html.join(""),true);

_src/plugins/xssFilter.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/**
2+
* @file xssFilter.js
3+
* @desc xss过滤器
4+
* @author robbenmu
5+
*/
6+
7+
UM.plugins.xssFilter = function() {
8+
9+
var config = UMEDITOR_CONFIG;
10+
var whiteList = config.whiteList;
11+
12+
function filter(node) {
13+
14+
var tagName = node.tagName;
15+
var attrs = node.attrs;
16+
17+
if (!whiteList.hasOwnProperty(tagName)) {
18+
node.parentNode.removeChild(node);
19+
return false;
20+
}
21+
22+
UM.utils.each(attrs, function (val, key) {
23+
24+
if (whiteList[tagName].indexOf(key) === -1) {
25+
node.setAttr(key);
26+
}
27+
});
28+
}
29+
30+
// 添加inserthtml\paste等操作用的过滤规则
31+
if (whiteList && config.xssFilterRules) {
32+
this.options.filterRules = function () {
33+
34+
var result = {};
35+
36+
UM.utils.each(whiteList, function(val, key) {
37+
result[key] = function (node) {
38+
return filter(node);
39+
};
40+
});
41+
42+
return result;
43+
}();
44+
}
45+
46+
var tagList = [];
47+
48+
UM.utils.each(whiteList, function (val, key) {
49+
tagList.push(key);
50+
});
51+
52+
// 添加input过滤规则
53+
//
54+
if (whiteList && config.inputXssFilter) {
55+
this.addInputRule(function (root) {
56+
57+
root.traversal(function(node) {
58+
if (node.type !== 'element') {
59+
return false;
60+
}
61+
filter(node);
62+
});
63+
});
64+
}
65+
// 添加output过滤规则
66+
//
67+
if (whiteList && config.outputXssFilter) {
68+
this.addOutputRule(function (root) {
69+
70+
root.traversal(function(node) {
71+
if (node.type !== 'element') {
72+
return false;
73+
}
74+
filter(node);
75+
});
76+
});
77+
}
78+
79+
};

_src/ui/widget.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//对jquery的扩展
33
$.parseTmpl = function parse(str, data) {
44
var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' + 'with(obj||{}){__p.push(\'' + str.replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/<%=([\s\S]+?)%>/g,function (match, code) {
5-
return "'," + code.replace(/\\'/g, "'") + ",'";
5+
return "',obj." + code.replace(/\\'/g, "'") + ",'";
66
}).replace(/<%([\s\S]+?)%>/g,function (match, code) {
77
return "');" + code.replace(/\\'/g, "'").replace(/[\r\n\t]/g, ' ') + "__p.push('";
88
}).replace(/\r/g, '\\r').replace(/\n/g, '\\n').replace(/\t/g, '\\t') + "');}return __p.join('');";

umeditor.config.js

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,81 @@
244244
//,topOffset:30
245245

246246
//填写过滤规则
247-
//,filterRules: {}
247+
,filterRules: {}
248+
// xss 过滤是否开启,inserthtml等操作
249+
,xssFilterRules: true
250+
//input xss过滤
251+
,inputXssFilter: true
252+
//output xss过滤
253+
,outputXssFilter: true
254+
// xss过滤白名单 名单来源: https://raw.githubusercontent.com/leizongmin/js-xss/master/lib/default.js
255+
,whiteList: {
256+
a: ['target', 'href', 'title', 'style', 'class', 'id'],
257+
abbr: ['title', 'style', 'class', 'id'],
258+
address: ['style', 'class', 'id'],
259+
area: ['shape', 'coords', 'href', 'alt', 'style', 'class', 'id'],
260+
article: ['style', 'class', 'id'],
261+
aside: ['style', 'class', 'id'],
262+
audio: ['autoplay', 'controls', 'loop', 'preload', 'src', 'style', 'class', 'id'],
263+
b: ['style', 'class', 'id'],
264+
bdi: ['dir'],
265+
bdo: ['dir'],
266+
big: [],
267+
blockquote: ['cite', 'style', 'class', 'id'],
268+
br: [],
269+
caption: ['style', 'class', 'id'],
270+
center: [],
271+
cite: [],
272+
code: ['style', 'class', 'id'],
273+
col: ['align', 'valign', 'span', 'width', 'style', 'class', 'id'],
274+
colgroup: ['align', 'valign', 'span', 'width', 'style', 'class', 'id'],
275+
dd: ['style', 'class', 'id'],
276+
del: ['datetime', 'style', 'class', 'id'],
277+
details: ['open', 'style', 'class', 'id'],
278+
div: ['style', 'class', 'id'],
279+
dl: ['style', 'class', 'id'],
280+
dt: ['style', 'class', 'id'],
281+
em: ['style', 'class', 'id'],
282+
embed: ['style', 'class', 'id', '_url', 'type', 'pluginspage', 'src', 'width', 'height', 'wmode', 'play', 'loop', 'menu', 'allowscriptaccess', 'allowfullscreen'],
283+
font: ['color', 'size', 'face', 'style', 'class', 'id'],
284+
footer: ['style', 'class', 'id'],
285+
h1: ['style', 'class', 'id'],
286+
h2: ['style', 'class', 'id'],
287+
h3: ['style', 'class', 'id'],
288+
h4: ['style', 'class', 'id'],
289+
h5: ['style', 'class', 'id'],
290+
h6: ['style', 'class', 'id'],
291+
header: ['style', 'class', 'id'],
292+
hr: ['style', 'class', 'id'],
293+
i: ['style', 'class', 'id'],
294+
iframe: ['style', 'class', 'id', 'src', 'frameborder', 'data-latex'],
295+
img: ['src', 'alt', 'title', 'width', 'height', 'style', 'class', 'id', '_url'],
296+
ins: ['datetime', 'style', 'class', 'id'],
297+
li: ['style', 'class', 'id'],
298+
mark: [],
299+
nav: [],
300+
ol: ['style', 'class', 'id'],
301+
p: ['style', 'class', 'id'],
302+
pre: ['style', 'class', 'id'],
303+
s: [],
304+
section:[],
305+
small: ['style', 'class', 'id'],
306+
span: ['style', 'class', 'id'],
307+
sub: ['style', 'class', 'id'],
308+
sup: ['style', 'class', 'id'],
309+
strong: ['style', 'class', 'id'],
310+
table: ['width', 'border', 'align', 'valign', 'style', 'class', 'id'],
311+
tbody: ['align', 'valign', 'style', 'class', 'id'],
312+
td: ['width', 'rowspan', 'colspan', 'align', 'valign', 'style', 'class', 'id'],
313+
tfoot: ['align', 'valign', 'style', 'class', 'id'],
314+
th: ['width', 'rowspan', 'colspan', 'align', 'valign', 'style', 'class', 'id'],
315+
thead: ['align', 'valign', 'style', 'class', 'id'],
316+
tr: ['rowspan', 'align', 'valign', 'style', 'class', 'id'],
317+
tt: ['style', 'class', 'id'],
318+
u: [],
319+
ul: ['style', 'class', 'id'],
320+
svg: ['style', 'class', 'id', 'width', 'height', 'xmlns', 'fill', 'viewBox'],
321+
video: ['autoplay', 'controls', 'loop', 'preload', 'src', 'height', 'width', 'style', 'class', 'id']
322+
}
248323
};
249324
})();

0 commit comments

Comments
 (0)