1 /* Any copyright is dedicated to the Public Domain.
2 * http://creativecommons.org/publicdomain/zero/1.0/ */
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
10 add_task(async function register_cleanup() {
11 registerCleanupFunction(() => {
12 let sss = Cc["@mozilla.org/ssservice;1"].getService(
13 Ci.nsISiteSecurityService
19 // In the absense of HSTS information, no upgrade should happen.
20 add_task(async function test_no_hsts_information_no_upgrade() {
22 getRootDirectory(gTestPath).replace(
23 "chrome://mochitests/content",
25 ) + "some_content.html";
26 await BrowserTestUtils.openNewForegroundTab(gBrowser, httpUrl);
27 Assert.equal(gBrowser.selectedBrowser.currentURI.scheme, "http");
28 gBrowser.removeCurrentTab();
31 // Visit a secure site that sends an HSTS header to set up the rest of the
33 add_task(async function see_hsts_header() {
35 getRootDirectory(gTestPath).replace(
36 "chrome://mochitests/content",
38 ) + "hsts_headers.sjs";
39 await BrowserTestUtils.openNewForegroundTab(gBrowser, setHstsUrl);
40 gBrowser.removeCurrentTab();
43 // Given a known HSTS host, future http navigations to that domain will be
45 add_task(async function test_http_upgrade() {
47 getRootDirectory(gTestPath).replace(
48 "chrome://mochitests/content",
50 ) + "some_content.html";
51 await BrowserTestUtils.openNewForegroundTab(gBrowser, httpUrl);
52 Assert.equal(gBrowser.selectedBrowser.currentURI.scheme, "https");
53 gBrowser.removeCurrentTab();
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",
62 ) + "some_content.html";
63 await BrowserTestUtils.openNewForegroundTab(gBrowser, differentHttpUrl);
64 Assert.equal(gBrowser.selectedBrowser.currentURI.scheme, "http");
65 gBrowser.removeCurrentTab();
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]],
74 let privateWindow = OpenBrowserWindow({ private: true });
75 await BrowserTestUtils.firstBrowserLoaded(privateWindow, false);
77 getRootDirectory(gTestPath).replace(
78 "chrome://mochitests/content",
80 ) + "some_content.html";
81 await BrowserTestUtils.openNewForegroundTab(privateWindow.gBrowser, url);
83 privateWindow.gBrowser.selectedBrowser.currentURI.scheme,
86 privateWindow.gBrowser.removeCurrentTab();
87 privateWindow.close();
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() {
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() {
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");
151 return frame.baseURI.startsWith("https://");
156 gBrowser.removeCurrentTab();
160 add_task(async function clear_hsts_state() {
161 let sss = Cc["@mozilla.org/ssservice;1"].getService(
162 Ci.nsISiteSecurityService
167 // Make sure this test is valid.
168 add_task(async function test_no_hsts_information_no_upgrade_again() {
170 getRootDirectory(gTestPath).replace(
171 "chrome://mochitests/content",
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() {
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");
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() {
199 getRootDirectory(gTestPath).replace(
200 "chrome://mochitests/content",
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() {
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");
222 gBrowser.removeCurrentTab();
225 // Since the HSTS header was not received in a first-party context, no upgrade
227 add_task(async function test_no_upgrade_for_third_party_header() {
229 getRootDirectory(gTestPath).replace(
230 "chrome://mochitests/content",
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
246 // HSTS information encountered in private contexts should not be used in
247 // non-private contexts.
249 async function test_no_upgrade_for_HSTS_information_from_private_window() {
250 await SpecialPowers.pushPrefEnv({
251 set: [["dom.security.https_first_pbm", false]],
253 let privateWindow = OpenBrowserWindow({ private: true });
254 await BrowserTestUtils.firstBrowserLoaded(privateWindow, false);
256 getRootDirectory(gTestPath).replace(
257 "chrome://mochitests/content",
258 "https://example.com"
259 ) + "hsts_headers.sjs";
260 await BrowserTestUtils.openNewForegroundTab(
261 privateWindow.gBrowser,
264 privateWindow.gBrowser.removeCurrentTab();
267 getRootDirectory(gTestPath).replace(
268 "chrome://mochitests/content",
270 ) + "some_content.html";
271 await BrowserTestUtils.openNewForegroundTab(gBrowser, httpUrl);
272 Assert.equal(gBrowser.selectedBrowser.currentURI.scheme, "http");
273 gBrowser.removeCurrentTab();
275 privateWindow.close();