Bug 1065186 - Drop support for exposing privileged arrays to untrusted content. r=gabor
authorBobby Holley <bobbyholley@gmail.com>
Thu, 16 Oct 2014 14:12:37 +0200
changeset 210735 ce796ac8901b15e09e41b4d6fc6608e2d8ec17f1
parent 210734 d6aadffaf23948b6f1b4b5994a42755e2fd60633
child 210736 db2672baa851a4a19753fe73794c5fcbe14a3113
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersgabor
bugs1065186
milestone36.0a1
Bug 1065186 - Drop support for exposing privileged arrays to untrusted content. r=gabor
js/xpconnect/tests/unit/test_bug849730.js
js/xpconnect/tests/unit/test_bug853709.js
js/xpconnect/wrappers/WrapperFactory.cpp
--- a/js/xpconnect/tests/unit/test_bug849730.js
+++ b/js/xpconnect/tests/unit/test_bug849730.js
@@ -1,7 +1,7 @@
 const Cu = Components.utils;
 
 function run_test() {
   var sb = new Cu.Sandbox('http://www.example.com');
   sb.arr = [3, 4];
-  do_check_true(Cu.evalInSandbox('Array.isArray(arr);', sb));
+  do_check_true(Cu.evalInSandbox('!Array.isArray(arr);', sb));
 }
--- a/js/xpconnect/tests/unit/test_bug853709.js
+++ b/js/xpconnect/tests/unit/test_bug853709.js
@@ -1,14 +1,13 @@
 const Cu = Components.utils;
 
 function setupChromeSandbox() {
   this.chromeObj = {a: 2, __exposedProps__: {a: "rw", b: "rw"} };
   this.chromeArr = [4, 2, 1];
-  this.chromeArr["__exposedProps__"] = { "1": "rw" };
 }
 
 function checkDefineThrows(sb, obj, prop, desc) {
   var result = Cu.evalInSandbox('(function() { try { Object.defineProperty(' + obj + ', "' + prop + '", ' + desc.toSource() + '); return "nothrow"; } catch (e) { return e.toString(); }})();', sb);
   do_check_neq(result, 'nothrow');
   do_check_true(!!/denied/.exec(result));
   do_check_true(result.indexOf(prop) != -1); // Make sure the prop name is in the error message.
 }
@@ -16,15 +15,18 @@ function checkDefineThrows(sb, obj, prop
 function run_test() {
   var chromeSB = new Cu.Sandbox(this);
   var contentSB = new Cu.Sandbox('http://www.example.org');
   Cu.evalInSandbox('(' + setupChromeSandbox.toSource() + ')()', chromeSB);
   contentSB.chromeObj = chromeSB.chromeObj;
   contentSB.chromeArr = chromeSB.chromeArr;
 
   do_check_eq(Cu.evalInSandbox('chromeObj.a', contentSB), 2);
-  do_check_eq(Cu.evalInSandbox('chromeArr[1]', contentSB), 2);
+  try {
+    Cu.evalInSandbox('chromeArr[1]', contentSB);
+    do_check_true(false);
+  } catch (e) { do_check_true(/denied|insecure/.test(e)); }
 
   checkDefineThrows(contentSB, 'chromeObj', 'a', {get: function() { return 2; }});
   checkDefineThrows(contentSB, 'chromeObj', 'a', {configurable: true, get: function() { return 2; }});
   checkDefineThrows(contentSB, 'chromeObj', 'b', {configurable: true, get: function() { return 2; }, set: function() {}});
   checkDefineThrows(contentSB, 'chromeArr', '1', {configurable: true, get: function() { return 2; }});
 }
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -114,17 +114,17 @@ static bool
 ForceCOWBehavior(JSObject *obj)
 {
     JSProtoKey key = IdentifyStandardInstanceOrPrototype(obj);
     if (key == JSProto_Function && GetXrayType(obj) == XrayForDOMObject) {
         // This means that we've got a DOM constructor, which we never want to
         // expose COW-style.
         return false;
     }
-    if (key == JSProto_Object || key == JSProto_Array || key == JSProto_Function) {
+    if (key == JSProto_Object || key == JSProto_Function) {
         MOZ_ASSERT(GetXrayType(obj) == XrayForJSObject,
                    "We should use XrayWrappers for standard ES Object, Array, and Function "
                    "instances modulo this hack");
         return true;
     }
 
     return false;
 }