Bug 752559 - Console warning when sandboxed iframe is used ineffectively. r=smaug
authorFrancois Marier <francois@mozilla.com>
Sun, 07 Sep 2014 23:05:00 -0400
changeset 204650 47c6e06437281aafe2ed5b53d6e0ccbe8a264c5d
parent 204649 bf4de5f37e5bb8f8124a6778406fb8b9c1ea45c4
child 204651 99cc09026985ff3f54fb1f0c7a063850d4cb5601
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerssmaug
bugs752559
milestone35.0a1
Bug 752559 - Console warning when sandboxed iframe is used ineffectively. r=smaug
browser/devtools/webconsole/test/browser.ini
browser/devtools/webconsole/test/browser_webconsole_bug_752559_ineffective_iframe_sandbox_warning.js
browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning-inner.html
browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning-nested1.html
browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning-nested2.html
browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning0.html
browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning1.html
browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning2.html
browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning3.html
browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning4.html
browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning5.html
browser/devtools/webconsole/webconsole.js
content/base/src/nsDocument.cpp
dom/locales/en-US/chrome/security/security.properties
--- a/browser/devtools/webconsole/test/browser.ini
+++ b/browser/devtools/webconsole/test/browser.ini
@@ -40,16 +40,25 @@ support-files =
   test-bug-621644-jsterm-dollar.html
   test-bug-630733-response-redirect-headers.sjs
   test-bug-632275-getters.html
   test-bug-632347-iterators-generators.html
   test-bug-644419-log-limits.html
   test-bug-646025-console-file-location.html
   test-bug-658368-time-methods.html
   test-bug-737873-mixedcontent.html
+  test-bug-752559-ineffective-iframe-sandbox-warning0.html
+  test-bug-752559-ineffective-iframe-sandbox-warning1.html
+  test-bug-752559-ineffective-iframe-sandbox-warning2.html
+  test-bug-752559-ineffective-iframe-sandbox-warning3.html
+  test-bug-752559-ineffective-iframe-sandbox-warning4.html
+  test-bug-752559-ineffective-iframe-sandbox-warning5.html
+  test-bug-752559-ineffective-iframe-sandbox-warning-inner.html
+  test-bug-752559-ineffective-iframe-sandbox-warning-nested1.html
+  test-bug-752559-ineffective-iframe-sandbox-warning-nested2.html
   test-bug-762593-insecure-passwords-about-blank-web-console-warning.html
   test-bug-762593-insecure-passwords-web-console-warning.html
   test-bug-766001-console-log.js
   test-bug-766001-js-console-links.html
   test-bug-766001-js-errors.js
   test-bug-782653-css-errors-1.css
   test-bug-782653-css-errors-2.css
   test-bug-782653-css-errors.html
@@ -230,16 +239,17 @@ run-if = os == "win"
 [browser_webconsole_bug_658368_time_methods.js]
 [browser_webconsole_bug_659907_console_dir.js]
 [browser_webconsole_bug_660806_history_nav.js]
 [browser_webconsole_bug_664131_console_group.js]
 [browser_webconsole_bug_686937_autocomplete_JSTerm_helpers.js]
 [browser_webconsole_bug_704295.js]
 [browser_webconsole_bug_734061_No_input_change_and_Tab_key_pressed.js]
 [browser_webconsole_bug_737873_mixedcontent.js]
+[browser_webconsole_bug_752559_ineffective_iframe_sandbox_warning.js]
 [browser_webconsole_bug_762593_insecure_passwords_about_blank_web_console_warning.js]
 skip-if = buildapp == 'mulet'
 [browser_webconsole_bug_762593_insecure_passwords_web_console_warning.js]
 skip-if = buildapp == 'mulet'
 [browser_webconsole_bug_764572_output_open_url.js]
 [browser_webconsole_bug_766001_JS_Console_in_Debugger.js]
 skip-if = buildapp == 'mulet'
 [browser_webconsole_bug_770099_violation.js]
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_752559_ineffective_iframe_sandbox_warning.js
@@ -0,0 +1,77 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Tests that warnings about ineffective iframe sandboxing are logged to the
+// web console when necessary (and not otherwise).
+
+const TEST_URI_WARNING = "http://example.com/browser/browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning0.html";
+const TEST_URI_NOWARNING = [
+  "http://example.com/browser/browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning1.html",
+  "http://example.com/browser/browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning2.html",
+  "http://example.com/browser/browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning3.html",
+  "http://example.com/browser/browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning4.html",
+  "http://example.com/browser/browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning5.html"
+];
+
+const INEFFECTIVE_IFRAME_SANDBOXING_MSG = "An iframe which has both allow-scripts and allow-same-origin for its sandbox attribute can remove its sandboxing.";
+const SENTINEL_MSG = "testing ineffective sandboxing message";
+
+function test()
+{
+  addTab(TEST_URI_WARNING);
+  browser.addEventListener("load", function onLoad(aEvent) {
+    browser.removeEventListener(aEvent.type, onLoad, true);
+    openConsole(null, function testIneffectiveIframeSandboxingLogged (hud) {
+      content.console.log(SENTINEL_MSG)
+      waitForMessages({
+        webconsole: hud,
+        messages: [
+          {
+            name: "Ineffective iframe sandboxing warning displayed successfully",
+            text: INEFFECTIVE_IFRAME_SANDBOXING_MSG,
+            category: CATEGORY_SECURITY,
+            severity: SEVERITY_WARNING
+          },
+          {
+            text: SENTINEL_MSG,
+            severity: SEVERITY_LOG
+          }
+        ]
+      }).then(() => {
+        let msgs = hud.outputNode.querySelectorAll(".message[category=security]");
+        is(msgs.length, 1, "one security message");
+        testNoWarning(0);
+      });
+    });
+  }, true);
+}
+
+function testNoWarning(id)
+{
+  addTab(TEST_URI_NOWARNING[id]);
+  browser.addEventListener("load", function onLoad(aEvent) {
+    browser.removeEventListener(aEvent.type, onLoad, true);
+    openConsole(null, function testIneffectiveIframeSandboxingNotLogged (hud) {
+      content.console.log(SENTINEL_MSG)
+      waitForMessages({
+        webconsole: hud,
+        messages: [
+          {
+            text: SENTINEL_MSG,
+            severity: SEVERITY_LOG
+          }
+        ]
+      }).then(() => {
+        let msgs = hud.outputNode.querySelectorAll(".message[category=security]");
+        is(msgs.length, 0, "no security messages (case " + id + ")");
+
+        id += 1;
+        if (id < TEST_URI_NOWARNING.length) {
+          testNoWarning(id);
+        } else {
+          finishTest();
+        }
+      });
+    });
+  }, true);
+}
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning-inner.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<html>
+  <head>
+    <meta charset="utf8">
+    <title>Bug 752559 - print warning to error console when iframe sandbox
+      is being used ineffectively</title>
+      <!-- Any copyright is dedicated to the Public Domain.
+        http://creativecommons.org/publicdomain/zero/1.0/ -->
+  </head>
+  <body>
+    <p>I am sandboxed and want to escape.</p>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning-nested1.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<html>
+  <head>
+    <meta charset="utf8">
+    <title>Bug 752559 - print warning to error console when iframe sandbox
+      is being used ineffectively</title>
+      <!-- Any copyright is dedicated to the Public Domain.
+        http://creativecommons.org/publicdomain/zero/1.0/ -->
+  </head>
+  <body>
+    <iframe
+src="http://www.example.com/browser/browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning-inner.html"></iframe>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning-nested2.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<html>
+  <head>
+    <meta charset="utf8">
+    <title>Bug 752559 - print warning to error console when iframe sandbox
+      is being used ineffectively</title>
+      <!-- Any copyright is dedicated to the Public Domain.
+        http://creativecommons.org/publicdomain/zero/1.0/ -->
+  </head>
+  <body>
+    <iframe
+src="http://www.example.com/browser/browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning-inner.html" sandbox="allow-scripts allow-same-origin"></iframe>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning0.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<html>
+  <head>
+    <meta charset="utf8">
+    <title>Bug 752559 - print warning to error console when iframe sandbox
+      is being used ineffectively (allow-scripts, allow-same-origin)</title>
+      <!-- Any copyright is dedicated to the Public Domain.
+        http://creativecommons.org/publicdomain/zero/1.0/ -->
+  </head>
+  <body>
+    <iframe src="test-bug-752559-ineffective-iframe-sandbox-warning-inner.html" sandbox="allow-scripts allow-same-origin"></iframe>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning1.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<html>
+  <head>
+    <meta charset="utf8">
+    <title>Bug 752559 - print warning to error console when iframe sandbox
+      is being used ineffectively (allow-scripts, no allow-same-origin)</title>
+      <!-- Any copyright is dedicated to the Public Domain.
+        http://creativecommons.org/publicdomain/zero/1.0/ -->
+  </head>
+  <body>
+    <iframe src="test-bug-752559-ineffective-iframe-sandbox-warning-inner.html" sandbox="allow-scripts"></iframe>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning2.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<html>
+  <head>
+    <meta charset="utf8">
+    <title>Bug 752559 - print warning to error console when iframe sandbox
+      is being used ineffectively (no allow-scripts, allow-same-origin)</title>
+      <!-- Any copyright is dedicated to the Public Domain.
+        http://creativecommons.org/publicdomain/zero/1.0/ -->
+  </head>
+  <body>
+    <iframe src="test-bug-752559-ineffective-iframe-sandbox-warning-inner.html" sandbox="allow-same-origin"></iframe>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning3.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<html>
+  <head>
+    <meta charset="utf8">
+    <title>Bug 752559 - print warning to error console when iframe sandbox
+      is being used ineffectively (allow-scripts, allow-same-origin)</title>
+      <!-- Any copyright is dedicated to the Public Domain.
+        http://creativecommons.org/publicdomain/zero/1.0/ -->
+  </head>
+  <body>
+    <iframe
+src="http://www.example.com/browser/browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning-inner.html" sandbox="allow-scripts allow-same-origin"></iframe>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning4.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<html>
+  <head>
+    <meta charset="utf8">
+    <title>Bug 752559 - print warning to error console when iframe sandbox
+      is being used ineffectively (allow-scripts, allow-same-origin, nested)</title>
+      <!-- Any copyright is dedicated to the Public Domain.
+        http://creativecommons.org/publicdomain/zero/1.0/ -->
+  </head>
+  <body>
+    <iframe
+src="http://www.example.com/browser/browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning-nested1.html" sandbox="allow-scripts allow-same-origin"></iframe>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning5.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<html>
+  <head>
+    <meta charset="utf8">
+    <title>Bug 752559 - print warning to error console when iframe sandbox
+      is being used ineffectively (nested, allow-scripts, allow-same-origin)</title>
+      <!-- Any copyright is dedicated to the Public Domain.
+        http://creativecommons.org/publicdomain/zero/1.0/ -->
+  </head>
+  <body>
+    <iframe
+src="http://www.example.com/browser/browser/devtools/webconsole/test/test-bug-752559-ineffective-iframe-sandbox-warning-nested2.html"></iframe>
+  </body>
+</html>
--- a/browser/devtools/webconsole/webconsole.js
+++ b/browser/devtools/webconsole/webconsole.js
@@ -4664,16 +4664,17 @@ var Utils = {
     switch (category) {
       case "Mixed Content Blocker":
       case "Mixed Content Message":
       case "CSP":
       case "Invalid HSTS Headers":
       case "Insecure Password Field":
       case "SSL":
       case "CORS":
+      case "Iframe Sandbox":
         return CATEGORY_SECURITY;
 
       default:
         return CATEGORY_JS;
     }
   },
 
   /**
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -2512,16 +2512,65 @@ nsDocument::FillStyleSet(nsStyleSet* aSt
   AppendSheetsToStyleSet(aStyleSet, mAdditionalSheets[eAgentSheet],
                          nsStyleSet::eAgentSheet);
   AppendSheetsToStyleSet(aStyleSet, mAdditionalSheets[eUserSheet],
                          nsStyleSet::eUserSheet);
   AppendSheetsToStyleSet(aStyleSet, mAdditionalSheets[eAuthorSheet],
                          nsStyleSet::eDocSheet);
 }
 
+static void
+WarnIfSandboxIneffective(nsIDocShell* aDocShell,
+                         uint32_t aSandboxFlags,
+                         nsIChannel* aChannel)
+{
+  // If the document is sandboxed (via the HTML5 iframe sandbox
+  // attribute) and both the allow-scripts and allow-same-origin
+  // keywords are supplied, the sandboxed document can call into its
+  // parent document and remove its sandboxing entirely - we print a
+  // warning to the web console in this case.
+  if (aSandboxFlags & SANDBOXED_NAVIGATION &&
+      !(aSandboxFlags & SANDBOXED_SCRIPTS) &&
+      !(aSandboxFlags & SANDBOXED_ORIGIN)) {
+    nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
+    aDocShell->GetSameTypeParent(getter_AddRefs(parentAsItem));
+    nsCOMPtr<nsIDocShell> parentDocShell = do_QueryInterface(parentAsItem);
+    if (!parentDocShell) {
+      return;
+    }
+
+    // Don't warn if our parent is not the top-level document.
+    nsCOMPtr<nsIDocShellTreeItem> grandParentAsItem;
+    parentDocShell->GetSameTypeParent(getter_AddRefs(grandParentAsItem));
+    if (grandParentAsItem) {
+      return;
+    }
+
+    nsCOMPtr<nsIChannel> parentChannel;
+    parentDocShell->GetCurrentDocumentChannel(getter_AddRefs(parentChannel));
+    if (!parentChannel) {
+      return;
+    }
+    nsresult rv = nsContentUtils::CheckSameOrigin(aChannel, parentChannel);
+    if (NS_FAILED(rv)) {
+      return;
+    }
+
+    nsCOMPtr<nsIDocument> parentDocument = do_GetInterface(parentDocShell);
+    nsCOMPtr<nsIURI> iframeUri;
+    parentChannel->GetURI(getter_AddRefs(iframeUri));
+    nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
+                                    NS_LITERAL_CSTRING("Iframe Sandbox"),
+                                    parentDocument,
+                                    nsContentUtils::eSECURITY_PROPERTIES,
+                                    "BothAllowScriptsAndSameOriginPresent",
+                                    nullptr, 0, iframeUri);
+  }
+}
+
 nsresult
 nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
                               nsILoadGroup* aLoadGroup,
                               nsISupports* aContainer,
                               nsIStreamListener **aDocListener,
                               bool aReset, nsIContentSink* aSink)
 {
 #ifdef PR_LOGGING
@@ -2601,16 +2650,17 @@ nsDocument::StartDocumentLoad(const char
 
   // If this document is being loaded by a docshell, copy its sandbox flags
   // to the document. These are immutable after being set here.
   nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(aContainer);
 
   if (docShell) {
     nsresult rv = docShell->GetSandboxFlags(&mSandboxFlags);
     NS_ENSURE_SUCCESS(rv, rv);
+    WarnIfSandboxIneffective(docShell, mSandboxFlags, GetChannel());
   }
 
   // If this is not a data document, set CSP.
   if (!mLoadedAsData) {
     nsresult rv = InitCSP(aChannel);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
--- a/dom/locales/en-US/chrome/security/security.properties
+++ b/dom/locales/en-US/chrome/security/security.properties
@@ -8,8 +8,10 @@ CrossSiteRequestBlocked=Cross-Origin Req
 
 # LOCALIZATION NOTE: Do not translate "Strict-Transport-Security" or "HSTS"
 InvalidSTSHeaders=The site specified an invalid Strict-Transport-Security header.
 InsecurePasswordsPresentOnPage=Password fields present on an insecure (http://) page. This is a security risk that allows user login credentials to be stolen.
 InsecureFormActionPasswordsPresent=Password fields present in a form with an insecure (http://) form action. This is a security risk that allows user login credentials to be stolen.
 InsecurePasswordsPresentOnIframe=Password fields present on an insecure (http://) iframe. This is a security risk that allows user login credentials to be stolen.
 LoadingMixedActiveContent=Loading mixed (insecure) active content on a secure page "%1$S"
 LoadingMixedDisplayContent=Loading mixed (insecure) display content on a secure page "%1$S"
+# LOCALIZATION NOTE: Do not translate "allow-scripts", "allow-same-origin", "sandbox" or "iframe"
+BothAllowScriptsAndSameOriginPresent=An iframe which has both allow-scripts and allow-same-origin for its sandbox attribute can remove its sandboxing.