有没有办法防止覆盖/覆盖单例实例中的函数/变量
Is there any way to prevent override/overwrite of functions/variables in singleton instance?
考虑这个伪代码:
(function(window){
var options = { /*where everything goes */ };
var instance = (function(options){
for (var i in options){
if (options.hasOwnProperty(i)){
this[i] = options[i];
}
}
})(options);
instance.callbacks = function(cb){
//...
}
instance.is_allowed = function()
//... checks, return boolean
}
window.instance = instance;
})(this);
如果有人想操纵这段代码(例如恶意用户),他会用自己的代码重写is_allowed
函数,例如,使用地址栏(他没有火虫,谁知道呢)。
javascript:(function(){ window.instance.is_allowed = function(){ return true; } })();
这是一个幼稚的例子,但这就是重点,Javascript中的任何内容都可以被覆盖。
我知道在 es5 中我们有 Object.defineProperty,所以你可以设置:
// being explicit
Object.defineProperty(instance, "is_allowed", {
enumerable: false,
configurable: false,
writable: false,
value: function(){
// do checks
}
});
实际上,从这个意义上说,最好的是使用 Object.freeze(instance)
或 Object.seal(instance)
而不是 Object.defineProperty
,因为后者可以用 writable: false
再次调用(傻吧?
有什么方法可以在旧浏览器(即IE6-8)中工作而不会有太多麻烦?如果不可能,那么我会耸耸肩继续前进。
如果有人想要操纵此代码(恶意用户 示例),他会用自己的函数重写is_allowed函数
他可以重写你的整个javascript代码,甚至不使用浏览器,而是模拟对你的服务器的"无浏览器"请求。
有没有办法在旧浏览器(即IE6-8)中工作,而没有 太麻烦了?
不。您全局公开的任何内容都可以由用户更改,这取决于浏览器限制javascript:
行为,以避免用户被愚弄访问预先制作的链接。Firefox最近对javascript URL协议进行了某种更改。
正如本文所述: http://survey-remover.com/blog/javascript-protocol-dangers/
从Chrome v13,Firefox v6和IE 9开始,浏览器开发人员已经注意到"javascript:"协议的危险,并随后禁止代码...在Chrome和IE的情况下,"javascript:"子字符串在粘贴代码时被剥离,而Firefox不再在活动页面范围内执行脚本。
所以。。。
如果不可能,那么我会耸耸肩继续前进。
你应该。
提案
我不会说我是这些事情的专家。但是假设您可以完全包装代码并使用事件来触发行为,您可以使用如下结构:
Closed = function(args) { return (function() {
"use strict";
var secret, init, get_secret, use_secret;
init = function(something){
secret = something;
};
get_secret = function() {
return secret;
};
use_secret = function () {
console.log(secret);
};
/* Run constructor */
init(args);
/* Publish API */
return { use_secret:use_secret };
}())};
使用obj = Closed("Anything");
设置它,您仍然可以让恶意用户覆盖 use_secret()
方法,因为它是公开的,但 get_secret()
方法和任何其他内部都受到保护。
如果您的 init 方法向应用程序声明了许多事件绑定,则可以通过这种方式保持状态私有。这些事件将能够触发内部方法,因为它们从内部闭包内部绑定,但外部代码不会看到它们。
保留
虽然这可能会解决您的问题,但我不能 100% 确定它确实如此,无论如何它都不值得信任。任何想要渗透您的应用程序的用户都可以,只要安全性在客户端。无论如何,没有什么可以阻止他们制作自己的对象来替换你的对象,ES5 或没有 ES5。
对于任何实际需要安全的东西,您都必须在服务器端重新验证。永远不要相信客户端代码来保护您,请求甚至可能不是来自您服务的页面......
如果is_allowed
完全是本地的呢?
(function(window){
var options = {}, is_allowed;
var instance = (function(options){
for (var i in options) {
if (options.hasOwnProperty(i)) {
this[i] = options[i];
}
}
return this;
})(options);
instance.callbacks = function(cb){
/* ... */
};
function check_allowed(){
/* check and let this function set [is_allowed] */
};
window.instance = check_allowed()
? instance
: { callbacks: function(){(alert('not allowed'));} };
} (this) );
jsBin 样机
顺便说一句:在您的代码中,window.instance
会undefined
.
- 覆盖函数中的函数
- 如何在javascript中覆盖函数的行为
- Javascript闭包覆盖函数表达式
- 具有生成名称的 Javascript 覆盖函数
- 在节点导出中覆盖函数的 toString()
- for 循环中的覆盖函数
- 在 JavaScript 中扩展或覆盖函数
- 覆盖函数(例如“alert”)并调用原始函数
- Javascript覆盖函数
- 如何在javascript中使用原型覆盖函数
- 覆盖/覆盖函数内部的函数
- JavaScript - 使用包含异步回调但仍返回原始值的函数覆盖函数
- Javascript 闭包 - 全局范围内被覆盖函数的行为
- 如何在javascript中用可变数量的参数覆盖函数
- 如果a或b = null或无值,则…填充最后一个字段将覆盖函数
- 保持添加值而不覆盖函数
- JS模块模式覆盖函数
- Javascript模块-覆盖函数
- 覆盖函数以识别任何dom更改,包括像jquery这样的插件
- 来自dataTableExt.oApi的数据表覆盖函数