browser_webauthn_cert_override.js (5481B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 let expectSecurityError = expectError("Security"); 8 9 async function test_webauthn_with_cert_override({ 10 aTestDomain, 11 aExpectSecurityError = false, 12 aFeltPrivacyV1 = false, 13 aAllowCertificateOverrideByPref = false, 14 }) { 15 let authenticatorId = add_virtual_authenticator(/*autoremove*/ false); 16 17 let certOverrideService = Cc[ 18 "@mozilla.org/security/certoverride;1" 19 ].getService(Ci.nsICertOverrideService); 20 Services.prefs.setBoolPref( 21 "security.certerrors.felt-privacy-v1", 22 aFeltPrivacyV1 23 ); 24 Services.prefs.setBoolPref("network.proxy.allow_hijacking_localhost", true); 25 Services.prefs.setBoolPref( 26 "security.webauthn.allow_with_certificate_override", 27 aAllowCertificateOverrideByPref 28 ); 29 let testURL = "https://" + aTestDomain; 30 let certErrorLoaded; 31 let tab = await BrowserTestUtils.openNewForegroundTab( 32 gBrowser, 33 () => { 34 gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, testURL); 35 let browser = gBrowser.selectedBrowser; 36 certErrorLoaded = BrowserTestUtils.waitForErrorPage(browser); 37 }, 38 false 39 ); 40 info("Waiting for cert error page."); 41 await certErrorLoaded; 42 43 let loaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser); 44 45 info("Adding certificate error override."); 46 await SpecialPowers.spawn( 47 tab.linkedBrowser, 48 [aFeltPrivacyV1], 49 async function (aFeltPrivacyV1) { 50 const doc = content.document; 51 52 if (!aFeltPrivacyV1) { 53 info("Using old cert error page flow."); 54 let doc = content.document; 55 let exceptionButton = doc.getElementById("exceptionDialogButton"); 56 exceptionButton.click(); 57 } else { 58 info("Using felt-privacy-v1 cert error page flow."); 59 const netErrorCard = 60 doc.querySelector("net-error-card").wrappedJSObject; 61 await netErrorCard.getUpdateComplete(); 62 await EventUtils.synthesizeMouseAtCenter( 63 netErrorCard.advancedButton, 64 {}, 65 content 66 ); 67 await ContentTaskUtils.waitForCondition(() => { 68 return ( 69 netErrorCard.exceptionButton && 70 !netErrorCard.exceptionButton.disabled 71 ); 72 }, "Waiting for exception button"); 73 netErrorCard.exceptionButton.scrollIntoView(); 74 EventUtils.synthesizeMouseAtCenter( 75 netErrorCard.exceptionButton, 76 {}, 77 content 78 ); 79 } 80 } 81 ); 82 83 info("Waiting for page load."); 84 await loaded; 85 86 await SpecialPowers.spawn(tab.linkedBrowser, [], async function () { 87 let doc = content.document; 88 ok( 89 !doc.documentURI.startsWith("about:certerror"), 90 "Exception has been added." 91 ); 92 }); 93 94 let makeCredPromise = promiseWebAuthnMakeCredential(tab, "none", "preferred"); 95 if (aExpectSecurityError) { 96 await makeCredPromise.then(arrivingHereIsBad).catch(expectSecurityError); 97 ok( 98 true, 99 "Calling navigator.credentials.create() results in a security error" 100 ); 101 } else { 102 await makeCredPromise.catch(arrivingHereIsBad); 103 ok(true, "Calling navigator.credentials.create() is allowed"); 104 } 105 106 let getAssertionPromise = promiseWebAuthnGetAssertionDiscoverable(tab); 107 if (aExpectSecurityError) { 108 await getAssertionPromise 109 .then(arrivingHereIsBad) 110 .catch(expectSecurityError); 111 ok(true, "Calling navigator.credentials.get() results in a security error"); 112 } else { 113 await getAssertionPromise.catch(arrivingHereIsBad); 114 ok(true, "Calling navigator.credentials.get() results in a security error"); 115 } 116 117 certOverrideService.clearValidityOverride(aTestDomain, -1, {}); 118 119 loaded = BrowserTestUtils.waitForErrorPage(tab.linkedBrowser); 120 BrowserCommands.reloadSkipCache(); 121 await loaded; 122 123 BrowserTestUtils.removeTab(gBrowser.selectedTab); 124 125 remove_virtual_authenticator(authenticatorId); 126 127 Services.prefs.clearUserPref( 128 "security.webauthn.allow_with_certificate_override" 129 ); 130 Services.prefs.clearUserPref("network.proxy.allow_hijacking_localhost"); 131 Services.prefs.clearUserPref("security.certerrors.felt-privacy-v1"); 132 } 133 134 for (let feltPrivacyV1 of [false, true]) { 135 add_task(() => 136 test_webauthn_with_cert_override({ 137 aTestDomain: "expired.example.com", 138 aExpectSecurityError: false, 139 aFeltPrivacyV1: feltPrivacyV1, 140 aAllowCertificateOverrideByPref: false, 141 }) 142 ); 143 add_task(() => 144 test_webauthn_with_cert_override({ 145 aTestDomain: "untrusted.example.com", 146 aExpectSecurityError: true, 147 aFeltPrivacyV1: feltPrivacyV1, 148 aAllowCertificateOverrideByPref: false, 149 }) 150 ); 151 add_task(() => 152 test_webauthn_with_cert_override({ 153 aTestDomain: "no-subject-alt-name.example.com", 154 aExpectSecurityError: true, 155 aFeltPrivacyV1: feltPrivacyV1, 156 aAllowCertificateOverrideByPref: false, 157 }) 158 ); 159 add_task(() => 160 test_webauthn_with_cert_override({ 161 aTestDomain: "badcertdomain.localhost", 162 aExpectSecurityError: false, 163 aFeltPrivacyV1: feltPrivacyV1, 164 aAllowCertificateOverrideByPref: false, 165 }) 166 ); 167 add_task(() => 168 test_webauthn_with_cert_override({ 169 aTestDomain: "untrusted.example.com", 170 aExpectSecurityError: false, 171 aFeltPrivacyV1: feltPrivacyV1, 172 aAllowCertificateOverrideByPref: true, 173 }) 174 ); 175 }