在 JavaScript 中呈现一个安全的 HTML 子集
Render a safe HTML subset in JavaScript
作为markdown的替代方案,我正在寻找一种在JavaScript中安全地解析HTML的可配置子集的方法。
例如,对于 (不受信任的) 输入
<b onclick="alert('XSS');" data-myapp="asdf" style="color:red">Hello</b>
<h1><i style="color:expression(alert('XSS'));"> World</i></h1>
使用参数
allowTags: b, i
allowAttrs: data-myapp
allowSafeStyle: color
我期待输出
<b data-myapp="asdf" style="color:red">Hello</b>
<i> World</i>
Markdown似乎无法表达更复杂的属性。Caja 似乎非常接近我想要的,但需要服务器端渲染。那么,如何在 JavaScript 中渲染一个安全的(根据上述参数allowTags
、allowAttrs
等)HTML 子集呢?
我使用 jQuery 来缩短我的答案并包含更少的样板代码,但它不相关。
我正在使用.innerHTML
因为它不会在 html 中执行可能的脚本或 css。
演示在这里 http://jsfiddle.net/QCaGq/
function filterData(data, options ){
var root;
try {
root = document.implementation.createHTMLDocument().body;
}
catch(e) {
root = document.createElement("body");
}
root.innerHTML = data;
$(root).find("*").filter(function(){
return options.allowTags.indexOf(this.tagName.toLowerCase()) === -1;
}).each( function() {
$(this).children().detach().insertBefore( this );
$(this).remove();
});
function removeStyle( node, attr ) {
var style = node.style,
prop,
name,
len = style.length,
i, val = "";
for( i = 0; i < len; ++i ) {
name = style[i];
prop = style[name];
if( options.allowSafeStyle.indexOf( name ) > -1 ) {
val += (name + ":" + prop + ";");
}
}
if( val ) {
attr.nodeValue = val;
}
else {
node.removeAttribute("style");
}
}
function removeAttrs( node ) {
$.each( node.attributes, function( index, attr ) {
if( !attr ) {
return;
}
if( attr.name.toLowerCase() === "style" ) {
return removeStyle( node, attr );
}
if( options.allowAttrs.indexOf(attr.name.toLowerCase()) === -1 ) {
node.removeAttribute(attr.name);
}
});
}
function walk( root ) {
removeAttrs(root);
$( root.childNodes ).each( function() {
if( this.nodeType === 8 ) { //Remove html comments
$(this).remove();
}
else if( this.nodeType === 1 ) {
walk(this);
}
});
}
walk(root);
return root.innerHTML;
}
var opts = {
allowTags: ["b", "i"],
allowAttrs: ["data-myapp"],
allowSafeStyle: ["color"]
}
filterData( '<b onclick="alert(''XSS'');" data-myapp="asdf" style="color:red">Hello</b>'n<h1><i style="color:expression(alert(''XSS''));"> World</i></h1>', opts );
结果:
<b data-myapp="asdf" style="color:red;">Hello</b>
<i> World</i>
这应该让你开始。
相关文章:
- 是一个javascript bookmarklet,可以设置破坏跨域安全的域cookie
- 构建一个HTML小部件来嵌入付费内容-如何确保与后端的通信安全
- 为什么我不能强制下载受污染的画布,为什么这是一个安全问题
- 让用户通过javascript访问cookie是一个安全问题
- json 一个 html 的安全方法
- 在 JavaScript 中呈现一个安全的 HTML 子集
- 安全问题是将我的访问者带到一个危险的下载页面
- 从前一个事务的完整回调开始打开新的 IndexedDb 事务是否安全
- 是一个经过SSL处理的JSONAPI,它使用cookie进行身份验证,并且随机数通常是安全的
- 如何在没有安全警告的情况下将一个 html 加载到另一个 html 中
- 在一个简单的网站上违反了内容安全策略指令
- 在express.js中创建一个安全的POST链接
- 如何让Javascript客户端创建一个安全的UUID
- 如何创建一个安全的PHP &;javascript api
- 如何将一个安全的、仅限http的cookie作为承载令牌呈现(不使用Angular.JS)
- 使用innerHTML插入内容不执行