Components.utils.evalInSandbox 编辑
Introduction
在某些情况下, 你希望将 JavaScript代码限定在可靠的执行环境 . 在Firefox 1.5 (Gecko 1.8) or 之后的版本, 有这么个API允许你去干这件事. 这里引入了“沙箱”的概念,你可以在沙箱中创建和执行代码. 这些代码的执行将会受到沙箱的限制,就像在一个普通的网页中一样。
Use
要使用 evalInSandbox()
, 你得先使用构造函数创建一个沙箱对象。 Components.utils.Sandbox
. 该沙箱必须使用origin URI 或者最好使用 DOM window (nsIDOMWindow, 就像网页中的 window
对象一样)来初始化. 在 Firefox 3 (Gecko 1.9) 及以后的版本, 你也可以通过 nsIPrincipal
对象来初始化. 使用 nsIPrincipal
比使用 origin URI更好。出于对安全的考虑, URI, window, or nsIPrincipal
会被当成"源" (e.g. 就像同源安全检测)。比如,传入一个 URI http://www.example.com/
,将允许沙箱中的代码从该地址创建AJAX请求。如果沙箱中的代码设置了 document.domain
, 那将会修改同源检测,你可以传递一个 DOM window 对象 or nsIPrincipal
给沙箱的构造函数,而不是URI。
咱们看一个关于 URI的例子:
// 通过 URI 创建沙箱 var s = Components.utils.Sandbox("http://www.example.com/");
这段代码创建了一个空的沙箱。 当你这么操作的时候 evalInSandbox(text, sandbox),
它将作为一个全局对象存在。
如果想在其中添加其他对象,看下面这个例子:
s.y = 5; // 添加属性 'y'值为 5 到全局范围 var result = Components.utils.evalInSandbox("x = y + 2; x + 3", s); // result is 10, s.x is now 7
这就是个普通操作,也干不了什么坏事:
s.foo = Components; // 报错 "Permission Denied" Components.utils.evalInSandbox("foo.classes", s);
另一方面, 沙箱中的任何函数都能够像chrome中的代码一样执行。你可以在下一节看到好几种骚操作。
Note bug 350558.
Security
安全警告: 当你使用evalInSandbox()
的时候,如果你依赖沙箱中执行代码返回的对象属性时,会冒出一些潜在的安全问题。比如 :
<script src="prototype.js"></script> <script> var s = new Components.utils.Sandbox(url); var x = Components.utils.evalInSandbox(untrusted_code, s); if (x == 1) { /* 调用x.valueOf() 不安全 */ } if (x === 1) { /* this code is safe */ } var y = x.y; /* this is unsafe */ var z = sandbox.z; /* unsafe */ if (typeof x == "number") { /* safe */ } </script>
我们来看看安全问题是怎么产生的, 上面例子 (x == 1)
。x.valueOf()
方法执行的时候会通过chrome code 来调用。这个时候,不安全的代码就可以在chrome code 全局范围创造一个String对象。
如果该chrome code 已经添加了具有chrome 某些方法的控制权,比如:String.prototype
, Object.prototype
, or Function.prototype
,不安全的代码就能够滥用这些。不安全代码能够做什么,取决于这些方法是什么。不管怎么样,不安全代码最终都能以chrome的权限来执行。
想要避免潜在安全隐患,你需要非常小心避免使用从evalInSandbox()
返回的对象,还有,你需要确保那些不受信任的JSON串在使用 evalInSandbox() 的时候不包括任何方法和表达式。
See also: PiggyBank analysis of sandbox
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论