javascript函数对象的实例是否不可变
我说函数对象的实例是不可变的,因为我们无法在函数创建后修改它,对吗 无论如何,我要重新表述我的问题:javascript函数对象的实例是否不可变,javascript,web-services,security,Javascript,Web Services,Security,我说函数对象的实例是不可变的,因为我们无法在函数创建后修改它,对吗 无论如何,我要重新表述我的问题: var f1=function(){ return true; } //Now i pass **f1** into the function **G**, storing it to **g1** function G(f){ return function(){ return f(); } }
var f1=function(){
return true;
}
//Now i pass **f1** into the function **G**, storing it to **g1**
function G(f){
return function(){
return f();
}
}
var g1=G(f1);
//I will try to hack/do anything i can to **f1**
//Now i will pass f1 to hacked piece of injection code which (assumingly) will try to hack f1
g1(); // but I can be 100% sure this will still return me true
因此,现在我可以确定,无论我对f1做了什么,g1()都将永远返回给我真的
尽管我对占互联网用户市场份额至少0.5%的浏览器感兴趣,但我还是欢迎类似于“在[x]浏览器中,这是不安全的,因为……”这样的回答
我知道,由于代码是在客户端运行的,如果客户端有恶意意图,他将能够做任何他想做的事情。。但这个问题专门针对保护“没有恶意意图的用户”,换句话说。。一个普通用户(如果用户是黑客,我不介意让他随意乱动函数,因为他会把所有异常都扔到脸上,这不关我的事)不:
var f = new Function("");
f.prop = 1;
无法阻止在所有浏览器上重新分配变量
g1
。某些浏览器允许您将g1
定义为:
这将防止名称g1
反弹,您可以使用Object.defineProperty
在其他对象上定义window
的全局属性,但通常JavaScript中没有const
定义
为了更清楚,考虑两种情况:
(1) 攻击者可以在声明f1
的范围内运行代码,然后其他代码读取f1
var f1 = ...; // You define f1
f1 = function () { return false; }; // Attacker code runs
doSomethingWith(f1()); // Naive code reads f1 and calls it.
在这种情况下,攻击者成功地混淆了原始代码,因为他们更改了f1
处的值
var f1 = ...; // You define f1
f1 = function () { return false; }; // Attacker code runs
doSomethingWith(f1()); // Naive code reads f1 and calls it.
(2) 攻击者在读取f1
后在作用域中运行代码
var f1 = ...; // You define f1
// Cautious code reads and stores f1 in a safe place for later use.
(function () {
var f = f1;
setTimeout(0, function () { doSomethingWith(f()); });
})();
f1 = function () { return false; }; // Attacker code runs.
在这种情况下,攻击者失败,因为在攻击者更改存储在
f1
的值之前,谨慎的代码读取了f1
的值,因此,私有f
继续返回true
您是指函数体还是对象的属性?@Jeremy Heiler我编辑了这个问题,您的代码在调用g1()
时会出错,因为g1
是true
。我想你的意思是让G
be返回f代码>。无论哪种方式,您所做的只是传递f1
,因此,在本例中,对它的任何更改都将反映在任何位置。但是,我认为在函数声明之后没有合法的方法来更改函数体。这还取决于函数是否引用了它外部的任何内容。@Jeremy Heiler不,函数不引用外部的任何内容。所以基本上我们可以100%确定功能体不能被触碰?@Pacerier:我知道的唯一方法是用一个新功能完全替换功能体。由于g1
现在包含了对f1
中函数的引用,因此替换f1
的主体并不重要。这就是我现在所能说的,我当然没有资格说我百分之百肯定不会有其他事情发生。我不想承担责任:-代码中的严重错误。。我已经编辑了我的问题:它不是您假设的代码。。但是:函数G(f){return function(){return f;}}
@Pacerier,删除了关于G的定义,因为它看起来像是你的新定义可以满足你的需要。这篇文章的其余部分,关于如何使名称g1
始终指向同一个函数实例(模屏蔽)仍然是相关的。因此,即使我将名为f1
的函数实例传递到攻击者的脚本中,他可以做他想做的任何事,但是在他的脚本结束时,我仍然可以调用f1
,并说它将100%返回true?@Pacerier,如果你通过f1()
调用f1
,它要么接受零个参数,要么不调用任何参数,那么它仍然会给你true
。显然,如果您定义一个函数调用它的一个参数var h1=function(f,x){return f(x);}
并将其传递给攻击者,那么攻击者可以通过执行h1(eval,“h1=function(){…}”)
重命名h1
。您应该始终怀疑此
的值,因为攻击者可以像控制任何其他参数一样轻松地控制它。并且您应该小心在传递给攻击者的任何函数的代码中存储机密;您不希望f.toString()
返回类似function(){var privateKey=“…”;…}
的内容。