Bug 1216469 - Bypass verification for signed packages from trust origins. r=valentin
authorJonathan Hao <jhao@mozilla.com>
Thu, 22 Oct 2015 17:09:44 +0800
changeset 304364 2f33a28c15a7d96f68f3aa7393a73ffe8a3f3aff
parent 304363 bc7c5bc091207782385673c4eb70f54b189faa0c
child 304365 ad80366135f31aa550911d7911ce6352dc5369d3
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvalentin
bugs1216469
milestone44.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 1216469 - Bypass verification for signed packages from trust origins. r=valentin
modules/libpref/init/all.js
netwerk/base/nsIPackagedAppVerifier.idl
netwerk/protocol/http/PackagedAppService.cpp
netwerk/protocol/http/PackagedAppVerifier.cpp
netwerk/protocol/http/PackagedAppVerifier.h
netwerk/test/mochitests/test_signed_web_packaged_app.html
netwerk/test/unit/test_packaged_app_channel.js
netwerk/test/unit/test_packaged_app_service.js
netwerk/test/unit/test_packaged_app_verifier.js
security/apps/AppTrustDomain.cpp
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1447,22 +1447,17 @@ pref("network.http.enforce-framing.soft"
 // Whether nsHttpChannel should use the PackagedAppService to load
 // resources from a package when directed to a URL
 // such as http://domain.com/package.pak!//resource.html
 // See http://www.w3.org/TR/web-packaging/#streamable-package-format
 pref("network.http.enable-packaged-apps", false);
 
 // Enable this to bring in the signature verification if the signature exists.
 // Set to false if you don't need the signed packaged web app support (i.e. NSec).
-pref("network.http.packaged-signed-apps-enabled", false);
-
-// Enable this pref to skip verification process. The packaged app
-// will be considered signed no matter the package has a valid/invalid
-// signature or no signature.
-pref("network.http.packaged-apps-developer-mode", false);
+pref("network.http.signed-packages.enabled", false);
 
 // default values for FTP
 // in a DSCP environment this should be 40 (0x28, or AF11), per RFC-4594,
 // Section 4.8 "High-Throughput Data Service Class", and 80 (0x50, or AF22)
 // per Section 4.7 "Low-Latency Data Service Class".
 pref("network.ftp.data.qos", 0);
 pref("network.ftp.control.qos", 0);
 
--- a/netwerk/base/nsIPackagedAppVerifier.idl
+++ b/netwerk/base/nsIPackagedAppVerifier.idl
@@ -12,17 +12,17 @@ interface nsIPackagedAppVerifierListener
 
 /**
  * nsIPackagedAppVerifier
  *
  * It inherits nsIStreamListener and all the data will be fed by
  * onStartRequest/onDataAvailable/onStopRequest.
  *
  */
-[scriptable, uuid(fbb28ef8-d3d0-4a2b-af98-8010163a2bfb)]
+[scriptable, uuid(37a5c208-0fce-4ad6-8431-aeb904dfe543)]
 interface nsIPackagedAppVerifier : nsIStreamListener
 {
   // The package identifier of the signed package. For a unsigned package, this
   // attribute is empty.
   readonly attribute ACString packageIdentifier;
 
   // Whether this package is signed.
   readonly attribute boolean isPackageSigned;
@@ -45,16 +45,17 @@ interface nsIPackagedAppVerifier : nsISt
    * @param aPackageCacheEntry
    *    the cache entry of the package itself (not the resource's cache).
    *    It will be used to store any necessary information like the signed
    *    package origin.
    *
    * The verifier init function.
    */
   void init(in nsIPackagedAppVerifierListener aListener,
+            in ACString aPackageOrigin,
             in ACString aSignature,
             in nsICacheEntry aPackageCacheEntry);
 
   /**
    * @param aUri
    *    the URI of the resource.
    *
    * @param aCacheEntry
--- a/netwerk/protocol/http/PackagedAppService.cpp
+++ b/netwerk/protocol/http/PackagedAppService.cpp
@@ -442,16 +442,17 @@ PackagedAppService::PackagedAppDownloade
 
   LOG(("Creating PackagedAppVerifier."));
 
   nsCOMPtr<nsIMultiPartChannel> multiChannel(do_QueryInterface(aRequest));
   nsCString signature = GetSignatureFromChannel(multiChannel);
   nsCOMPtr<nsICacheEntry> packageCacheEntry = GetPackageCacheEntry(aRequest);
 
   mVerifier = new PackagedAppVerifier(this,
+                                      mPackageOrigin,
                                       signature,
                                       packageCacheEntry);
 }
 
 NS_IMETHODIMP
 PackagedAppService::PackagedAppDownloader::OnStartRequest(nsIRequest *aRequest,
                                                           nsISupports *aContext)
 {
--- a/netwerk/protocol/http/PackagedAppVerifier.cpp
+++ b/netwerk/protocol/http/PackagedAppVerifier.cpp
@@ -11,22 +11,21 @@
 #include "mozilla/DebugOnly.h"
 #include "nsThreadUtils.h"
 #include "PackagedAppVerifier.h"
 #include "nsITimer.h"
 #include "nsIPackagedAppVerifier.h"
 #include "mozilla/Preferences.h"
 #include "nsIPackagedAppUtils.h"
 #include "nsIInputStream.h"
+#include "nsComponentManagerUtils.h"
+#include "nsIURL.h"
 
 static const short kResourceHashType = nsICryptoHash::SHA256;
 
-// If it's true, all the verification will be skipped and the package will
-// be treated signed.
-static bool gDeveloperMode = false;
 static bool gSignedAppEnabled = false;
 
 namespace mozilla {
 namespace net {
 
 ///////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS(PackagedAppVerifier, nsIPackagedAppVerifier, nsIVerificationCallback)
@@ -35,57 +34,61 @@ NS_IMPL_ISUPPORTS(PackagedAppVerifier::R
 
 const char* PackagedAppVerifier::kSignedPakIdMetadataKey = "package-id";
 
 PackagedAppVerifier::PackagedAppVerifier()
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread(),
                      "PackagedAppVerifier::OnResourceVerified must be on main thread");
 
-  Init(nullptr, EmptyCString(), nullptr);
+  Init(nullptr, EmptyCString(), EmptyCString(), nullptr);
 }
 
 PackagedAppVerifier::PackagedAppVerifier(nsIPackagedAppVerifierListener* aListener,
+                                         const nsACString& aPackageOrigin,
                                          const nsACString& aSignature,
                                          nsICacheEntry* aPackageCacheEntry)
 {
-  Init(aListener, aSignature, aPackageCacheEntry);
+  Init(aListener, aPackageOrigin, aSignature, aPackageCacheEntry);
 }
 
 PackagedAppVerifier::~PackagedAppVerifier()
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread(), "mPendingResourceCacheInfoList is not thread safe.");
   while (auto i = mPendingResourceCacheInfoList.popFirst()) {
     // This seems to be the only way that we can manually delete a
     // nsISupports instance with no warning.
     RefPtr<ResourceCacheInfo> deleter(i);
   }
 }
 
 NS_IMETHODIMP PackagedAppVerifier::Init(nsIPackagedAppVerifierListener* aListener,
+                                        const nsACString& aPackageOrigin,
                                         const nsACString& aSignature,
                                         nsICacheEntry* aPackageCacheEntry)
 {
   static bool onceThru = false;
   if (!onceThru) {
-    Preferences::AddBoolVarCache(&gDeveloperMode,
-                                 "network.http.packaged-apps-developer-mode", false);
     Preferences::AddBoolVarCache(&gSignedAppEnabled,
-                                 "network.http.packaged-signed-apps-enabled", false);
+                                 "network.http.signed-packages.enabled", false);
     onceThru = true;
   }
 
   mListener = aListener;
   mState = STATE_UNKNOWN;
+  mPackageOrigin = aPackageOrigin;
   mSignature = aSignature;
   mIsPackageSigned = false;
   mPackageCacheEntry = aPackageCacheEntry;
   mIsFirstResource = true;
   mManifest = EmptyCString();
 
+  mBypassVerification = (mPackageOrigin ==
+      Preferences::GetCString("network.http.signed-packages.trusted-origin"));
+
   nsresult rv;
   mPackagedAppUtils = do_CreateInstance(NS_PACKAGEDAPPUTILS_CONTRACTID, &rv);
   if (NS_FAILED(rv)) {
     LOG(("create packaged app utils failed"));
     return rv;
   }
 
   return NS_OK;
@@ -272,18 +275,21 @@ PackagedAppVerifier::VerifyManifest(cons
   if (mSignature.IsEmpty()) {
     LOG(("No signature. No need to do verification."));
     FireVerifiedEvent(true, true);
     return;
   }
 
   LOG(("Signature: length = %u\n%s", mSignature.Length(), mSignature.get()));
   LOG(("Manifest: length = %u\n%s", mManifest.Length(), mManifest.get()));
+
+  bool useDeveloperRoot =
+    !Preferences::GetCString("network.http.signed-packages.developer-root").IsEmpty();
   nsresult rv = mPackagedAppUtils->VerifyManifest(mSignature, mManifest,
-                                                  this, gDeveloperMode);
+                                                  this, useDeveloperRoot);
   if (NS_FAILED(rv)) {
     LOG(("VerifyManifest FAILED rv = %u", (unsigned)rv));
   }
 }
 
 void
 PackagedAppVerifier::VerifyResource(const ResourceCacheInfo* aInfo)
 {
@@ -300,16 +306,22 @@ PackagedAppVerifier::VerifyResource(cons
   aInfo->mURI->GetAsciiSpec(uriAsAscii);
   nsCString* resourceHash = mResourceHashStore.Get(uriAsAscii);
 
   if (!resourceHash) {
     LOG(("Hash value for %s is not computed. ERROR!", uriAsAscii.get()));
     MOZ_CRASH();
   }
 
+  if (mBypassVerification) {
+    LOG(("Origin is trusted. Bypass integrity check."));
+    FireVerifiedEvent(false, true);
+    return;
+  }
+
   if (mSignature.IsEmpty()) {
     LOG(("No signature. No need to do resource integrity check."));
     FireVerifiedEvent(false, true);
     return;
   }
 
   nsAutoCString path;
   nsCOMPtr<nsIURL> url(do_QueryInterface(aInfo->mURI));
@@ -334,17 +346,18 @@ PackagedAppVerifier::OnManifestVerified(
 
   LOG(("PackagedAppVerifier::OnManifestVerified: %d", aSuccess));
 
   // The listener could have been removed before we verify the resource.
   if (!mListener) {
     return;
   }
 
-  if (!aSuccess && gDeveloperMode) {
+
+  if (!aSuccess && mBypassVerification) {
     aSuccess = true;
     LOG(("Developer mode! Treat junk signature valid."));
   }
 
   // Only when the manifest verified and package has signature would we
   // regard this package is signed.
   mIsPackageSigned = aSuccess && !mSignature.IsEmpty();
 
--- a/netwerk/protocol/http/PackagedAppVerifier.h
+++ b/netwerk/protocol/http/PackagedAppVerifier.h
@@ -88,16 +88,17 @@ public:
   private:
     virtual ~ResourceCacheInfo() { }
   };
 
 public:
   PackagedAppVerifier();
 
   PackagedAppVerifier(nsIPackagedAppVerifierListener* aListener,
+                      const nsACString& aPackageOrigin,
                       const nsACString& aSignature,
                       nsICacheEntry* aPackageCacheEntry);
 
   // A internal used function to let the verifier know there's a broken
   // last part.
   void SetHasBrokenLastPart(nsresult aStatusCode);
 
   // Used to explicitly clear the listener to avoid circula reference.
@@ -165,16 +166,19 @@ private:
   nsCString mManifest;
 
   // Whether we're processing the first resource, which is the manfiest
   bool mIsFirstResource;
 
   // Whether this package app is signed.
   bool mIsPackageSigned;
 
+  // Whether we should bypass verification.
+  bool mBypassVerification;
+
   // The package cache entry (e.g. http://foo.com/app.pak) used to store
   // any necessarry signed package information.
   nsCOMPtr<nsICacheEntry> mPackageCacheEntry;
 
   // The resource URI that we are computing its hash.
   nsCString mHashingResourceURI;
 
   // Used to compute resource's hash value.
--- a/netwerk/test/mochitests/test_signed_web_packaged_app.html
+++ b/netwerk/test/mochitests/test_signed_web_packaged_app.html
@@ -16,18 +16,18 @@
 
 var Cc = SpecialPowers.Cc;
 var Ci = SpecialPowers.Ci;
 var Cu = SpecialPowers.Cu;
 var Cr = SpecialPowers.Cr;
 
 SpecialPowers.pushPrefEnv(
   { "set": [["network.http.enable-packaged-apps", true],
-            ["network.http.packaged-signed-apps-enabled", true],
             ["dom.ipc.processPriorityManager.testMode", true],
+            ["network.http.signed-packages.enabled", true],
             ["dom.ipc.processPriorityManager.enabled", true],
             ["dom.ipc.tabs.disabled", false],
             ["dom.ipc.processCount", 3],
             ["dom.mozBrowserFramesEnabled", true]] },
   () => SpecialPowers.pushPermissions([
     { "type": "browser", "allow": 1, "context": document }
   ], function() {
     runTest();
--- a/netwerk/test/unit/test_packaged_app_channel.js
+++ b/netwerk/test/unit/test_packaged_app_channel.js
@@ -206,41 +206,57 @@ function run_test()
   httpserver.registerPathHandler("/package", contentHandler);
   httpserver.registerPathHandler("/regular", regularContentHandler);
   httpserver.registerPathHandler("/package_with_good_signature", contentHandlerWithGoodSignature);
   httpserver.registerPathHandler("/package_with_bad_signature", contentHandlerWithBadSignature);
   httpserver.start(-1);
 
   // Enable the feature and save the original pref value
   originalPref = Services.prefs.getBoolPref("network.http.enable-packaged-apps");
-  originalSignedAppEnabled = Services.prefs.getBoolPref("network.http.packaged-signed-apps-enabled");
+  originalSignedAppEnabled = Services.prefs.getBoolPref("network.http.signed-packages.enabled");
   Services.prefs.setBoolPref("network.http.enable-packaged-apps", true);
-  Services.prefs.setBoolPref("network.http.packaged-signed-apps-enabled", true);
+  Services.prefs.setBoolPref("network.http.signed-packages.enabled", true);
   do_register_cleanup(reset_pref);
 
   add_test(test_channel);
   add_test(test_channel_no_notificationCallbacks);
   add_test(test_channel_uris);
 
+  add_test(test_channel_with_bad_signature_from_trusted_origin);
   add_test(test_channel_with_bad_signature);
   add_test(test_channel_with_good_signature);
 
   // run tests
   run_next_test();
 }
 
 function test_channel_with_bad_signature() {
   var channel = make_channel(uri+"/package_with_bad_signature!//index.html");
   channel.notificationCallbacks = new LoadContextCallback(1024, false, false, false);
   channel.asyncOpen(new Listener(function(l) {
     do_check_true(l.gotFileNotFound);
     run_next_test();
   }), null);
 }
 
+function test_channel_with_bad_signature_from_trusted_origin() {
+  let pref = "network.http.signed-packages.trusted-origin";
+  ok(!!Ci.nsISupportsString, "Ci.nsISupportsString");
+  let origin = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
+  origin.data = uri + "^appId=1024";
+  Services.prefs.setComplexValue(pref, Ci.nsISupportsString, origin);
+  var channel = make_channel(uri+"/package_with_bad_signature!//index.html");
+  channel.notificationCallbacks = new LoadContextCallback(1024, false, false, false);
+  channel.asyncOpen(new Listener(function(l) {
+    do_check_true(l.gotStopRequestOK);
+    Services.prefs.clearUserPref(pref);
+    run_next_test();
+  }), null);
+}
+
 function test_channel_with_good_signature() {
   var channel = make_channel(uri+"/package_with_good_signature!//index.html");
   channel.notificationCallbacks = new LoadContextCallback(1024, false, false, false);
   channel.asyncOpen(new Listener(function(l) {
     do_check_true(l.gotStopRequestOK);
     run_next_test();
   }), null);
 }
@@ -276,10 +292,10 @@ function check_regular_response(request,
   do_check_eq(request.responseStatus, 200);
   do_check_eq(buffer, "response");
   run_next_test();
 }
 
 function reset_pref() {
   // Set the pref to its original value
   Services.prefs.setBoolPref("network.http.enable-packaged-apps", originalPref);
-  Services.prefs.setBoolPref("network.http.packaged-signed-apps-enabled", originalSignedAppEnabled);
+  Services.prefs.setBoolPref("network.http.signed-packages.enabled", originalSignedAppEnabled);
 }
--- a/netwerk/test/unit/test_packaged_app_service.js
+++ b/netwerk/test/unit/test_packaged_app_service.js
@@ -215,30 +215,25 @@ function run_test()
   for (let i = 0; i < worsePackageNum; i++) {
     httpserver.registerPathHandler("/worsePackage_" + i,
                                    packagedAppWorseContentHandler.bind(null, i));
   }
 
   httpserver.registerPathHandler("/signedPackage", signedPackagedAppContentHandler);
   httpserver.start(-1);
 
-  // We will enable the developer mode in 'test_signed_package_callback'.
-  // So restore it after testing.
-  //
-  // TODO: To be removed in Bug 1178518.
   do_register_cleanup(function() {
-    gPrefs.clearUserPref("network.http.packaged-apps-developer-mode");
-    gPrefs.clearUserPref("network.http.packaged-signed-apps-enabled");
+    gPrefs.clearUserPref("network.http.signed-packages.enabled");
   });
 
   paservice = Cc["@mozilla.org/network/packaged-app-service;1"]
                      .getService(Ci.nsIPackagedAppService);
   ok(!!paservice, "test service exists");
 
-  gPrefs.setBoolPref("network.http.packaged-signed-apps-enabled", true);
+  gPrefs.setBoolPref("network.http.signed-packages.enabled", true);
 
   add_test(test_bad_args);
 
   add_test(test_callback_gets_called);
   add_test(test_same_content);
   add_test(test_request_number);
   add_test(test_updated_package);
 
--- a/netwerk/test/unit/test_packaged_app_verifier.js
+++ b/netwerk/test/unit/test_packaged_app_verifier.js
@@ -35,26 +35,16 @@ var gCacheStorageService = Cc["@mozilla.
 var gLoadContextInfoFactory =
   Cu.import("resource://gre/modules/LoadContextInfo.jsm", {}).LoadContextInfo;
 
 const kUriIdx                 = 0;
 const kStatusCodeIdx          = 1;
 const kVerificationSuccessIdx = 2;
 const kContentIdx             = 3;
 
-function enable_developer_mode()
-{
-  gPrefs.setBoolPref("network.http.packaged-apps-developer-mode", true);
-}
-
-function reset_developer_mode()
-{
-  gPrefs.clearUserPref("network.http.packaged-apps-developer-mode");
-}
-
 function createVerifierListener(aExpecetedCallbacks,
                                 aExpectedPackageId,
                                 aExpectedIsSigned,
                                 aPackageCacheEntry) {
   let cnt = 0;
 
   return {
     onVerified: function(aIsManifest,
@@ -85,17 +75,16 @@ function createVerifierListener(aExpecet
         ok(!!aPackageCacheEntry, aPackageCacheEntry.key);
         let signePakIdInCache = aPackageCacheEntry.getMetaDataElement('package-id');
         equal(signePakIdInCache,
               (aExpectedIsSigned ? aExpectedPackageId : ''),
               'package-id in cache');
       }
 
       if (isLastPart) {
-        reset_developer_mode();
         run_next_test();
       }
     },
   };
 };
 
 function feedData(aString) {
   let stringStream = Cc["@mozilla.org/io/string-input-stream;1"].
@@ -132,97 +121,107 @@ function feedResources(aExpectedCallback
 function createPackageCache(aPackageUriAsAscii, aLoadContextInfo) {
   let cacheStorage =
       gCacheStorageService.memoryCacheStorage(aLoadContextInfo);
 
   let uri = gIoService.newURI(aPackageUriAsAscii, null, null);
   return cacheStorage.openTruncate(uri, '');
 }
 
-function test_no_signature(aDeveloperMode) {
+function test_no_signature(aBypassVerification) {
   const kOrigin = 'http://foo.com';
 
-  aDeveloperMode = !!aDeveloperMode;
+  aBypassVerification = !!aBypassVerification;
 
-  // If the package has no signature and not in developer mode, the package is unsigned
+  // If the package has no signature, the package is unsigned
   // but the verification result is always true.
 
   const expectedCallbacks = [
   // URL                    statusCode   verificationResult
     [kOrigin + '/manifest', Cr.NS_OK,    true],
     [kOrigin + '/1.html',   Cr.NS_OK,    true],
     [kOrigin + '/2.js',     Cr.NS_OK,    true],
     [kOrigin + '/3.jpg',    Cr.NS_OK,    true],
     [kOrigin + '/4.html',   Cr.NS_OK,    true],
     [kOrigin + '/5.css',    Cr.NS_OK,    true],
   ];
 
   let isPackageSigned = false;
 
   // We only require the package URL to be different in each test case.
-  let packageUriString = kOrigin + '/pak' + (aDeveloperMode ? '-dev' : '');
+  let packageUriString = kOrigin + '/pak' + (aBypassVerification ? '-dev' : '');
 
   let packageCacheEntry =
     createPackageCache(packageUriString, gLoadContextInfoFactory.default);
 
   let verifierListener = createVerifierListener(expectedCallbacks,
                                                 '',
                                                 isPackageSigned,
                                                 packageCacheEntry);
 
-  gVerifier.init(verifierListener, '', packageCacheEntry);
+  gVerifier.init(verifierListener, kOrigin, '', packageCacheEntry);
 
   feedResources(expectedCallbacks, '');
 }
 
-function test_invalid_signature(aDeveloperMode) {
+function test_invalid_signature(aBypassVerification) {
   const kOrigin = 'http://bar.com';
 
-  aDeveloperMode = !!aDeveloperMode;
+  aBypassVerification = !!aBypassVerification;
 
   // Since we haven't implemented signature verification, the verification always
   // fails if the signature exists.
 
-  let verificationResult = aDeveloperMode; // Verification always success in developer mode.
-  let isPackageSigned = aDeveloperMode;   // Package is always considered as signed in developer mode.
+  let verificationResult = aBypassVerification; // Verification always success in developer mode.
+  let isPackageSigned = aBypassVerification;   // Package is always considered as signed in developer mode.
 
   const kPackagedId = '611FC2FE-491D-4A47-B3B3-43FBDF6F404F';
   const kManifestContent = 'Content-Location: manifest.webapp\r\n' +
                            'Content-Type: application/x-web-app-manifest+json\r\n' +
                            '\r\n' +
                            '{ "package-identifier": "' + kPackagedId + '" }';
 
   const expectedCallbacks = [
   // URL                      statusCode   verificationResult     content
     [kOrigin + '/manifest',   Cr.NS_OK,    verificationResult,    kManifestContent],
-    [kOrigin + '/1.html',     Cr.NS_OK,    verificationResult],
-    [kOrigin + '/2.js',       Cr.NS_OK,    verificationResult],
-    [kOrigin + '/3.jpg',      Cr.NS_OK,    verificationResult],
-    [kOrigin + '/4.html',     Cr.NS_OK,    verificationResult],
-    [kOrigin + '/5.css',      Cr.NS_OK,    verificationResult],
+    [kOrigin + '/1.html',     Cr.NS_OK,    verificationResult, 'abc'],
+    [kOrigin + '/2.js',       Cr.NS_OK,    verificationResult, 'abc'],
+    [kOrigin + '/3.jpg',      Cr.NS_OK,    verificationResult, 'abc'],
+    [kOrigin + '/4.html',     Cr.NS_OK,    verificationResult, 'abc'],
+    [kOrigin + '/5.css',      Cr.NS_OK,    verificationResult, 'abc'],
   ];
 
-  let packageUriString = kOrigin + '/pak' + (aDeveloperMode ? '-dev' : '');
+  let packageUriString = kOrigin + '/pak' + (aBypassVerification ? '-dev' : '');
   let packageCacheEntry =
     createPackageCache(packageUriString, gLoadContextInfoFactory.private);
 
   let verifierListener = createVerifierListener(expectedCallbacks,
-                                                aDeveloperMode ? kPackagedId : '',
+                                                aBypassVerification ? kPackagedId : '',
                                                 isPackageSigned,
                                                 packageCacheEntry);
 
   let signature = 'manifest-signature: 11111111111111111111111';
-  gVerifier.init(verifierListener, signature, packageCacheEntry);
+  gVerifier.init(verifierListener, kOrigin, signature, packageCacheEntry);
 
   feedResources(expectedCallbacks, signature);
 }
 
+function test_invalid_signature_bypass_verification() {
+  let pref = "network.http.signed-packages.trusted-origin";
+  ok(!!Ci.nsISupportsString, "Ci.nsISupportsString");
+  let origin = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
+  origin.data = "http://bar.com";
+  gPrefs.setComplexValue(pref, Ci.nsISupportsString, origin);
+  test_invalid_signature(true);
+  gPrefs.clearUserPref(pref);
+}
+
 function run_test()
 {
   ok(!!gVerifier);
 
-  // Test cases in non-developer mode.
   add_test(test_no_signature);
   add_test(test_invalid_signature);
+  add_test(test_invalid_signature_bypass_verification);
 
   // run tests
   run_next_test();
 }
--- a/security/apps/AppTrustDomain.cpp
+++ b/security/apps/AppTrustDomain.cpp
@@ -36,17 +36,17 @@
 #include "privileged-package-root.inc"
 
 using namespace mozilla::pkix;
 
 extern PRLogModuleInfo* gPIPNSSLog;
 
 static const unsigned int DEFAULT_MIN_RSA_BITS = 2048;
 static char kDevImportedDER[] =
-  "network.http.packaged-apps-developer-trusted-root";
+  "network.http.signed-packages.developer-root";
 
 namespace mozilla { namespace psm {
 
 StaticMutex AppTrustDomain::sMutex;
 nsAutoArrayPtr<unsigned char> AppTrustDomain::sDevImportedDERData(nullptr);
 unsigned int AppTrustDomain::sDevImportedDERLen = 0;
 
 AppTrustDomain::AppTrustDomain(ScopedCERTCertList& certChain, void* pinArg)