summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/tabPrompts/browser_auth_spoofing_protection.js
blob: ca139df8e4ad3e30c77e629eede3d7323ffceb6f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

let TEST_PATH = getRootDirectory(gTestPath).replace(
  "chrome://mochitests/content",
  "https://example.com"
);

let TEST_PATH_AUTH = getRootDirectory(gTestPath).replace(
  "chrome://mochitests/content",
  "https://example.org"
);

const CROSS_DOMAIN_URL = TEST_PATH + "redirect-crossDomain.html";

const SAME_DOMAIN_URL = TEST_PATH + "redirect-sameDomain.html";

const AUTH_URL = TEST_PATH_AUTH + "auth-route.sjs";

/**
 * Opens a new tab with a url that ether redirects us cross or same domain
 *
 * @param {Boolean} doConfirmPrompt - true if we want to test the case when the user accepts the prompt,
 *         false if we want to test the case when the user cancels the prompt.
 * @param {Boolean} crossDomain - if true we will open a url that redirects us to a cross domain url,
 *        if false, we will open a url that redirects us to a same domain url
 * @param {Boolean} prefEnabled true will enable "privacy.authPromptSpoofingProtection",
 *        false will disable the pref
 */
async function trigger401AndHandle(doConfirmPrompt, crossDomain, prefEnabled) {
  await SpecialPowers.pushPrefEnv({
    set: [["privacy.authPromptSpoofingProtection", prefEnabled]],
  });
  let url = crossDomain ? CROSS_DOMAIN_URL : SAME_DOMAIN_URL;
  let dialogShown = waitForDialog(doConfirmPrompt, crossDomain, prefEnabled);
  await BrowserTestUtils.withNewTab(url, async function () {
    await dialogShown;
  });
  await new Promise(resolve => {
    Services.clearData.deleteData(
      Ci.nsIClearDataService.CLEAR_AUTH_CACHE,
      resolve
    );
  });
}

async function waitForDialog(doConfirmPrompt, crossDomain, prefEnabled) {
  await TestUtils.topicObserved("common-dialog-loaded");
  let dialog = gBrowser.getTabDialogBox(gBrowser.selectedBrowser)
    ._tabDialogManager._topDialog;
  let dialogDocument = dialog._frame.contentDocument;
  if (crossDomain) {
    if (prefEnabled) {
      Assert.equal(
        dialog._overlay.getAttribute("hideContent"),
        "true",
        "Dialog overlay hides the current sites content"
      );
      Assert.equal(
        window.gURLBar.value,
        AUTH_URL,
        "Correct location is provided by the prompt"
      );
      Assert.equal(
        window.gBrowser.selectedTab.label,
        "example.org",
        "Tab title is manipulated"
      );
      // switch to another tab and make sure we dont mess up this new tabs url bar and tab title
      let tab = await BrowserTestUtils.openNewForegroundTab(
        gBrowser,
        "https://example.org:443"
      );
      Assert.equal(
        window.gURLBar.value,
        "https://example.org",
        "No location is provided by the prompt, correct location is displayed"
      );
      Assert.equal(
        window.gBrowser.selectedTab.label,
        "mochitest index /",
        "Tab title is not manipulated"
      );
      // switch back to our tab with the prompt and make sure the url bar state and tab title is still there
      BrowserTestUtils.removeTab(tab);
      Assert.equal(
        window.gURLBar.value,
        AUTH_URL,
        "Correct location is provided by the prompt"
      );
      Assert.equal(
        window.gBrowser.selectedTab.label,
        "example.org",
        "Tab title is manipulated"
      );
      // make sure a value that the user types in has a higher priority than our prompts location
      gBrowser.selectedBrowser.userTypedValue = "user value";
      gURLBar.setURI();
      Assert.equal(
        window.gURLBar.value,
        "user value",
        "User typed value is shown"
      );
      // if the user clears the url bar we again fall back to the location of the prompt if we trigger setURI by a tab switch
      gBrowser.selectedBrowser.userTypedValue = "";
      gURLBar.setURI(null, true);
      Assert.equal(
        window.gURLBar.value,
        AUTH_URL,
        "Correct location is provided by the prompt"
      );
      // Cross domain and pref is not enabled
    } else {
      Assert.equal(
        dialog._overlay.getAttribute("hideContent"),
        "",
        "Dialog overlay does not hide the current sites content"
      );
      Assert.equal(
        window.gURLBar.value,
        CROSS_DOMAIN_URL,
        "No location is provided by the prompt, correct location is displayed"
      );
      Assert.equal(
        window.gBrowser.selectedTab.label,
        "example.com",
        "Tab title is not manipulated"
      );
    }
    // same domain
  } else {
    Assert.equal(
      dialog._overlay.getAttribute("hideContent"),
      "",
      "Dialog overlay does not hide the current sites content"
    );
    Assert.equal(
      window.gURLBar.value,
      SAME_DOMAIN_URL,
      "No location is provided by the prompt, correct location is displayed"
    );
    Assert.equal(
      window.gBrowser.selectedTab.label,
      "example.com",
      "Tab title is not manipulated"
    );
  }

  let onDialogClosed = BrowserTestUtils.waitForEvent(
    window,
    "DOMModalDialogClosed"
  );
  if (doConfirmPrompt) {
    dialogDocument.getElementById("loginTextbox").value = "guest";
    dialogDocument.getElementById("password1Textbox").value = "guest";
    dialogDocument.getElementById("commonDialog").acceptDialog();
  } else {
    dialogDocument.getElementById("commonDialog").cancelDialog();
  }

  // wait for the dialog to be closed to check that the URLBar state is reset
  await onDialogClosed;
  // Due to bug 1812014, the url bar will be clear if we have set its value to "" while the prompt was open
  // so we trigger a tab switch again to have the uri displayed to be able to check its value
  gURLBar.setURI(null, true);
  Assert.equal(
    window.gURLBar.value,
    crossDomain ? CROSS_DOMAIN_URL : SAME_DOMAIN_URL,
    "No location is provided by the prompt"
  );
  Assert.equal(
    window.gBrowser.selectedTab.label,
    "example.com",
    "Tab title is not manipulated"
  );
}

add_setup(async function () {
  await SpecialPowers.pushPrefEnv({
    set: [["privacy.authPromptSpoofingProtection", true]],
  });
});

/**
 * Tests that the 401 auth spoofing mechanisms apply if the 401 is from a different base domain than the current sites,
 * canceling the prompt
 */
add_task(async function testCrossDomainCancelPrefEnabled() {
  await trigger401AndHandle(false, true, true);
});

/**
 * Tests that the 401 auth spoofing mechanisms apply if the 401 is from a different base domain than the current sites,
 * accepting the prompt
 */
add_task(async function testCrossDomainAcceptPrefEnabled() {
  await trigger401AndHandle(true, true, true);
});

/**
 * Tests that the 401 auth spoofing mechanisms do not apply if "privacy.authPromptSpoofingProtection" is not set to true
 * canceling the prompt
 */
add_task(async function testCrossDomainCancelPrefDisabled() {
  await trigger401AndHandle(false, true, false);
});

/**
 * Tests that the 401 auth spoofing mechanisms do not apply if "privacy.authPromptSpoofingProtection" is not set to true,
 * accepting the prompt
 */
add_task(async function testCrossDomainAcceptPrefDisabled() {
  await trigger401AndHandle(true, true, false);
});

/**
 * Tests that the 401 auth spoofing mechanisms are not triggered by a 401 within the same base domain as the current sites,
 * canceling the prompt
 */
add_task(async function testSameDomainCancelPrefEnabled() {
  await trigger401AndHandle(false, false, true);
});

/**
 * Tests that the 401 auth spoofing mechanisms are not triggered by a 401 within the same base domain as the current sites,
 * accepting the prompt
 */
add_task(async function testSameDomainAcceptPrefEnabled() {
  await trigger401AndHandle(true, false, true);
});