Bug 1936575 - PART 2: Do not trigger default browser prompt until ToS is accepted...
[gecko.git] / security / manager / ssl / tests / mochitest / browser / browser_HSTS.js
blobf578ac7c4f8e32046f5a5e8f9869608bcf9ce7d4
1 /* Any copyright is dedicated to the Public Domain.
2  * http://creativecommons.org/publicdomain/zero/1.0/ */
4 "use strict";
6 // Tests that HTTP Strict Transport Security (HSTS) headers are noted as appropriate.
8 // Register a cleanup function to clear all accumulated HSTS state when this
9 // test is done.
10 add_task(async function register_cleanup() {
11   registerCleanupFunction(() => {
12     let sss = Cc["@mozilla.org/ssservice;1"].getService(
13       Ci.nsISiteSecurityService
14     );
15     sss.clearAll();
16   });
17 });
19 // In the absense of HSTS information, no upgrade should happen.
20 add_task(async function test_no_hsts_information_no_upgrade() {
21   let httpUrl =
22     getRootDirectory(gTestPath).replace(
23       "chrome://mochitests/content",
24       "http://example.com"
25     ) + "some_content.html";
26   await BrowserTestUtils.openNewForegroundTab(gBrowser, httpUrl);
27   Assert.equal(gBrowser.selectedBrowser.currentURI.scheme, "http");
28   gBrowser.removeCurrentTab();
29 });
31 // Visit a secure site that sends an HSTS header to set up the rest of the
32 // test.
33 add_task(async function see_hsts_header() {
34   let setHstsUrl =
35     getRootDirectory(gTestPath).replace(
36       "chrome://mochitests/content",
37       "https://example.com"
38     ) + "hsts_headers.sjs";
39   await BrowserTestUtils.openNewForegroundTab(gBrowser, setHstsUrl);
40   gBrowser.removeCurrentTab();
41 });
43 // Given a known HSTS host, future http navigations to that domain will be
44 // upgraded.
45 add_task(async function test_http_upgrade() {
46   let httpUrl =
47     getRootDirectory(gTestPath).replace(
48       "chrome://mochitests/content",
49       "http://example.com"
50     ) + "some_content.html";
51   await BrowserTestUtils.openNewForegroundTab(gBrowser, httpUrl);
52   Assert.equal(gBrowser.selectedBrowser.currentURI.scheme, "https");
53   gBrowser.removeCurrentTab();
54 });
56 // http navigations to unrelated hosts should not be upgraded.
57 add_task(async function test_unrelated_domain_no_upgrade() {
58   let differentHttpUrl =
59     getRootDirectory(gTestPath).replace(
60       "chrome://mochitests/content",
61       "http://example.org"
62     ) + "some_content.html";
63   await BrowserTestUtils.openNewForegroundTab(gBrowser, differentHttpUrl);
64   Assert.equal(gBrowser.selectedBrowser.currentURI.scheme, "http");
65   gBrowser.removeCurrentTab();
66 });
68 // http navigations in private contexts shouldn't use information from
69 // non-private contexts, so no upgrade should occur.
70 add_task(async function test_private_window_no_upgrade() {
71   await SpecialPowers.pushPrefEnv({
72     set: [["dom.security.https_first_pbm", false]],
73   });
74   let privateWindow = OpenBrowserWindow({ private: true });
75   await BrowserTestUtils.firstBrowserLoaded(privateWindow, false);
76   let url =
77     getRootDirectory(gTestPath).replace(
78       "chrome://mochitests/content",
79       "http://example.com"
80     ) + "some_content.html";
81   await BrowserTestUtils.openNewForegroundTab(privateWindow.gBrowser, url);
82   Assert.equal(
83     privateWindow.gBrowser.selectedBrowser.currentURI.scheme,
84     "http"
85   );
86   privateWindow.gBrowser.removeCurrentTab();
87   privateWindow.close();
88 });
90 // Since the header didn't specify "includeSubdomains", visiting a subdomain
91 // should not result in an upgrade.
92 add_task(async function test_subdomain_no_upgrade() {
93   let subdomainHttpUrl =
94     getRootDirectory(gTestPath).replace(
95       "chrome://mochitests/content",
96       "http://test1.example.com"
97     ) + "some_content.html";
98   await BrowserTestUtils.openNewForegroundTab(gBrowser, subdomainHttpUrl);
99   Assert.equal(gBrowser.selectedBrowser.currentURI.scheme, "http");
100   gBrowser.removeCurrentTab();
103 // Now visit a secure site that sends an HSTS header that also includes subdomains.
104 add_task(async function see_hsts_header_include_subdomains() {
105   let setHstsUrl =
106     getRootDirectory(gTestPath).replace(
107       "chrome://mochitests/content",
108       "https://example.com"
109     ) + "hsts_headers.sjs?includeSubdomains";
110   await BrowserTestUtils.openNewForegroundTab(gBrowser, setHstsUrl);
111   gBrowser.removeCurrentTab();
114 // Now visiting a subdomain should result in an upgrade.
115 add_task(async function test_subdomain_upgrade() {
116   let subdomainHttpUrl =
117     getRootDirectory(gTestPath).replace(
118       "chrome://mochitests/content",
119       "http://test1.example.com"
120     ) + "some_content.html";
121   await BrowserTestUtils.openNewForegroundTab(gBrowser, subdomainHttpUrl);
122   Assert.equal(gBrowser.selectedBrowser.currentURI.scheme, "https");
123   gBrowser.removeCurrentTab();
126 // Visiting a subdomain with https should result in an https URL (this isn't an
127 // upgrade - this test is essentially a consistency check).
128 add_task(async function test_already_https() {
129   let subdomainHttpsUrl =
130     getRootDirectory(gTestPath).replace(
131       "chrome://mochitests/content",
132       "https://test2.example.com"
133     ) + "some_content.html";
134   await BrowserTestUtils.openNewForegroundTab(gBrowser, subdomainHttpsUrl);
135   Assert.equal(gBrowser.selectedBrowser.currentURI.scheme, "https");
136   gBrowser.removeCurrentTab();
139 // Test that subresources are upgraded.
140 add_task(async function test_iframe_upgrade() {
141   let framedUrl =
142     getRootDirectory(gTestPath).replace(
143       "chrome://mochitests/content",
144       "https://example.com"
145     ) + "some_content_framed.html";
146   await BrowserTestUtils.openNewForegroundTab(gBrowser, framedUrl);
147   await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function () {
148     await ContentTaskUtils.waitForCondition(() => {
149       let frame = content.document.getElementById("frame");
150       if (frame) {
151         return frame.baseURI.startsWith("https://");
152       }
153       return false;
154     });
155   });
156   gBrowser.removeCurrentTab();
159 // Clear state.
160 add_task(async function clear_hsts_state() {
161   let sss = Cc["@mozilla.org/ssservice;1"].getService(
162     Ci.nsISiteSecurityService
163   );
164   sss.clearAll();
167 // Make sure this test is valid.
168 add_task(async function test_no_hsts_information_no_upgrade_again() {
169   let httpUrl =
170     getRootDirectory(gTestPath).replace(
171       "chrome://mochitests/content",
172       "http://example.com"
173     ) + "some_content.html";
174   await BrowserTestUtils.openNewForegroundTab(gBrowser, httpUrl);
175   Assert.equal(gBrowser.selectedBrowser.currentURI.scheme, "http");
176   gBrowser.removeCurrentTab();
179 // Visit a site with an iframe that loads first-party content that sends an
180 // HSTS header. The header should be heeded because it's first-party.
181 add_task(async function see_hsts_header_in_framed_first_party_context() {
182   let framedUrl =
183     getRootDirectory(gTestPath).replace(
184       "chrome://mochitests/content",
185       "https://example.com"
186     ) + "hsts_headers_framed.html";
187   await BrowserTestUtils.openNewForegroundTab(gBrowser, framedUrl);
188   await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function () {
189     await ContentTaskUtils.waitForCondition(() => {
190       return content.document.getElementById("done");
191     });
192   });
193   gBrowser.removeCurrentTab();
196 // Check that the framed, first-party header was heeded.
197 add_task(async function test_http_upgrade_after_framed_first_party_header() {
198   let httpUrl =
199     getRootDirectory(gTestPath).replace(
200       "chrome://mochitests/content",
201       "http://example.com"
202     ) + "some_content.html";
203   await BrowserTestUtils.openNewForegroundTab(gBrowser, httpUrl);
204   Assert.equal(gBrowser.selectedBrowser.currentURI.scheme, "https");
205   gBrowser.removeCurrentTab();
208 // Visit a site with an iframe that loads third-party content that sends an
209 // HSTS header. The header should be ignored because it's third-party.
210 add_task(async function see_hsts_header_in_third_party_context() {
211   let framedUrl =
212     getRootDirectory(gTestPath).replace(
213       "chrome://mochitests/content",
214       "https://example.com"
215     ) + "hsts_headers_framed.html?third-party";
216   await BrowserTestUtils.openNewForegroundTab(gBrowser, framedUrl);
217   await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function () {
218     await ContentTaskUtils.waitForCondition(() => {
219       return content.document.getElementById("done");
220     });
221   });
222   gBrowser.removeCurrentTab();
225 // Since the HSTS header was not received in a first-party context, no upgrade
226 // should occur.
227 add_task(async function test_no_upgrade_for_third_party_header() {
228   let url =
229     getRootDirectory(gTestPath).replace(
230       "chrome://mochitests/content",
231       "http://example.org"
232     ) + "some_content.html";
233   await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
234   Assert.equal(gBrowser.selectedBrowser.currentURI.scheme, "http");
235   gBrowser.removeCurrentTab();
238 // Clear state again.
239 add_task(async function clear_hsts_state_again() {
240   let sss = Cc["@mozilla.org/ssservice;1"].getService(
241     Ci.nsISiteSecurityService
242   );
243   sss.clearAll();
246 // HSTS information encountered in private contexts should not be used in
247 // non-private contexts.
248 add_task(
249   async function test_no_upgrade_for_HSTS_information_from_private_window() {
250     await SpecialPowers.pushPrefEnv({
251       set: [["dom.security.https_first_pbm", false]],
252     });
253     let privateWindow = OpenBrowserWindow({ private: true });
254     await BrowserTestUtils.firstBrowserLoaded(privateWindow, false);
255     let setHstsUrl =
256       getRootDirectory(gTestPath).replace(
257         "chrome://mochitests/content",
258         "https://example.com"
259       ) + "hsts_headers.sjs";
260     await BrowserTestUtils.openNewForegroundTab(
261       privateWindow.gBrowser,
262       setHstsUrl
263     );
264     privateWindow.gBrowser.removeCurrentTab();
266     let httpUrl =
267       getRootDirectory(gTestPath).replace(
268         "chrome://mochitests/content",
269         "http://example.com"
270       ) + "some_content.html";
271     await BrowserTestUtils.openNewForegroundTab(gBrowser, httpUrl);
272     Assert.equal(gBrowser.selectedBrowser.currentURI.scheme, "http");
273     gBrowser.removeCurrentTab();
275     privateWindow.close();
276   }