Bug 1335970 - Add prefs to add "Not Secure" text to insecure pages. r?johannh draft
authorJonathan Kingston <jkt@mozilla.com>
Sat, 20 Jan 2018 22:41:59 +0000
changeset 723646 9b46c508c390b0464d20b372eae8e975fa7a3fd6
parent 722931 553f7f86829a479910782e82511c986be4f75dee
child 746915 a9a203dda37cebe5975b719bdd3327eb9022ebfa
push id96492
push userbmo:jkt@mozilla.com
push dateTue, 23 Jan 2018 17:31:27 +0000
reviewersjohannh
bugs1335970
milestone59.0a1
Bug 1335970 - Add prefs to add "Not Secure" text to insecure pages. r?johannh MozReview-Commit-ID: JtCAjIYI3Qz
browser/app/profile/firefox.js
browser/base/content/browser.js
browser/base/content/test/siteIdentity/browser_check_identity_state.js
browser/locales/en-US/chrome/browser/browser.properties
browser/themes/shared/identity-block/identity-block.inc.css
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1336,16 +1336,20 @@ pref("security.insecure_password.ui.enab
 
 // Show in-content login form warning UI for insecure login fields
 pref("security.insecure_field_warning.contextual.enabled", true);
 
 // Show degraded UI for http pages; disabled for now
 pref("security.insecure_connection_icon.enabled", false);
 pref("security.insecure_connection_icon.pbmode.enabled", false);
 
+// Show "Not Secure" text for http pages; disabled for now
+pref("security.insecure_connection_text.enabled", false);
+pref("security.insecure_connection_text.pbmode.enabled", false);
+
 // 1 = allow MITM for certificate pinning checks.
 pref("security.cert_pinning.enforcement_level", 1);
 
 
 // Override the Gecko-default value of false for Firefox.
 pref("plain_text.wrap_long_lines", true);
 
 // If this turns true, Moz*Gesture events are not called stopPropagation()
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -7506,18 +7506,25 @@ var gIdentityHandler = {
         } else {
           this._identityBox.classList.add("weakCipher");
         }
       } else {
         let warnOnInsecure = Services.prefs.getBoolPref("security.insecure_connection_icon.enabled") ||
                              (Services.prefs.getBoolPref("security.insecure_connection_icon.pbmode.enabled") &&
                              PrivateBrowsingUtils.isWindowPrivate(window));
         let className = warnOnInsecure ? "notSecure" : "unknownIdentity";
-
         this._identityBox.className = className;
+
+        let warnTextOnInsecure = Services.prefs.getBoolPref("security.insecure_connection_text.enabled") ||
+                                 (Services.prefs.getBoolPref("security.insecure_connection_text.pbmode.enabled") &&
+                                 PrivateBrowsingUtils.isWindowPrivate(window));
+        if (warnTextOnInsecure) {
+          icon_label = gNavigatorBundle.getString("identity.notSecure.label");
+          this._identityBox.classList.add("notSecureText");
+        }
       }
       if (this._hasInsecureLoginForms) {
         // Insecure login forms can only be present on "unknown identity"
         // pages, either already insecure or with mixed active content loaded.
         this._identityBox.classList.add("insecureLoginForms");
       }
     }
 
--- a/browser/base/content/test/siteIdentity/browser_check_identity_state.js
+++ b/browser/base/content/test/siteIdentity/browser_check_identity_state.js
@@ -1,16 +1,17 @@
 /*
  * Test the identity mode UI for a variety of page types
  */
 
 "use strict";
 
 const DUMMY = "browser/browser/base/content/test/siteIdentity/dummy_page.html";
 const INSECURE_ICON_PREF = "security.insecure_connection_icon.enabled";
+const INSECURE_TEXT_PREF = "security.insecure_connection_text.enabled";
 const INSECURE_PBMODE_ICON_PREF = "security.insecure_connection_icon.pbmode.enabled";
 
 function loadNewTab(url) {
   return BrowserTestUtils.openNewForegroundTab(gBrowser, url, true);
 }
 
 function getIdentityMode(aWindow = window) {
   return aWindow.document.getElementById("identity-box").className;
@@ -51,16 +52,79 @@ async function webpageTest(secureCheck) 
   await SpecialPowers.popPrefEnv();
 }
 
 add_task(async function test_webpage() {
   await webpageTest(false);
   await webpageTest(true);
 });
 
+async function webpageTestTextWarning(secureCheck) {
+  await SpecialPowers.pushPrefEnv({set: [[INSECURE_TEXT_PREF, secureCheck]]});
+  let oldTab = gBrowser.selectedTab;
+
+  let newTab = await loadNewTab("http://example.com/" + DUMMY);
+  if (secureCheck) {
+    is(getIdentityMode(), "unknownIdentity notSecureText", "Identity should have not secure text");
+  } else {
+    is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
+  }
+
+  gBrowser.selectedTab = oldTab;
+  is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
+
+  gBrowser.selectedTab = newTab;
+  if (secureCheck) {
+    is(getIdentityMode(), "unknownIdentity notSecureText", "Identity should have not secure text");
+  } else {
+    is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
+  }
+
+  gBrowser.removeTab(newTab);
+  await SpecialPowers.popPrefEnv();
+}
+
+add_task(async function test_webpage_text_warning() {
+  await webpageTestTextWarning(false);
+  await webpageTestTextWarning(true);
+});
+
+async function webpageTestTextWarningCombined(secureCheck) {
+  await SpecialPowers.pushPrefEnv({set: [
+    [INSECURE_TEXT_PREF, secureCheck],
+    [INSECURE_ICON_PREF, secureCheck]
+  ]});
+  let oldTab = gBrowser.selectedTab;
+
+  let newTab = await loadNewTab("http://example.com/" + DUMMY);
+  if (secureCheck) {
+    is(getIdentityMode(), "notSecure notSecureText", "Identity should be not secure");
+  } else {
+    is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
+  }
+
+  gBrowser.selectedTab = oldTab;
+  is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
+
+  gBrowser.selectedTab = newTab;
+  if (secureCheck) {
+    is(getIdentityMode(), "notSecure notSecureText", "Identity should be not secure");
+  } else {
+    is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
+  }
+
+  gBrowser.removeTab(newTab);
+  await SpecialPowers.popPrefEnv();
+}
+
+add_task(async function test_webpage_text_warning_combined() {
+  await webpageTestTextWarning(false);
+  await webpageTestTextWarning(true);
+});
+
 async function blankPageTest(secureCheck) {
   let oldTab = gBrowser.selectedTab;
   await SpecialPowers.pushPrefEnv({set: [[INSECURE_ICON_PREF, secureCheck]]});
 
   let newTab = await loadNewTab("about:blank");
   is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
 
   gBrowser.selectedTab = oldTab;
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -510,16 +510,21 @@ canvas.remember=Always remember my decis
 
 # Spoof Accept-Language prompt
 privacy.spoof_english=Changing your language setting to English will make you more difficult to identify and enhance your privacy. Do you want to request English language versions of web pages?
 
 identity.identified.verifier=Verified by: %S
 identity.identified.verified_by_you=You have added a security exception for this site.
 identity.identified.state_and_country=%S, %S
 
+# LOCALIZATION NOTE (identity.notSecure.label):
+# Keep this string as short as possible, this is displayed in the URL bar
+# use a synonym for "safe" or "private" if "secure" is too long.
+identity.notSecure.label=Not Secure
+
 identity.icon.tooltip=Show site information
 identity.extension.label=Extension (%S)
 identity.extension.tooltip=Loaded by extension: %S
 identity.showDetails.tooltip=Show connection details
 
 trackingProtection.intro.title=How Tracking Protection works
 # LOCALIZATION NOTE (trackingProtection.intro.description2):
 # %S is brandShortName. This string should match the one from Step 1 of the tour
--- a/browser/themes/shared/identity-block/identity-block.inc.css
+++ b/browser/themes/shared/identity-block/identity-block.inc.css
@@ -39,33 +39,35 @@
 }
 
 #identity-icon-labels:-moz-locale-dir(ltr) {
   padding-left: 4px;
 }
 #identity-icon-labels:-moz-locale-dir(rtl) {
   padding-right: 4px;
 }
-#identity-box:not(.chromeUI):not(.extensionPage) {
+#identity-box:not(.chromeUI):not(.extensionPage):not(.notSecureText) {
   --urlbar-separator-color: transparent;
 }
 #urlbar[pageproxystate=valid] > #identity-box.verifiedIdentity {
   --urlbar-separator-color: rgba(18, 188, 0, .5);
 }
 
+#urlbar[pageproxystate=valid] > #identity-box.notSecureText,
 #urlbar[pageproxystate=valid] > #identity-box.verifiedIdentity,
 #urlbar[pageproxystate=valid] > #identity-box.chromeUI,
 #urlbar[pageproxystate=valid] > #identity-box.extensionPage,
 #urlbar-display-box {
   margin-inline-end: 8px;
   border-inline-end: 1px solid var(--urlbar-separator-color);
   border-image: linear-gradient(transparent 15%, var(--urlbar-separator-color) 15%, var(--urlbar-separator-color) 85%, transparent 85%);
   border-image-slice: 1;
 }
 
+#urlbar[pageproxystate=valid] > #identity-box.notSecureText,
 #urlbar[pageproxystate=valid] > #identity-box.verifiedIdentity,
 #urlbar[pageproxystate=valid] > #identity-box.chromeUI,
 #urlbar[pageproxystate=valid] > #identity-box.extensionPage {
   padding-inline-end: 8px;
 }
 
 #urlbar-display-box {
   padding-inline-start: 4px;