Bug 1388889 fix null principal handling for webrequest, r?kmag draft
authorShane Caraveo <scaraveo@mozilla.com>
Fri, 25 Aug 2017 14:12:42 -0700
changeset 653349 bef9afd1ad026a155a1888ea07b47ab0950dc26f
parent 653118 56188620cce00b19700fbb8efaafea65e6ca8c61
child 728316 8c707a60146e310ee6ec7101024ec7a97709c413
push id76303
push usermixedpuppy@gmail.com
push dateFri, 25 Aug 2017 21:13:10 +0000
reviewerskmag
bugs1388889
milestone57.0a1
Bug 1388889 fix null principal handling for webrequest, r?kmag MozReview-Commit-ID: B8qK4ZnaO9i
toolkit/components/extensions/test/mochitest/file_simple_sandboxed_frame.html
toolkit/components/extensions/test/mochitest/file_simple_xhr_frame2.html
toolkit/components/extensions/test/mochitest/mochitest-common.ini
toolkit/components/extensions/test/mochitest/test_ext_webrequest_frameId.html
toolkit/modules/addons/WebRequest.jsm
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/test/mochitest/file_simple_sandboxed_frame.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+
+<html>
+<head>
+<meta charset="utf-8">
+</head>
+<body>
+
+<script>
+"use strict";
+
+let req = new XMLHttpRequest();
+req.open("GET", "/xhr_sandboxed");
+req.send();
+</script>
+<img src="file_image_great.png"/>
+</body>
+</html>
--- a/toolkit/components/extensions/test/mochitest/file_simple_xhr_frame2.html
+++ b/toolkit/components/extensions/test/mochitest/file_simple_xhr_frame2.html
@@ -7,12 +7,17 @@
 <body>
 
 <script>
 "use strict";
 
 let req = new XMLHttpRequest();
 req.open("GET", "/xhr_resource_2");
 req.send();
+
+let sandbox = document.createElement("iframe");
+sandbox.setAttribute("sandbox", "allow-scripts");
+sandbox.setAttribute("src", "file_simple_sandboxed_frame.html");
+document.documentElement.appendChild(sandbox);
 </script>
 <img src="file_image_bad.png#2"/>
 </body>
 </html>
--- a/toolkit/components/extensions/test/mochitest/mochitest-common.ini
+++ b/toolkit/components/extensions/test/mochitest/mochitest-common.ini
@@ -22,27 +22,29 @@ support-files =
   file_webNavigation_manualSubframe.html
   file_webNavigation_manualSubframe_page1.html
   file_webNavigation_manualSubframe_page2.html
   file_WebNavigation_page1.html
   file_WebNavigation_page2.html
   file_WebNavigation_page3.html
   file_with_about_blank.html
   file_image_good.png
+  file_image_great.png
   file_image_bad.png
   file_image_redirect.png
   file_style_good.css
   file_style_bad.css
   file_style_redirect.css
   file_script_good.js
   file_script_bad.js
   file_script_redirect.js
   file_script_xhr.js
   file_remote_frame.html
   file_sample.html
+  file_simple_sandboxed_frame.html
   file_simple_xhr.html
   file_simple_xhr_frame.html
   file_simple_xhr_frame2.html
   redirect_auto.sjs
   redirection.sjs
   file_privilege_escalation.html
   file_ext_test_api_injection.js
   file_permission_xhr.html
--- a/toolkit/components/extensions/test/mochitest/test_ext_webrequest_frameId.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_webrequest_frameId.html
@@ -64,39 +64,56 @@ let expected = {
     type: "sub_frame",
   },
   "file_image_bad.png#2": {
     type: "image",
   },
   "xhr_resource_2": {
     type: "xmlhttprequest",
   },
+  // This is loaded in a sandbox iframe.
+  "file_simple_sandboxed_frame.html": {
+    type: "sub_frame",
+  },
+  "xhr_sandboxed": {
+    type: "xmlhttprequest",
+    sandboxed: true,
+  },
+  "file_image_great.png": {
+    type: "image",
+    sandboxed: true,
+  },
 };
 
-let subframeId, parentId;
 function checkDetails(details) {
   let url = new URL(details.url);
   let filename = url.pathname.split("/").pop();
   let expect = expected[filename];
   is(expect.type, details.type, `${details.type} type matches`);
   if (expect.toplevel) {
     is(0, details.frameId, "expect load at top level");
     is(-1, details.parentFrameId, "expect top level frame to have no parent");
   } else if (details.type == "sub_frame") {
     ok(details.frameId > 0, "expect sub_frame to load into a new frame");
     if (expect.toplevelParent) {
       is(0, details.parentFrameId, "expect sub_frame to have top level parent");
     } else {
       ok(details.parentFrameId > 0, "expect sub_frame to have parent");
     }
-    subframeId = details.frameId;
-    parentId = details.parentFrameId;
+    expect.subframeId = details.frameId;
+    expect.parentId = details.parentFrameId;
+  } else if (expect.sandboxed) {
+    is(details.documentUrl, undefined, "null principal documentUrl for sandboxed request");
   } else {
-    is(subframeId, details.frameId, "expect load in subframe");
-    is(parentId, details.parentFrameId, "expect subframe parent");
+    // get the parent frame.
+    let purl = new URL(details.documentUrl);
+    let pfilename = purl.pathname.split("/").pop();
+    let parent = expected[pfilename];
+    is(details.frameId, parent.subframeId, "expect load in subframe");
+    is(details.parentFrameId, parent.parentId, "expect subframe parent");
   }
 }
 
 add_task(async function test_webRequest_main_frame() {
   // Clear the image cache, since it gets in the way otherwise.
   let imgTools = SpecialPowers.Cc["@mozilla.org/image/tools;1"].getService(SpecialPowers.Ci.imgITools);
   let cache = imgTools.getImgCacheForDocument(document);
   cache.clearCache(false);
--- a/toolkit/modules/addons/WebRequest.jsm
+++ b/toolkit/modules/addons/WebRequest.jsm
@@ -784,21 +784,21 @@ HttpObserverManager = {
 
     // force the protocol to be ws again.
     if (data.type == "websocket" && data.url.startsWith("http")) {
       data.url = `ws${data.url.substring(4)}`;
     }
 
     if (loadInfo) {
       let originPrincipal = loadInfo.triggeringPrincipal;
-      if (originPrincipal.URI) {
+      if (!originPrincipal.isNullPrincipal && originPrincipal.URI) {
         data.originUrl = originPrincipal.URI.spec;
       }
       let docPrincipal = loadInfo.loadingPrincipal;
-      if (docPrincipal && docPrincipal.URI) {
+      if (docPrincipal && !docPrincipal.isNullPrincipal && docPrincipal.URI) {
         data.documentUrl = docPrincipal.URI.spec;
       }
 
       // If there is no loadingPrincipal, check that the request is not going to
       // inherit a system principal.  triggeringPrincipal is the context that
       // initiated the load, but is not necessarily the principal that the
       // request results in, only rely on that if no other principal is available.
       let {isSystemPrincipal} = Services.scriptSecurityManager;