kol*_*kol 6 javascript information-hiding eval global-variables
我通常认为全局范围是一个总是可以从任何地方访问的命名空间.我想知道理论上是否有可能完全隐藏全球范围.例如,假设我们有一些我们想要的代码eval
(在浏览器的控制台中):
var code =
"console.log(this); " + // access the global object directly
"console.log(window); " + // access the global object as the window object
"newGlobalVar = 42; "; // implicitly create global object
eval(code);
Run Code Online (Sandbox Code Playgroud)
通过包装eval
调用,this
并window
可以从隐藏code
:
(function (window) { eval(code); }).call({});
Run Code Online (Sandbox Code Playgroud)
但我无法阻止code
隐式创建全局变量.有可能吗?我不想用这些东西,我只是好奇.
小智 6
如果你在相当现代的浏览器中运行,你可以window
通过创建一个用参数遮蔽window
和self
变量的函数来阻止访问,并以严格模式运行代码.
var obj = {};
var func = new Function("self", "window", "'use strict';" + code);
func.call(obj, obj, obj);
console.log(obj); // see if there were any attempts to set global variables.
Run Code Online (Sandbox Code Playgroud)
任何访问window
或self
将只访问我们的obj
对象的尝试,其价值this
也将是我们的obj
.
因为我们处于严格模式,所以不允许使用隐式全局变量.此外,this
函数的默认值将undefined
代替window
.
我认为有一些黑客可能会解决这个问题,但这应该涵盖大多数情况.
注意:这仍然是一项正在进行中的工作,部分受到了眯眼的代码片段的启发。
function quarantinedFunction(fnText){
var exceptionKeys=[
"eval","Object", //need exceptions for this else error. (ie, 'Exception: redefining eval is deprecated')
"Number","String","Boolean","RegExp","JSON","Date",
];
var forbiddenKeys=[
"fn","fnText","forbiddenKeys","exceptionKeys","empty","oForbiddenKeys",
];
var oForbiddenKeys=Object.create(null);
var empty=Object.create(null);
Object.freeze(empty);
forbiddenKeys.forEach(function(key){
oForbiddenKeys[key]=null;
});
[this,self].forEach(function(obj){
Object.getOwnPropertyNames(obj).forEach(function(key){
if(!key.match(/^[\$\w]+$/))return;
oForbiddenKeys[key]=null;
});
});
exceptionKeys.forEach(function(key){
delete oForbiddenKeys[key];
});
if(0){//debugging.
return function(){
return Object.keys(oForbiddenKeys);
return Object.keys(empty);
};
}
fnText=[
'"use strict";',
"var "+Object.keys(oForbiddenKeys).join(", ")+";",
"{",
fnText,
"}"
].join("\n");
var fn= (function(){
with(empty)
{
return new Function("self","window",fnText);
}
})();
return function(){
return fn.call(Object.create(null)); //self,window undefined
return fn.call(empty,empty,empty); //self,window are objects w/o properties
};
}
Run Code Online (Sandbox Code Playgroud)
输出结果(来自 Firefox 暂存器):
quarantinedFunction("return location.href;")();
/*
Exception: location is undefined
*/
quarantinedFunction("someGlobalVar=15;")();
/*
Exception: assignment to undeclared variable someGlobalVar
*/
quarantinedFunction("return 9*9;")();
/*
81
*/
quarantinedFunction("return console;")();
/*
undefined
*/
Run Code Online (Sandbox Code Playgroud)
和一些结果的jsfiddle。
注意:一些意外的结果出现在 fiddle 中,但没有出现在其他工具中(即,location
当从 firefox aurora 查看 fiddle 时,变量返回页面的 url,但不是在 chrome 上,也不是在 Scratchpad devtool 上——可能是 Firefox__noSuchMethod__
或类似工具的手工作品“后期绑定”机制,导致仅在访问时添加属性)。
归档时间: |
|
查看次数: |
3888 次 |
最近记录: |