browser_check_identity_state.js (20336B)
1 /* 2 * Test the identity mode UI for a variety of page types 3 */ 4 5 "use strict"; 6 7 const DUMMY = "browser/browser/base/content/test/siteIdentity/dummy_page.html"; 8 const INSECURE_TEXT_PREF = "security.insecure_connection_text.enabled"; 9 const HTTPS_FIRST_PBM_PREF = "dom.security.https_first_pbm"; 10 11 const NOT_SECURE_LABEL = Services.prefs.getBoolPref( 12 "security.insecure_connection_text.enabled", 13 true 14 ) 15 ? "notSecure notSecureText" 16 : "notSecure"; 17 const NOT_SECURE_LABEL_PBMODE = Services.prefs.getBoolPref( 18 "security.insecure_connection_text.pbmode.enabled", 19 true 20 ) 21 ? "notSecure notSecureText" 22 : "notSecure"; 23 24 function loadNewTab(url) { 25 return BrowserTestUtils.openNewForegroundTab(gBrowser, url, true); 26 } 27 28 function getConnectionState() { 29 // Prevents items that are being lazy loaded causing issues 30 document.getElementById("identity-icon-box").click(); 31 gIdentityHandler.refreshIdentityPopup(); 32 return document.getElementById("identity-popup").getAttribute("connection"); 33 } 34 35 function getSecurityConnectionBG() { 36 // Get the background image of the security connection. 37 document.getElementById("identity-icon-box").click(); 38 gIdentityHandler.refreshIdentityPopup(); 39 return gBrowser.ownerGlobal 40 .getComputedStyle( 41 document 42 .getElementById("identity-popup-mainView") 43 .getElementsByClassName("identity-popup-security-connection")[0] 44 ) 45 .getPropertyValue("list-style-image"); 46 } 47 48 async function getReaderModeURL() { 49 // Gets the reader mode URL from "identity-popup mainView panel header span" 50 document.getElementById("identity-icon-box").click(); 51 gIdentityHandler.refreshIdentityPopup(); 52 53 let headerSpan = document.getElementById( 54 "identity-popup-mainView-panel-header-span" 55 ); 56 await BrowserTestUtils.waitForCondition(() => 57 headerSpan.innerHTML.includes("example.com") 58 ); 59 return headerSpan.innerHTML; 60 } 61 62 // This test is slow on Linux debug e10s 63 requestLongerTimeout(2); 64 65 add_task(async function chromeUITest() { 66 // needs to be set due to bug in ion.js that occurs when testing 67 SpecialPowers.pushPrefEnv({ 68 set: [ 69 ["toolkit.pioneer.testCachedContent", "[]"], 70 ["toolkit.pioneer.testCachedAddons", "[]"], 71 ], 72 }); 73 // Might needs to be extended with new secure chrome pages 74 // about:debugging is a secure chrome UI but is not tested for causing problems. 75 let secureChromePages = [ 76 "addons", 77 "cache", 78 "certificate", 79 "compat", 80 "config", 81 "downloads", 82 "license", 83 "logins", 84 "loginsimportreport", 85 "performance", 86 "policies", 87 "preferences", 88 "processes", 89 "profiles", 90 "profiling", 91 "protections", 92 "sessionrestore", 93 "studies", 94 "support", 95 "telemetry", 96 "welcomeback", 97 ]; 98 99 // else skip about:crashes, it is only available with plugin 100 if (AppConstants.MOZ_CRASHREPORTER) { 101 secureChromePages.push("crashes"); 102 } 103 104 let nonSecureExamplePages = [ 105 "about:about", 106 "about:credits", 107 "about:home", 108 "about:logo", 109 "about:memory", 110 "about:mozilla", 111 "about:networking", 112 "about:privatebrowsing", 113 "about:robots", 114 "about:serviceWorkers", 115 "about:sync-log", 116 "about:unloads", 117 "about:url-classifier", 118 "about:webrtc", 119 "about:welcome", 120 "about:rights", 121 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 122 "http://example.com/" + DUMMY, 123 ]; 124 125 for (let i = 0; i < secureChromePages.length; i++) { 126 await BrowserTestUtils.withNewTab("about:" + secureChromePages[i], () => { 127 is(getIdentityMode(), "chromeUI", "Identity should be chromeUI"); 128 }); 129 } 130 131 for (let i = 0; i < nonSecureExamplePages.length; i++) { 132 console.log(nonSecureExamplePages[i]); 133 await BrowserTestUtils.withNewTab(nonSecureExamplePages[i], () => { 134 Assert.notEqual( 135 getIdentityMode(), 136 "chromeUI", 137 "Identity should not be chromeUI" 138 ); 139 }); 140 } 141 }); 142 143 add_task(async function test_webpage() { 144 let oldTab = await loadNewTab("about:robots"); 145 146 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 147 let newTab = await loadNewTab("http://example.com/" + DUMMY); 148 is(getIdentityMode(), NOT_SECURE_LABEL, "Identity should be not secure"); 149 150 gBrowser.selectedTab = oldTab; 151 is(getIdentityMode(), "localResource", "Identity should be localResource"); 152 153 gBrowser.selectedTab = newTab; 154 is(getIdentityMode(), NOT_SECURE_LABEL, "Identity should be not secure"); 155 156 gBrowser.removeTab(newTab); 157 gBrowser.removeTab(oldTab); 158 }); 159 160 async function webpageTestTextWarning(secureCheck) { 161 await SpecialPowers.pushPrefEnv({ set: [[INSECURE_TEXT_PREF, secureCheck]] }); 162 let oldTab = await loadNewTab("about:robots"); 163 164 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 165 let newTab = await loadNewTab("http://example.com/" + DUMMY); 166 if (secureCheck) { 167 is( 168 getIdentityMode(), 169 "notSecure notSecureText", 170 "Identity should have not secure text" 171 ); 172 } else { 173 is(getIdentityMode(), "notSecure", "Identity should be not secure"); 174 } 175 176 gBrowser.selectedTab = oldTab; 177 is(getIdentityMode(), "localResource", "Identity should be localResource"); 178 179 gBrowser.selectedTab = newTab; 180 if (secureCheck) { 181 is( 182 getIdentityMode(), 183 "notSecure notSecureText", 184 "Identity should have not secure text" 185 ); 186 } else { 187 is(getIdentityMode(), "notSecure", "Identity should be not secure"); 188 } 189 190 gBrowser.removeTab(newTab); 191 gBrowser.removeTab(oldTab); 192 await SpecialPowers.popPrefEnv(); 193 } 194 195 add_task(async function test_webpage_text_warning() { 196 await webpageTestTextWarning(false); 197 await webpageTestTextWarning(true); 198 }); 199 200 async function webpageTestTextWarningCombined(secureCheck) { 201 await SpecialPowers.pushPrefEnv({ 202 set: [[INSECURE_TEXT_PREF, secureCheck]], 203 }); 204 let oldTab = await loadNewTab("about:robots"); 205 206 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 207 let newTab = await loadNewTab("http://example.com/" + DUMMY); 208 if (secureCheck) { 209 is( 210 getIdentityMode(), 211 "notSecure notSecureText", 212 "Identity should be not secure" 213 ); 214 } 215 216 gBrowser.selectedTab = oldTab; 217 is(getIdentityMode(), "localResource", "Identity should be unknown"); 218 219 gBrowser.selectedTab = newTab; 220 if (secureCheck) { 221 is( 222 getIdentityMode(), 223 "notSecure notSecureText", 224 "Identity should be not secure" 225 ); 226 } 227 228 gBrowser.removeTab(newTab); 229 gBrowser.removeTab(oldTab); 230 await SpecialPowers.popPrefEnv(); 231 } 232 233 add_task(async function test_webpage_text_warning_combined() { 234 await webpageTestTextWarningCombined(false); 235 await webpageTestTextWarningCombined(true); 236 }); 237 238 add_task(async function test_blank_page() { 239 let oldTab = await loadNewTab("about:robots"); 240 241 let newTab = await loadNewTab("about:blank"); 242 is( 243 gURLBar.getAttribute("pageproxystate"), 244 "invalid", 245 "pageproxystate should be invalid" 246 ); 247 248 gBrowser.selectedTab = oldTab; 249 is( 250 gURLBar.getAttribute("pageproxystate"), 251 "valid", 252 "pageproxystate should be valid" 253 ); 254 is(getIdentityMode(), "localResource", "Identity should be localResource"); 255 256 gBrowser.selectedTab = newTab; 257 is( 258 gURLBar.getAttribute("pageproxystate"), 259 "invalid", 260 "pageproxystate should be invalid" 261 ); 262 263 gBrowser.removeTab(newTab); 264 gBrowser.removeTab(oldTab); 265 }); 266 267 add_task(async function test_secure() { 268 let oldTab = await loadNewTab("about:robots"); 269 270 let newTab = await loadNewTab("https://example.com/" + DUMMY); 271 is(getIdentityMode(), "verifiedDomain", "Identity should be verified"); 272 273 gBrowser.selectedTab = oldTab; 274 is(getIdentityMode(), "localResource", "Identity should be localResource"); 275 276 gBrowser.selectedTab = newTab; 277 is(getIdentityMode(), "verifiedDomain", "Identity should be verified"); 278 279 gBrowser.removeTab(newTab); 280 gBrowser.removeTab(oldTab); 281 }); 282 283 add_task(async function test_view_source() { 284 let sourceTab = await loadNewTab("view-source:https://example.com/" + DUMMY); 285 286 gBrowser.selectedTab = sourceTab; 287 is( 288 getIdentityMode(), 289 "verifiedDomain", 290 "Identity should be verified while viewing source" 291 ); 292 293 gBrowser.removeTab(sourceTab); 294 }); 295 296 add_task(async function test_insecure() { 297 let oldTab = await loadNewTab("about:robots"); 298 299 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 300 let newTab = await loadNewTab("http://example.com/" + DUMMY); 301 is(getIdentityMode(), NOT_SECURE_LABEL, "Identity should be not secure"); 302 is( 303 document.getElementById("identity-icon").getAttribute("tooltiptext"), 304 gNavigatorBundle.getString("identity.notSecure.tooltip"), 305 "The insecure lock icon has a correct tooltip text." 306 ); 307 308 gBrowser.selectedTab = oldTab; 309 is(getIdentityMode(), "localResource", "Identity should be localResource"); 310 311 gBrowser.selectedTab = newTab; 312 is(getIdentityMode(), NOT_SECURE_LABEL, "Identity should be not secure"); 313 is( 314 document.getElementById("identity-icon").getAttribute("tooltiptext"), 315 gNavigatorBundle.getString("identity.notSecure.tooltip"), 316 "The insecure lock icon has a correct tooltip text." 317 ); 318 319 gBrowser.removeTab(newTab); 320 gBrowser.removeTab(oldTab); 321 }); 322 323 add_task(async function test_addons() { 324 let oldTab = await loadNewTab("about:robots"); 325 326 let newTab = await loadNewTab("about:addons"); 327 is(getIdentityMode(), "chromeUI", "Identity should be chrome"); 328 329 gBrowser.selectedTab = oldTab; 330 is(getIdentityMode(), "localResource", "Identity should be localResource"); 331 332 gBrowser.selectedTab = newTab; 333 is(getIdentityMode(), "chromeUI", "Identity should be chrome"); 334 335 gBrowser.removeTab(newTab); 336 gBrowser.removeTab(oldTab); 337 }); 338 339 add_task(async function test_file() { 340 let oldTab = await loadNewTab("about:robots"); 341 let fileURI = getTestFilePath(""); 342 343 let newTab = await loadNewTab(fileURI); 344 is(getConnectionState(), "file", "Connection should be file"); 345 346 gBrowser.selectedTab = oldTab; 347 is(getIdentityMode(), "localResource", "Identity should be localResource"); 348 349 gBrowser.selectedTab = newTab; 350 is(getConnectionState(), "file", "Connection should be file"); 351 352 gBrowser.removeTab(newTab); 353 gBrowser.removeTab(oldTab); 354 }); 355 356 add_task(async function test_resource_uri() { 357 let oldTab = await loadNewTab("about:robots"); 358 let dataURI = "resource://gre/modules/XPCOMUtils.sys.mjs"; 359 360 let newTab = await loadNewTab(dataURI); 361 362 is(getConnectionState(), "file", "Connection should be file"); 363 364 gBrowser.selectedTab = oldTab; 365 is( 366 getIdentityMode(), 367 "localResource", 368 "Identity should be a local a resource" 369 ); 370 371 gBrowser.selectedTab = newTab; 372 is(getConnectionState(), "file", "Connection should be file"); 373 374 gBrowser.removeTab(newTab); 375 gBrowser.removeTab(oldTab); 376 }); 377 378 add_task(async function test_no_cert_error() { 379 let oldTab = await loadNewTab("about:robots"); 380 let newTab = BrowserTestUtils.addTab(gBrowser); 381 gBrowser.selectedTab = newTab; 382 383 let promise = BrowserTestUtils.waitForErrorPage(gBrowser.selectedBrowser); 384 BrowserTestUtils.startLoadingURIString( 385 gBrowser, 386 "https://nocert.example.com/" 387 ); 388 await promise; 389 is( 390 getIdentityMode(), 391 "certErrorPage notSecureText", 392 "Identity should be the cert error page." 393 ); 394 is( 395 getConnectionState(), 396 "cert-error-page", 397 "Connection should be the cert error page." 398 ); 399 400 gBrowser.selectedTab = oldTab; 401 is(getIdentityMode(), "localResource", "Identity should be localResource"); 402 403 gBrowser.selectedTab = newTab; 404 is( 405 getIdentityMode(), 406 "certErrorPage notSecureText", 407 "Identity should be the cert error page." 408 ); 409 is( 410 getConnectionState(), 411 "cert-error-page", 412 "Connection should be the cert error page." 413 ); 414 415 gBrowser.removeTab(newTab); 416 gBrowser.removeTab(oldTab); 417 }); 418 419 add_task(async function test_https_only_error() { 420 let oldTab = await loadNewTab("about:robots"); 421 await SpecialPowers.pushPrefEnv({ 422 set: [["dom.security.https_only_mode", true]], 423 }); 424 let newTab = BrowserTestUtils.addTab(gBrowser); 425 gBrowser.selectedTab = newTab; 426 427 let promise = BrowserTestUtils.waitForErrorPage(gBrowser.selectedBrowser); 428 BrowserTestUtils.startLoadingURIString( 429 gBrowser, 430 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 431 "http://nocert.example.com/" 432 ); 433 await promise; 434 is( 435 getIdentityMode(), 436 "httpsOnlyErrorPage", 437 "Identity should be the https-only mode error page." 438 ); 439 is( 440 getConnectionState(), 441 "https-only-error-page", 442 "Connection should be the https-only mode error page." 443 ); 444 445 gBrowser.selectedTab = oldTab; 446 is(getIdentityMode(), "localResource", "Identity should be localResource"); 447 448 gBrowser.selectedTab = newTab; 449 is( 450 getIdentityMode(), 451 "httpsOnlyErrorPage", 452 "Identity should be the https-only mode error page." 453 ); 454 is( 455 getConnectionState(), 456 "https-only-error-page", 457 "Connection should be the https-only mode page." 458 ); 459 460 gBrowser.removeTab(newTab); 461 gBrowser.removeTab(oldTab); 462 463 await SpecialPowers.popPrefEnv(); 464 }); 465 466 add_task(async function test_no_cert_error_from_navigation() { 467 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 468 let newTab = await loadNewTab("http://example.com/" + DUMMY); 469 470 let promise = BrowserTestUtils.waitForErrorPage(gBrowser.selectedBrowser); 471 await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { 472 content.document.getElementById("no-cert").click(); 473 }); 474 await promise; 475 await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { 476 is( 477 content.window.location.href, 478 "https://nocert.example.com/", 479 "Should be the cert error URL" 480 ); 481 }); 482 483 is( 484 newTab.linkedBrowser.documentURI.spec.startsWith("about:certerror?"), 485 true, 486 "Should be an about:certerror" 487 ); 488 is( 489 getIdentityMode(), 490 "certErrorPage notSecureText", 491 "Identity should be the cert error page." 492 ); 493 is( 494 getConnectionState(), 495 "cert-error-page", 496 "Connection should be the cert error page." 497 ); 498 499 gBrowser.removeTab(newTab); 500 }); 501 502 add_task(async function test_tls_error_page() { 503 const TLS10_PAGE = "https://tls1.example.com/"; 504 await SpecialPowers.pushPrefEnv({ 505 set: [ 506 ["security.tls.version.min", 3], 507 ["security.tls.version.max", 4], 508 ], 509 }); 510 511 let browser; 512 let pageLoaded; 513 await BrowserTestUtils.openNewForegroundTab( 514 gBrowser, 515 () => { 516 gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, TLS10_PAGE); 517 browser = gBrowser.selectedBrowser; 518 pageLoaded = BrowserTestUtils.waitForErrorPage(browser); 519 }, 520 false 521 ); 522 523 info("Loading and waiting for the net error"); 524 await pageLoaded; 525 526 await SpecialPowers.spawn(browser, [], function () { 527 const doc = content.document; 528 ok( 529 doc.documentURI.startsWith("about:neterror"), 530 "Should be showing error page" 531 ); 532 }); 533 534 is( 535 getConnectionState(), 536 "cert-error-page", 537 "Connection state should be the cert error page." 538 ); 539 540 BrowserTestUtils.removeTab(gBrowser.selectedTab); 541 542 await SpecialPowers.popPrefEnv(); 543 }); 544 545 add_task(async function test_net_error_page() { 546 // Connect to a server that rejects all requests, to test network error pages: 547 let { HttpServer } = ChromeUtils.importESModule( 548 "resource://testing-common/httpd.sys.mjs" 549 ); 550 let server = new HttpServer(); 551 server.registerPrefixHandler("/", (req, res) => 552 res.abort(new Error("Noooope.")) 553 ); 554 server.start(-1); 555 let port = server.identity.primaryPort; 556 const ERROR_PAGE = `http://localhost:${port}/`; 557 558 let browser; 559 let pageLoaded; 560 await BrowserTestUtils.openNewForegroundTab( 561 gBrowser, 562 () => { 563 gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, ERROR_PAGE); 564 browser = gBrowser.selectedBrowser; 565 pageLoaded = BrowserTestUtils.waitForErrorPage(browser); 566 }, 567 false 568 ); 569 570 info("Loading and waiting for the net error"); 571 await pageLoaded; 572 573 await SpecialPowers.spawn(browser, [], function () { 574 const doc = content.document; 575 ok( 576 doc.documentURI.startsWith("about:neterror"), 577 "Should be showing error page" 578 ); 579 }); 580 581 is( 582 getConnectionState(), 583 "net-error-page", 584 "Connection should be the net error page." 585 ); 586 587 BrowserTestUtils.removeTab(gBrowser.selectedTab); 588 }); 589 590 add_task(async function test_about_blocked() { 591 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 592 let url = "http://www.itisatrap.org/firefox/its-an-attack.html"; 593 let oldTab = await loadNewTab("about:robots"); 594 await SpecialPowers.pushPrefEnv({ 595 set: [["urlclassifier.blockedTable", "moztest-block-simple"]], 596 }); 597 let newTab = BrowserTestUtils.addTab(gBrowser); 598 gBrowser.selectedTab = newTab; 599 600 BrowserTestUtils.startLoadingURIString(gBrowser.selectedBrowser, url); 601 602 await BrowserTestUtils.browserLoaded( 603 gBrowser.selectedBrowser, 604 false, 605 url, 606 true 607 ); 608 609 is(getIdentityMode(), "unknownIdentity", "Identity should be unknown."); 610 is(getConnectionState(), "not-secure", "Connection should be not secure."); 611 612 gBrowser.selectedTab = oldTab; 613 is(getIdentityMode(), "localResource", "Identity should be localResource"); 614 615 gBrowser.selectedTab = newTab; 616 is(getIdentityMode(), "unknownIdentity", "Identity should be unknown."); 617 is(getConnectionState(), "not-secure", "Connection should be not secure."); 618 619 gBrowser.removeTab(newTab); 620 gBrowser.removeTab(oldTab); 621 622 await SpecialPowers.popPrefEnv(); 623 }); 624 625 add_task(async function test_no_cert_error_security_connection_bg() { 626 let tab = BrowserTestUtils.addTab(gBrowser); 627 gBrowser.selectedTab = tab; 628 let promise = BrowserTestUtils.waitForErrorPage(gBrowser.selectedBrowser); 629 BrowserTestUtils.startLoadingURIString( 630 gBrowser, 631 "https://nocert.example.com/" 632 ); 633 await promise; 634 635 is( 636 getSecurityConnectionBG(), 637 `url("chrome://global/skin/icons/security-warning.svg")`, 638 "Security connection should show a warning lock icon." 639 ); 640 641 BrowserTestUtils.removeTab(tab); 642 }); 643 644 add_task(async function test_about_uri() { 645 let oldTab = await loadNewTab("about:robots"); 646 let aboutURI = "about:robots"; 647 648 let newTab = await loadNewTab(aboutURI); 649 is(getConnectionState(), "file", "Connection should be file"); 650 651 gBrowser.selectedTab = oldTab; 652 is(getIdentityMode(), "localResource", "Identity should be localResource"); 653 654 gBrowser.selectedTab = newTab; 655 is(getConnectionState(), "file", "Connection should be file"); 656 657 gBrowser.removeTab(newTab); 658 gBrowser.removeTab(oldTab); 659 }); 660 661 add_task(async function test_reader_uri() { 662 let newTab = await loadNewTab("about:reader?url=http://example.com"); 663 gBrowser.selectedTab = newTab; 664 let readerURL = await getReaderModeURL(); 665 is( 666 readerURL, 667 "Site information for example.com", 668 "should be the correct URI in reader mode" 669 ); 670 671 gBrowser.removeTab(newTab); 672 673 await SpecialPowers.popPrefEnv(); 674 }); 675 676 add_task(async function test_data_uri() { 677 let oldTab = await loadNewTab("about:robots"); 678 let dataURI = "data:text/html,hi"; 679 680 let newTab = await loadNewTab(dataURI); 681 is(getIdentityMode(), NOT_SECURE_LABEL, "Identity should be not secure"); 682 683 gBrowser.selectedTab = oldTab; 684 is(getIdentityMode(), "localResource", "Identity should be localResource"); 685 686 gBrowser.selectedTab = newTab; 687 is(getIdentityMode(), NOT_SECURE_LABEL, "Identity should be not secure"); 688 689 gBrowser.removeTab(newTab); 690 gBrowser.removeTab(oldTab); 691 }); 692 693 add_task(async function test_pb_mode() { 694 await SpecialPowers.pushPrefEnv({ set: [[HTTPS_FIRST_PBM_PREF, false]] }); 695 696 let privateWin = await BrowserTestUtils.openNewBrowserWindow({ 697 private: true, 698 }); 699 let oldTab = await BrowserTestUtils.openNewForegroundTab( 700 privateWin.gBrowser, 701 "about:robots" 702 ); 703 let newTab = await BrowserTestUtils.openNewForegroundTab( 704 privateWin.gBrowser, 705 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 706 "http://example.com/" + DUMMY 707 ); 708 709 is( 710 getIdentityMode(privateWin), 711 NOT_SECURE_LABEL_PBMODE, 712 "Identity should be not secure" 713 ); 714 715 privateWin.gBrowser.selectedTab = oldTab; 716 is( 717 getIdentityMode(privateWin), 718 "localResource", 719 "Identity should be localResource" 720 ); 721 722 privateWin.gBrowser.selectedTab = newTab; 723 is( 724 getIdentityMode(privateWin), 725 NOT_SECURE_LABEL_PBMODE, 726 "Identity should be not secure" 727 ); 728 await BrowserTestUtils.closeWindow(privateWin); 729 730 await SpecialPowers.popPrefEnv(); 731 });