Bug 1525245 - Stabilize cookiePolicy/cookiePermission for live documents - part 11 - windows/workers/documents must keep the current cookie settings and ignore changes, r=Ehsan
☠☠ backed out by 66a4a5cb3fc7 ☠ ☠
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 27 Feb 2019 19:58:07 +0000
changeset 461524 efb2e8fca464952ac811ffc124d47bb543ff3a76
parent 461523 6a8401de32379f23a5544a7e0b5b1b16916fd581
child 461525 009e7457b990b1a0f6c19814cd31526539303ebc
push id79173
push useramarchesini@mozilla.com
push dateWed, 27 Feb 2019 20:36:38 +0000
treeherderautoland@009e7457b990 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersEhsan
bugs1525245
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1525245 - Stabilize cookiePolicy/cookiePermission for live documents - part 11 - windows/workers/documents must keep the current cookie settings and ignore changes, r=Ehsan Differential Revision: https://phabricator.services.mozilla.com/D18960
dom/base/Document.cpp
dom/base/nsGlobalWindowOuter.cpp
dom/workers/RuntimeService.cpp
netwerk/cookie/test/browser/browser_broadcastChannel.js
netwerk/cookie/test/browser/browser_domCache.js
netwerk/cookie/test/browser/browser_indexedDB.js
netwerk/cookie/test/browser/browser_serviceWorker.js
netwerk/cookie/test/browser/browser_sharedWorker.js
netwerk/cookie/test/browser/browser_storage.js
netwerk/cookie/test/browser/head.js
--- a/dom/base/Document.cpp
+++ b/dom/base/Document.cpp
@@ -11808,17 +11808,17 @@ void Document::SetDocTreeHadPlayRevoked(
   }
 }
 
 DocumentAutoplayPolicy Document::AutoplayPolicy() const {
   return AutoplayPolicy::IsAllowedToPlay(*this);
 }
 
 void Document::MaybeAllowStorageForOpenerAfterUserInteraction() {
-  if (StaticPrefs::network_cookie_cookieBehavior() !=
+  if (mCookieSettings->GetCookieBehavior() !=
       nsICookieService::BEHAVIOR_REJECT_TRACKER) {
     return;
   }
 
   // This will probably change for project fission, but currently this document
   // and the opener are on the same process. In the future, we should make this
   // part async.
 
@@ -12324,18 +12324,18 @@ already_AddRefed<mozilla::dom::Promise> 
 
   // Step 2. If the document has a null origin, reject.
   if (NodePrincipal()->GetIsNullPrincipal()) {
     promise->MaybeRejectWithUndefined();
     return promise.forget();
   }
 
   // Only enforce third-party checks when there is a reason to enforce them.
-  if (StaticPrefs::network_cookie_cookieBehavior() !=
-      nsICookieService::BEHAVIOR_ACCEPT) {
+  if (mCookieSettings->GetCookieBehavior() !=
+      nsICookieService::BEHAVIOR_REJECT_TRACKER) {
     // Step 3. If the document's frame is the main frame, resolve.
     if (IsTopLevelContentDocument()) {
       promise->MaybeResolveWithUndefined();
       return promise.forget();
     }
 
     // Step 4. If the sub frame's origin is equal to the main frame's, resolve.
     nsCOMPtr<Document> topLevelDoc = GetTopLevelContentDocument();
@@ -12377,17 +12377,17 @@ already_AddRefed<mozilla::dom::Promise> 
 
   if (nsContentUtils::IsInPrivateBrowsing(this)) {
     // If the document is in PB mode, it doesn't have access to its persistent
     // cookie jar, so reject the promise here.
     promise->MaybeRejectWithUndefined();
     return promise.forget();
   }
 
-  if (StaticPrefs::network_cookie_cookieBehavior() ==
+  if (mCookieSettings->GetCookieBehavior() ==
           nsICookieService::BEHAVIOR_REJECT_TRACKER &&
       inner) {
     // Only do something special for third-party tracking content.
     if (nsContentUtils::StorageDisabledByAntiTracking(this, nullptr)) {
       // Note: If this has returned true, the top-level document is guaranteed
       // to not be on the Content Blocking allow list.
       DebugOnly<bool> isOnAllowList = false;
       // If we have a parent document, it has to be non-private since we
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -1259,20 +1259,16 @@ nsGlobalWindowOuter::~nsGlobalWindowOute
 
   nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID);
   if (ac) ac->RemoveWindowAsListener(this);
 
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   if (obs) {
     obs->RemoveObserver(this, PERM_CHANGE_NOTIFICATION);
   }
-  nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID);
-  if (prefBranch) {
-    prefBranch->RemoveObserver("network.cookie.cookieBehavior", this);
-  }
 
   nsLayoutStatics::Release();
 }
 
 // static
 void nsGlobalWindowOuter::ShutDown() {
   AssertIsOnMainThread();
 
@@ -2319,30 +2315,28 @@ nsresult nsGlobalWindowOuter::SetNewDocu
 
   // If we have a recorded interesting Large-Allocation header status, report it
   // to the newly attached document.
   ReportLargeAllocStatus();
   mLargeAllocStatus = LargeAllocStatus::NONE;
 
   mHasStorageAccess = false;
   nsIURI* uri = aDocument->GetDocumentURI();
-  if (newInnerWindow) {
-    if (StaticPrefs::network_cookie_cookieBehavior() ==
-            nsICookieService::BEHAVIOR_REJECT_TRACKER &&
-        nsContentUtils::IsThirdPartyWindowOrChannel(newInnerWindow, nullptr,
-                                                    uri) &&
-        nsContentUtils::IsTrackingResourceWindow(newInnerWindow)) {
-      // Grant storage access by default if the first-party storage access
-      // permission has been granted already.
-      // Don't notify in this case, since we would be notifying the user
-      // needlessly.
-      mHasStorageAccess =
-          AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(
-              newInnerWindow, uri, nullptr);
-    }
+  if (newInnerWindow &&
+      aDocument->CookieSettings()->GetCookieBehavior() ==
+          nsICookieService::BEHAVIOR_REJECT_TRACKER &&
+      nsContentUtils::IsThirdPartyWindowOrChannel(newInnerWindow, nullptr,
+                                                  uri) &&
+      nsContentUtils::IsTrackingResourceWindow(newInnerWindow)) {
+    // Grant storage access by default if the first-party storage access
+    // permission has been granted already.
+    // Don't notify in this case, since we would be notifying the user
+    // needlessly.
+    mHasStorageAccess = AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(
+        newInnerWindow, uri, nullptr);
   }
 
   return NS_OK;
 }
 
 void nsGlobalWindowOuter::PreloadLocalStorage() {
   if (!Storage::StoragePrefIsEnabled()) {
     return;
@@ -6970,21 +6964,16 @@ nsGlobalWindowOuter::GetInterface(const 
 //*****************************************************************************
 // nsGlobalWindowOuter::nsIObserver
 //*****************************************************************************
 
 NS_IMETHODIMP
 nsGlobalWindowOuter::Observe(nsISupports* aSupports, const char* aTopic,
                              const char16_t* aData) {
   if (!nsCRT::strcmp(aTopic, PERM_CHANGE_NOTIFICATION)) {
-    if (!nsCRT::strcmp(aData, u"cleared") && !aSupports) {
-      // All permissions have been cleared.
-      mHasStorageAccess = false;
-      return NS_OK;
-    }
     nsCOMPtr<nsIPermission> permission = do_QueryInterface(aSupports);
     if (!permission) {
       return NS_OK;
     }
     nsIPrincipal* principal = GetPrincipal();
     if (!principal) {
       return NS_OK;
     }
@@ -7006,20 +6995,16 @@ nsGlobalWindowOuter::Observe(nsISupports
            expireTime >= PR_Now() / 1000) ||
           (expireType == nsIPermissionManager::EXPIRE_SESSION &&
            expireTime != 0)) {
         // Permission hasn't expired yet.
         mHasStorageAccess = true;
         return NS_OK;
       }
     }
-  } else if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
-    // Reset the storage access permission when our cookie policy changes.
-    mHasStorageAccess = false;
-    return NS_OK;
   }
   return NS_OK;
 }
 
 bool nsGlobalWindowOuter::IsSuspended() const {
   MOZ_ASSERT(NS_IsMainThread());
   // No inner means we are effectively suspended
   if (!mInnerWindow) {
@@ -7806,20 +7791,16 @@ mozilla::dom::TabGroup* nsPIDOMWindowOut
   if (obs) {
     // Delay calling AddObserver until we hit the event loop, in case we may be
     // in the middle of modifying the observer list somehow.
     NS_DispatchToMainThread(
         NS_NewRunnableFunction("PermChangeDelayRunnable", [obs, window] {
           obs->AddObserver(window, PERM_CHANGE_NOTIFICATION, true);
         }));
   }
-  nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID);
-  if (prefBranch) {
-    prefBranch->AddObserver("network.cookie.cookieBehavior", window, true);
-  }
   return window.forget();
 }
 
 nsIURI* nsPIDOMWindowOuter::GetDocumentURI() const {
   return mDoc ? mDoc->GetDocumentURI() : mDocumentURI.get();
 }
 
 void nsPIDOMWindowOuter::MaybeCreateDoc() {
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -2012,18 +2012,20 @@ void RuntimeService::ResumeWorkersForWin
     workers[index]->ParentWindowResumed();
   }
 }
 
 void RuntimeService::PropagateFirstPartyStorageAccessGranted(
     nsPIDOMWindowInner* aWindow) {
   AssertIsOnMainThread();
   MOZ_ASSERT(aWindow);
-  MOZ_ASSERT(StaticPrefs::network_cookie_cookieBehavior() ==
-             nsICookieService::BEHAVIOR_REJECT_TRACKER);
+  MOZ_ASSERT_IF(
+      aWindow->GetExtantDoc(),
+      aWindow->GetExtantDoc()->CookieSettings()->GetCookieBehavior() ==
+          nsICookieService::BEHAVIOR_REJECT_TRACKER);
 
   nsTArray<WorkerPrivate*> workers;
   GetWorkersForWindow(aWindow, workers);
 
   for (uint32_t index = 0; index < workers.Length(); index++) {
     workers[index]->PropagateFirstPartyStorageAccessGranted();
   }
 }
@@ -2394,18 +2396,20 @@ void ResumeWorkersForWindow(nsPIDOMWindo
   if (runtime) {
     runtime->ResumeWorkersForWindow(aWindow);
   }
 }
 
 void PropagateFirstPartyStorageAccessGrantedToWorkers(
     nsPIDOMWindowInner* aWindow) {
   AssertIsOnMainThread();
-  MOZ_ASSERT(StaticPrefs::network_cookie_cookieBehavior() ==
-             nsICookieService::BEHAVIOR_REJECT_TRACKER);
+  MOZ_ASSERT_IF(
+      aWindow->GetExtantDoc(),
+      aWindow->GetExtantDoc()->CookieSettings()->GetCookieBehavior() ==
+          nsICookieService::BEHAVIOR_REJECT_TRACKER);
 
   RuntimeService* runtime = RuntimeService::GetService();
   if (runtime) {
     runtime->PropagateFirstPartyStorageAccessGranted(aWindow);
   }
 }
 
 WorkerPrivate* GetWorkerPrivateFromContext(JSContext* aCx) {
--- a/netwerk/cookie/test/browser/browser_broadcastChannel.js
+++ b/netwerk/cookie/test/browser/browser_broadcastChannel.js
@@ -1,75 +1,75 @@
 // BroadcastChannel is not considered part of CookieJar. It's not allowed to
 // communicate with other windows with different cookie settings.
 
 CookiePolicyHelper.runTest("BroadcastChannel", {
-  cookieJarAccessAllowed: async _ => {
-    new content.BroadcastChannel("hello");
+  cookieJarAccessAllowed: async w => {
+    new w.BroadcastChannel("hello");
     ok(true, "BroadcastChannel be used");
   },
 
-  cookieJarAccessDenied: async _ => {
+  cookieJarAccessDenied: async w => {
     try {
-      new content.BroadcastChannel("hello");
+      new w.BroadcastChannel("hello");
       ok(false, "BroadcastChannel cannot be used!");
     } catch (e) {
       ok(true, "BroadcastChannel cannot be used!");
       is(e.name, "SecurityError", "We want a security error message.");
     }
   }
 });
 
 CookiePolicyHelper.runTest("BroadcastChannel in workers", {
-  cookieJarAccessAllowed: async _ => {
+  cookieJarAccessAllowed: async w => {
     function nonBlockingCode() {
       new BroadcastChannel("hello");
       postMessage(true);
     }
 
-    let blob = new content.Blob([nonBlockingCode.toString() + "; nonBlockingCode();"]);
+    let blob = new w.Blob([nonBlockingCode.toString() + "; nonBlockingCode();"]);
     ok(blob, "Blob has been created");
 
-    let blobURL = content.URL.createObjectURL(blob);
+    let blobURL = w.URL.createObjectURL(blob);
     ok(blobURL, "Blob URL has been created");
 
-    let worker = new content.Worker(blobURL);
+    let worker = new w.Worker(blobURL);
     ok(worker, "Worker has been created");
 
-    await new content.Promise((resolve, reject) => {
+    await new w.Promise((resolve, reject) => {
       worker.onmessage = function(e) {
         if (e) {
           resolve();
         } else {
           reject();
         }
       };
     });
   },
 
-  cookieJarAccessDenied: async _ => {
+  cookieJarAccessDenied: async w => {
     function blockingCode() {
       try {
         new BroadcastChannel("hello");
         postMessage(false);
       } catch (e) {
         postMessage(e.name == "SecurityError");
       }
     }
 
-    let blob = new content.Blob([blockingCode.toString() + "; blockingCode();"]);
+    let blob = new w.Blob([blockingCode.toString() + "; blockingCode();"]);
     ok(blob, "Blob has been created");
 
-    let blobURL = content.URL.createObjectURL(blob);
+    let blobURL = w.URL.createObjectURL(blob);
     ok(blobURL, "Blob URL has been created");
 
-    let worker = new content.Worker(blobURL);
+    let worker = new w.Worker(blobURL);
     ok(worker, "Worker has been created");
 
-    await new content.Promise((resolve, reject) => {
+    await new w.Promise((resolve, reject) => {
       worker.onmessage = function(e) {
         if (e) {
           resolve();
         } else {
           reject();
         }
       };
     });
--- a/netwerk/cookie/test/browser/browser_domCache.js
+++ b/netwerk/cookie/test/browser/browser_domCache.js
@@ -1,13 +1,13 @@
 CookiePolicyHelper.runTest("DOM Cache", {
-  cookieJarAccessAllowed: async _ => {
-    await content.caches.open("wow").then(
+  cookieJarAccessAllowed: async w => {
+    await w.caches.open("wow").then(
       _ => { ok(true, "DOM Cache can be used!"); },
       _ => { ok(false, "DOM Cache can be used!"); });
   },
 
-  cookieJarAccessDenied: async _ => {
-    await content.caches.open("wow").then(
+  cookieJarAccessDenied: async w => {
+    await w.caches.open("wow").then(
       _ => { ok(false, "DOM Cache cannot be used!"); },
       _ => { ok(true, "DOM Cache cannot be used!"); });
   },
 });
--- a/netwerk/cookie/test/browser/browser_indexedDB.js
+++ b/netwerk/cookie/test/browser/browser_indexedDB.js
@@ -1,76 +1,76 @@
 CookiePolicyHelper.runTest("IndexedDB", {
-  cookieJarAccessAllowed: async _ => {
-    content.indexedDB.open("test", "1");
+  cookieJarAccessAllowed: async w => {
+    w.indexedDB.open("test", "1");
     ok(true, "IDB should be allowed");
   },
 
-  cookieJarAccessDenied: async _ => {
+  cookieJarAccessDenied: async w => {
     try {
-      content.indexedDB.open("test", "1");
+      w.indexedDB.open("test", "1");
       ok(false, "IDB should be blocked");
     } catch (e) {
       ok(true, "IDB should be blocked");
       is(e.name, "SecurityError", "We want a security error message.");
     }
   },
 });
 
 CookiePolicyHelper.runTest("IndexedDB in workers", {
-  cookieJarAccessAllowed: async _ => {
+  cookieJarAccessAllowed: async w => {
     function nonBlockCode() {
       indexedDB.open("test", "1");
       postMessage(true);
     }
 
-    let blob = new content.Blob([nonBlockCode.toString() + "; nonBlockCode();"]);
+    let blob = new w.Blob([nonBlockCode.toString() + "; nonBlockCode();"]);
     ok(blob, "Blob has been created");
 
-    let blobURL = content.URL.createObjectURL(blob);
+    let blobURL = w.URL.createObjectURL(blob);
     ok(blobURL, "Blob URL has been created");
 
-    let worker = new content.Worker(blobURL);
+    let worker = new w.Worker(blobURL);
     ok(worker, "Worker has been created");
 
-    await new content.Promise((resolve, reject) => {
+    await new w.Promise((resolve, reject) => {
       worker.onmessage = function(e) {
         if (e.data) {
           resolve();
         } else {
           reject();
         }
       };
 
       worker.onerror = function(e) {
         reject();
       };
     });
   },
 
-  cookieJarAccessDenied: async _ => {
+  cookieJarAccessDenied: async w => {
     function blockCode() {
       try {
         indexedDB.open("test", "1");
         postMessage(false);
       } catch (e) {
         postMessage(e.name == "SecurityError");
       }
     }
 
-    let blob = new content.Blob([blockCode.toString() + "; blockCode();"]);
+    let blob = new w.Blob([blockCode.toString() + "; blockCode();"]);
     ok(blob, "Blob has been created");
 
-    let blobURL = content.URL.createObjectURL(blob);
+    let blobURL = w.URL.createObjectURL(blob);
     ok(blobURL, "Blob URL has been created");
 
-    let worker = new content.Worker(blobURL);
+    let worker = new w.Worker(blobURL);
     ok(worker, "Worker has been created");
 
-    await new content.Promise((resolve, reject) => {
+    await new w.Promise((resolve, reject) => {
       worker.onmessage = function(e) {
         if (e.data) {
           resolve();
         } else {
           reject();
         }
       };
 
--- a/netwerk/cookie/test/browser/browser_serviceWorker.js
+++ b/netwerk/cookie/test/browser/browser_serviceWorker.js
@@ -1,24 +1,24 @@
 CookiePolicyHelper.runTest("ServiceWorker", {
   prefs: [
     ["dom.serviceWorkers.exemptFromPerDomainMax", true],
     ["dom.ipc.processCount", 1],
     ["dom.serviceWorkers.enabled", true],
     ["dom.serviceWorkers.testing.enabled", true],
   ],
 
-  cookieJarAccessAllowed: async _ => {
-    await content.navigator.serviceWorker.register("file_empty.js").then(
+  cookieJarAccessAllowed: async w => {
+    await w.navigator.serviceWorker.register("file_empty.js").then(
       reg => { ok(true, "ServiceWorker can be used!"); return reg; },
       _ => { ok(false, "ServiceWorker cannot be used! " + _); }).then(
       reg => reg.unregister(),
       _ => { ok(false, "unregister failed"); }).
       catch(e => ok(false, "Promise rejected: " + e));
   },
 
-  cookieJarAccessDenied: async _ => {
-    await content.navigator.serviceWorker.register("file_empty.js").then(
+  cookieJarAccessDenied: async w => {
+    await w.navigator.serviceWorker.register("file_empty.js").then(
       _ => { ok(false, "ServiceWorker cannot be used!"); },
       _ => { ok(true, "ServiceWorker cannot be used!"); }).
       catch(e => ok(false, "Promise rejected: " + e));
   },
 });
--- a/netwerk/cookie/test/browser/browser_sharedWorker.js
+++ b/netwerk/cookie/test/browser/browser_sharedWorker.js
@@ -1,16 +1,16 @@
 CookiePolicyHelper.runTest("SharedWorker", {
-  cookieJarAccessAllowed: async _ => {
-    new content.SharedWorker("a.js", "foo");
+  cookieJarAccessAllowed: async w => {
+    new w.SharedWorker("a.js", "foo");
     ok(true, "SharedWorker is allowed");
   },
 
-  cookieJarAccessDenied: async _ => {
+  cookieJarAccessDenied: async w => {
     try {
-      new content.SharedWorker("a.js", "foo");
+      new w.SharedWorker("a.js", "foo");
       ok(false, "SharedWorker cannot be used!");
     } catch (e) {
       ok(true, "SharedWorker cannot be used!");
       is(e.name, "SecurityError", "We want a security error message.");
     }
   },
 });
--- a/netwerk/cookie/test/browser/browser_storage.js
+++ b/netwerk/cookie/test/browser/browser_storage.js
@@ -1,41 +1,41 @@
 CookiePolicyHelper.runTest("SessionStorage", {
-  cookieJarAccessAllowed: async _ => {
+  cookieJarAccessAllowed: async w => {
     try {
-      content.sessionStorage.foo = 42;
+      w.sessionStorage.foo = 42;
       ok(true, "SessionStorage works");
     } catch (e) {
       ok(false, "SessionStorage works");
     }
   },
 
-  cookieJarAccessDenied: async _ => {
+  cookieJarAccessDenied: async w => {
     try {
-      content.sessionStorage.foo = 42;
+      w.sessionStorage.foo = 42;
       ok(false, "SessionStorage doesn't work");
     } catch (e) {
       ok(true, "SessionStorage doesn't work");
       is(e.name, "SecurityError", "We want a security error message.");
     }
   },
 });
 
 CookiePolicyHelper.runTest("LocalStorage", {
-  cookieJarAccessAllowed: async _ => {
+  cookieJarAccessAllowed: async w => {
     try {
-      content.localStorage.foo = 42;
+      w.localStorage.foo = 42;
       ok(true, "LocalStorage works");
     } catch (e) {
       ok(false, "LocalStorage works");
     }
   },
 
-  cookieJarAccessDenied: async _ => {
+  cookieJarAccessDenied: async w => {
     try {
-      content.localStorage.foo = 42;
+      w.localStorage.foo = 42;
       ok(false, "LocalStorage doesn't work");
     } catch (e) {
       ok(true, "LocalStorage doesn't work");
-      is(e.name, "SecurityError", "We want a security error message.");
+      is(e.name, "TypeError", "We want a security error message.");
     }
   },
 });
--- a/netwerk/cookie/test/browser/head.js
+++ b/netwerk/cookie/test/browser/head.js
@@ -92,40 +92,58 @@ this.CookiePolicyHelper = {
 
       // Let's open a tab and load content.
       let tab = BrowserTestUtils.addTab(gBrowser, TEST_TOP_PAGE);
       gBrowser.selectedTab = tab;
 
       let browser = gBrowser.getBrowserForTab(tab);
       await BrowserTestUtils.browserLoaded(browser);
 
+      // Let's create an iframe.
+      await ContentTask.spawn(browser, { url: TEST_TOP_PAGE },
+                              async obj => {
+        return new content.Promise(resolve => {
+          let ifr = content.document.createElement('iframe');
+          ifr.setAttribute("id", "iframe");
+          ifr.src = obj.url;
+          ifr.onload = resolve;
+          content.document.body.appendChild(ifr);
+        });
+      });
+
       // Let's exec the "good" callback.
       info("Executing the test after setting the cookie behavior to " + config.fromBehavior + " and permission to " + config.fromPermission);
       await ContentTask.spawn(browser,
                               { callback: goodCb.toString() },
                               async obj => {
         let runnableStr = `(() => {return (${obj.callback});})();`;
         let runnable = eval(runnableStr); // eslint-disable-line no-eval
-        await runnable();
+        await runnable(content);
+
+        let ifr = content.document.getElementById("iframe");
+        await runnable(ifr.contentWindow);
       });
 
       // Now, let's change the cookie settings
       Services.perms.add(uri, "cookie", config.toPermission);
       await SpecialPowers.pushPrefEnv({"set": [
         ["network.cookie.cookieBehavior", config.toBehavior],
       ]});
 
       // We still want the good callback to succeed.
       info("Executing the test after setting the cookie behavior to " + config.toBehavior + " and permission to " + config.toPermission);
       await ContentTask.spawn(browser,
                               { callback: goodCb.toString() },
                               async obj => {
         let runnableStr = `(() => {return (${obj.callback});})();`;
         let runnable = eval(runnableStr); // eslint-disable-line no-eval
-        await runnable.call(content.window);
+        await runnable(content);
+
+        let ifr = content.document.getElementById("iframe");
+        await runnable(ifr.contentWindow);
       });
 
       // Let's close the tab.
       BrowserTestUtils.removeTab(tab);
 
       // Let's open a new tab and load content again.
       tab = BrowserTestUtils.addTab(gBrowser, TEST_TOP_PAGE);
       gBrowser.selectedTab = tab;
@@ -135,17 +153,17 @@ this.CookiePolicyHelper = {
 
       // Let's exec the "bad" callback.
       info("Executing the test in a new tab");
       await ContentTask.spawn(browser,
                               { callback: badCb.toString() },
                               async obj => {
         let runnableStr = `(() => {return (${obj.callback});})();`;
         let runnable = eval(runnableStr); // eslint-disable-line no-eval
-        await runnable.call(content.window);
+        await runnable(content);
       });
 
       // Let's close the tab.
       BrowserTestUtils.removeTab(tab);
 
       // Cleanup.
       await new Promise(resolve => {
         Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, resolve);