考虑这个伪代码:
(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)中运行而不会有太多麻烦?如果这是不可能的,那么我只会耸耸肩继续前进。
答案 0 :(得分:2)
如果有人想要操纵此代码(恶意用户) 例如,他会用自己的
重写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不再在活动页面的范围内执行脚本。
因此...
如果不可能,那我就耸耸肩继续前进。
你应该。
答案 1 :(得分:1)
我不会说我是这方面的专家。但假设您可以完全包装代码并使用事件来触发行为,您可以使用如下结构:
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()
方法和任何其他内部方法都受到保护。< / p>
如果你的init方法声明了一些对应用程序的事件绑定,你可以用这种方式保持你的状态私有。事件将能够触发内部方法,因为它们从内部闭包内部绑定,但外部代码将看不到它们。
虽然这可能会解决您的问题,但我并不是百分之百确定它,不管怎么说都不值得信任。只要安全性在客户端,任何想要渗透您的应用程序的用户都可以。无论如何,ES5或没有ES5,没有什么可以阻止他们制作自己的对象来替换你的。
对于任何实际需要安全的内容,您必须在服务器端重新验证。永远不要相信客户端代码来保护您,请求可能甚至不会来自您提供的页面......
答案 2 :(得分:0)
如果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模型
BTW:在您的代码中,window.instance
将是undefined
。