From 33058f2b292b3a581333bdfb21b8f671898c5060 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:40:17 -0500 Subject: initial commit --- .../components.utils.evalinsandbox/index.html | 80 ++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 files/zh-cn/components.utils.evalinsandbox/index.html (limited to 'files/zh-cn/components.utils.evalinsandbox/index.html') diff --git a/files/zh-cn/components.utils.evalinsandbox/index.html b/files/zh-cn/components.utils.evalinsandbox/index.html new file mode 100644 index 0000000000..57df3fe2c7 --- /dev/null +++ b/files/zh-cn/components.utils.evalinsandbox/index.html @@ -0,0 +1,80 @@ +--- +title: Components.utils.evalInSandbox +slug: Components.utils.evalInSandbox +tags: + - Developing Mozilla + - Extensions + - JavaScript + - XPConnect +translation_of: Mozilla/Tech/XPCOM/Language_Bindings/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

-- cgit v1.2.3-54-g00ecf