From 1888d11307e6efa264a354aba725207abcf78e1d Mon Sep 17 00:00:00 2001 From: robbenmu Date: Fri, 13 May 2016 11:27:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0xssfileter=E8=BF=87=E6=BB=A4?= =?UTF-8?q?=E5=99=A8=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _examples/editor_api.js | 10 ++-- _src/plugins/xssFilter.js | 79 +++++++++++++++++++++++++++++ ueditor.config.js | 101 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 181 insertions(+), 9 deletions(-) mode change 100644 => 100755 _examples/editor_api.js create mode 100644 _src/plugins/xssFilter.js mode change 100644 => 100755 ueditor.config.js diff --git a/_examples/editor_api.js b/_examples/editor_api.js old mode 100644 new mode 100755 index 54b81bdf1..fc0bba4ce --- a/_examples/editor_api.js +++ b/_examples/editor_api.js @@ -89,8 +89,9 @@ 'plugins/section.js', 'plugins/simpleupload.js', 'plugins/serverparam.js', - 'plugins/insertfile.js', - 'ui/ui.js', + 'plugins/insertfile.js', + 'plugins/xssFilter.js', + 'ui/ui.js', 'ui/uiutils.js', 'ui/uibase.js', 'ui/separator.js', @@ -119,9 +120,8 @@ 'adapter/editorui.js', 'adapter/editor.js', 'adapter/message.js', - 'adapter/autosave.js' - - ], + 'adapter/autosave.js' + ], baseURL = '../_src/'; for (var i=0,pi;pi = paths[i++];) { document.write(''); diff --git a/_src/plugins/xssFilter.js b/_src/plugins/xssFilter.js new file mode 100644 index 000000000..39665eff1 --- /dev/null +++ b/_src/plugins/xssFilter.js @@ -0,0 +1,79 @@ +/** + * @file xssFilter.js + * @desc xss过滤器 + * @author robbenmu + */ + +UE.plugins.xssFilter = function() { + + var config = UEDITOR_CONFIG; + var whitList = config.whitList; + + function filter(node) { + + var tagName = node.tagName; + var attrs = node.attrs; + + if (!whitList.hasOwnProperty(tagName)) { + node.parentNode.removeChild(node); + return false; + } + + UE.utils.each(attrs, function (val, key) { + + if (whitList[tagName].indexOf(key) === -1) { + node.setAttr(key); + } + }); + } + + // 添加inserthtml\paste等操作用的过滤规则 + if (whitList && config.xssFilterRules) { + this.options.filterRules = function () { + + var result = {}; + + UE.utils.each(whitList, function(val, key) { + result[key] = function (node) { + return filter(node); + }; + }); + + return result; + }(); + } + + var tagList = []; + + UE.utils.each(whitList, function (val, key) { + tagList.push(key); + }); + + // 添加input过滤规则 + // + if (whitList && config.inputXssFilter) { + this.addInputRule(function (root) { + + root.traversal(function(node) { + if (node.type !== 'element') { + return false; + } + filter(node); + }); + }); + } + // 添加output过滤规则 + // + if (whitList && config.outputXssFilter) { + this.addOutputRule(function (root) { + + root.traversal(function(node) { + if (node.type !== 'element') { + return false; + } + filter(node); + }); + }); + } + +}; diff --git a/ueditor.config.js b/ueditor.config.js old mode 100644 new mode 100755 index 44782639b..c34f6dccf --- a/ueditor.config.js +++ b/ueditor.config.js @@ -32,7 +32,7 @@ // 服务器统一请求接口路径 , serverUrl: URL + "php/controller.php" - //工具栏上的所有的功能按钮和下拉框,可以在new编辑器的实例时选择自己需要的从新定义 + //工具栏上的所有的功能按钮和下拉框,可以在new编辑器的实例时选择自己需要的重新定义 , toolbars: [[ 'fullscreen', 'source', '|', 'undo', 'redo', '|', 'bold', 'italic', 'underline', 'fontborder', 'strikethrough', 'superscript', 'subscript', 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', 'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist', 'selectall', 'cleardoc', '|', @@ -44,7 +44,7 @@ 'simpleupload', 'insertimage', 'emotion', 'scrawl', 'insertvideo', 'music', 'attachment', 'map', 'gmap', 'insertframe', 'insertcode', 'webapp', 'pagebreak', 'template', 'background', '|', 'horizontal', 'date', 'time', 'spechars', 'snapscreen', 'wordimage', '|', 'inserttable', 'deletetable', 'insertparagraphbeforetable', 'insertrow', 'deleterow', 'insertcol', 'deletecol', 'mergecells', 'mergeright', 'mergedown', 'splittocells', 'splittorows', 'splittocols', 'charts', '|', - 'print', 'preview', 'searchreplace', 'help', 'drafts' + 'print', 'preview', 'searchreplace', 'drafts', 'help' ]] //当鼠标放在工具栏上时显示的tooltip提示,留空支持自动多语言配置,否则以配置值为准 //,labelMap:{ @@ -83,7 +83,8 @@ //如果自定义,最好给p标签如下的行高,要不输入中文时,会有跳动感 //,initialStyle:'p{line-height:1em}'//编辑器层级的基数,可以用来改变字体等 - //,iframeCssUrl: URL + '/themes/iframe.css' //给编辑器内部引入一个css文件 + //,iframeJsUrl: '' //给编辑区域的iframe引入一个js文件 + //,iframeCssUrl: URL + '/themes/iframe.css' //给编辑区域的iframe引入一个css文件 //indentValue //首行缩进距离,默认是2em @@ -101,6 +102,14 @@ //自动保存间隔时间, 单位ms //,saveInterval: 500 + //启用拖放上传 + //,enableDragUpload: true + //启用粘贴上传 + //,enablePasteUpload: true + + //启用图片拉伸缩放 + //,imageScaleEnabled: true + //,fullscreen : false //是否开启初始化时即全屏,默认关闭 //,imagePopup:true //图片操作的浮层开关,默认打开 @@ -293,6 +302,9 @@ //编辑器底部距离工具栏高度(如果参数大于等于编辑器高度,则设置无效) //,toolbarTopOffset:400 + //设置远程图片是否抓取到本地保存 + //,catchRemoteImageEnable: true //设置是否抓取远程图片 + //pageBreakTag //分页标识符,默认是_ueditor_page_break_tag_ //,pageBreakTag:'_ueditor_page_break_tag_' @@ -321,7 +333,7 @@ //表格是否可以拖拽 //,tableDragable: true - //,disabledTableInTable:true //禁止表格嵌套 + //sourceEditor //源码的查看方式,codemirror 是代码高亮,textarea是文本框,默认是codemirror @@ -341,8 +353,89 @@ // 'anchor':'~/dialogs/anchor/anchor.html', //} + //allowLinkProtocol 允许的链接地址,有这些前缀的链接地址不会自动添加http + //, allowLinkProtocols: ['http:', 'https:', '#', '/', 'ftp:', 'mailto:', 'tel:', 'git:', 'svn:'] + //webAppKey 百度应用的APIkey,每个站长必须首先去百度官网注册一个key后方能正常使用app功能,注册介绍,http://app.baidu.com/static/cms/getapikey.html //, webAppKey: "" + + //默认过滤规则相关配置项目 + //,disabledTableInTable:true //禁止表格嵌套 + //,allowDivTransToP:true //允许进入编辑器的div标签自动变成p标签 + //,rgb2Hex:true //默认产出的数据中的color自动从rgb格式变成16进制格式 + + // xss 过滤是否开启,inserthtml等操作 + ,xssFilterRules: true + //input xss过滤 + ,inputXssFilter: true + //output xss过滤 + ,outputXssFilter: true + // xss过滤白名单 名单来源: https://raw.githubusercontent.com/leizongmin/js-xss/master/lib/default.js + ,whitList: { + 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'] + } }; function getUEBasePath(docUrl, confUrl) {