Bug 1715785 - Trim redirect chain of excess information; r=necko-reviewers,ckerschb,tjr,dragana

Differential Revision: https://phabricator.services.mozilla.com/D136885
This commit is contained in:
june wilde 2022-04-13 13:33:49 +00:00
parent 91cacbd5ef
commit 600ce18f08
6 changed files with 414 additions and 82 deletions

View File

@ -0,0 +1,172 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gtest/gtest.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/ContentPrincipal.h"
#include "mozilla/NullPrincipal.h"
#include "mozilla/SystemPrincipal.h"
#include "nsContentUtils.h"
#include "mozilla/LoadInfo.h"
namespace mozilla {
void checkPrincipalTruncation(nsIPrincipal* aPrincipal,
const nsACString& aExpectedSpec) {
nsCOMPtr<nsIPrincipal> truncatedPrincipal =
net::CreateTruncatedPrincipal(aPrincipal);
ASSERT_TRUE(truncatedPrincipal);
if (aPrincipal->IsSystemPrincipal()) {
ASSERT_TRUE(truncatedPrincipal->IsSystemPrincipal());
return;
}
if (aPrincipal->GetIsNullPrincipal()) {
nsCOMPtr<nsIPrincipal> precursorPrincipal =
aPrincipal->GetPrecursorPrincipal();
nsAutoCString principalSpecEnding("}");
nsAutoCString expectedTestSpec(aExpectedSpec);
if (!aExpectedSpec.IsEmpty()) {
principalSpecEnding += "?"_ns;
expectedTestSpec += "/"_ns;
}
if (precursorPrincipal) {
nsAutoCString precursorSpec;
precursorPrincipal->GetAsciiSpec(precursorSpec);
ASSERT_TRUE(precursorSpec.Equals(expectedTestSpec));
}
// NullPrincipals have UUIDs as part of their scheme i.e.
// moz-nullprincipal:{9bebdabb-828a-4284-8b00-432a968c6e42}
// To avoid having to know the UUID beforehand we check the principal's spec
// before and after the UUID
nsAutoCString principalSpec;
truncatedPrincipal->GetAsciiSpec(principalSpec);
ASSERT_TRUE(StringBeginsWith(principalSpec, "moz-nullprincipal:{"_ns));
ASSERT_TRUE(
StringEndsWith(principalSpec, principalSpecEnding + aExpectedSpec));
return;
}
if (aPrincipal->GetIsContentPrincipal()) {
nsAutoCString principalSpec;
truncatedPrincipal->GetAsciiSpec(principalSpec);
ASSERT_TRUE(principalSpec.Equals(aExpectedSpec));
return;
}
// Tests should not reach this point
ADD_FAILURE();
}
TEST(RedirectChainURITruncation, ContentPrincipal)
{
// ======================= HTTP Scheme =======================
nsAutoCString httpSpec(
"http://root:toor@www.example.com:200/foo/bar/baz.html?qux#thud");
nsCOMPtr<nsIURI> uri;
nsresult rv = NS_NewURI(getter_AddRefs(uri), httpSpec);
ASSERT_EQ(rv, NS_OK);
nsCOMPtr<nsIPrincipal> principal;
OriginAttributes attrs;
principal = BasePrincipal::CreateContentPrincipal(uri, attrs);
ASSERT_TRUE(principal);
checkPrincipalTruncation(principal,
"http://www.example.com:200/foo/bar/baz.html"_ns);
// ======================= HTTPS Scheme =======================
nsAutoCString httpsSpec(
"https://root:toor@www.example.com:200/foo/bar/baz.html?qux#thud");
rv = NS_NewURI(getter_AddRefs(uri), httpsSpec);
ASSERT_EQ(rv, NS_OK);
principal = BasePrincipal::CreateContentPrincipal(uri, attrs);
ASSERT_TRUE(principal);
checkPrincipalTruncation(principal,
"https://www.example.com:200/foo/bar/baz.html"_ns);
// ======================= View Source Scheme =======================
nsAutoCString viewSourceSpec(
"view-source:https://root:toor@www.example.com:200/foo/bar/"
"baz.html?qux#thud");
rv = NS_NewURI(getter_AddRefs(uri), viewSourceSpec);
ASSERT_EQ(rv, NS_OK);
principal = BasePrincipal::CreateContentPrincipal(uri, attrs);
ASSERT_TRUE(principal);
checkPrincipalTruncation(
principal, "view-source:https://www.example.com:200/foo/bar/baz.html"_ns);
// ======================= About Scheme =======================
nsAutoCString aboutSpec("about:config");
rv = NS_NewURI(getter_AddRefs(uri), aboutSpec);
ASSERT_EQ(rv, NS_OK);
principal = BasePrincipal::CreateContentPrincipal(uri, attrs);
ASSERT_TRUE(principal);
checkPrincipalTruncation(principal, "about:config"_ns);
// ======================= Resource Scheme =======================
nsAutoCString resourceSpec("resource://testing/");
rv = NS_NewURI(getter_AddRefs(uri), resourceSpec);
ASSERT_EQ(rv, NS_OK);
principal = BasePrincipal::CreateContentPrincipal(uri, attrs);
ASSERT_TRUE(principal);
checkPrincipalTruncation(principal, "resource://testing/"_ns);
// ======================= Chrome Scheme =======================
nsAutoCString chromeSpec("chrome://foo/content/bar.xul");
rv = NS_NewURI(getter_AddRefs(uri), chromeSpec);
ASSERT_EQ(rv, NS_OK);
principal = BasePrincipal::CreateContentPrincipal(uri, attrs);
ASSERT_TRUE(principal);
checkPrincipalTruncation(principal, "chrome://foo/content/bar.xul"_ns);
}
TEST(RedirectChainURITruncation, NullPrincipal)
{
// ======================= NullPrincipal =======================
nsCOMPtr<nsIPrincipal> principal =
NullPrincipal::CreateWithoutOriginAttributes();
ASSERT_TRUE(principal);
checkPrincipalTruncation(principal, ""_ns);
// ======================= NullPrincipal & Precursor =======================
nsAutoCString precursorSpec(
"https://root:toor@www.example.com:200/foo/bar/baz.html?qux#thud");
nsCOMPtr<nsIURI> precursorURI;
nsresult rv = NS_NewURI(getter_AddRefs(precursorURI), precursorSpec);
ASSERT_EQ(rv, NS_OK);
OriginAttributes attrs;
nsCOMPtr<nsIPrincipal> precursorPrincipal =
BasePrincipal::CreateContentPrincipal(precursorURI, attrs);
principal = NullPrincipal::CreateWithInheritedAttributes(precursorPrincipal);
ASSERT_TRUE(principal);
checkPrincipalTruncation(principal, "https://www.example.com:200"_ns);
}
TEST(RedirectChainURITruncation, SystemPrincipal)
{
nsCOMPtr<nsIPrincipal> principal = nsContentUtils::GetSystemPrincipal();
ASSERT_TRUE(principal);
checkPrincipalTruncation(principal, ""_ns);
}
} // namespace mozilla

View File

@ -9,6 +9,7 @@ UNIFIED_SOURCES += [
"TestOriginAttributes.cpp",
"TestPrincipalAttributes.cpp",
"TestPrincipalSerialization.cpp",
"TestRedirectChainURITruncation.cpp",
]
include("/ipc/chromium/chromium-config.mozbuild")

View File

@ -47,8 +47,7 @@
using namespace mozilla::dom;
namespace mozilla {
namespace net {
namespace mozilla::net {
static nsContentPolicyType InternalContentPolicyTypeForFrame(
CanonicalBrowsingContext* aBrowsingContext) {
@ -1378,6 +1377,119 @@ LoadInfo::GetInitialSecurityCheckDone(bool* aResult) {
return NS_OK;
}
// To prevent unintenional credential and information leaks in content
// processes we can use this function to truncate a Principal's URI as much as
// possible.
already_AddRefed<nsIPrincipal> CreateTruncatedPrincipal(
nsIPrincipal* aPrincipal) {
nsCOMPtr<nsIPrincipal> truncatedPrincipal;
// System Principal URIs don't need to be truncated as they don't contain any
// sensitive browsing history information.
if (aPrincipal->IsSystemPrincipal()) {
truncatedPrincipal = aPrincipal;
return truncatedPrincipal.forget();
}
// Content Principal URIs are the main location of the information we need to
// truncate.
if (aPrincipal->GetIsContentPrincipal()) {
// Certain URIs (chrome, resource, about) don't need to be truncated as they
// should be free of any sensitive user browsing history.
if (aPrincipal->SchemeIs("chrome") || aPrincipal->SchemeIs("resource") ||
aPrincipal->SchemeIs("about")) {
truncatedPrincipal = aPrincipal;
return truncatedPrincipal.forget();
}
// Different parts of the URI are preserved due to being vital to the
// browser's operation.
// Scheme for differentiating between different types of URIs and how to
// truncate them and later on utilize them.
// Host and Port to retain the redirect chain's core functionality.
// Path would ideally be removed but needs to be retained to ensure that
// http/https redirect loops can be detected.
// The entirety of the Query String, Reference Fragment, and User Info
// subcomponents must be stripped to avoid leaking Oauth tokens, user
// identifiers, and similar bits of information that these subcomponents may
// contain.
nsAutoCString scheme;
nsAutoCString separator("://");
nsAutoCString hostPort;
nsAutoCString path;
nsAutoCString uriString("");
if (aPrincipal->SchemeIs("view-source")) {
// The path portion of the view-source URI will be the URI whose source is
// being viewed, so we create a new URI object with a truncated form of
// the path and append the view-source scheme to the front again.
nsAutoCString viewSourcePath;
aPrincipal->GetFilePath(viewSourcePath);
nsCOMPtr<nsIURI> nestedURI;
nsresult rv = NS_NewURI(getter_AddRefs(nestedURI), viewSourcePath);
if (NS_FAILED(rv)) {
// Since the path here should be an already validated URI this should
// never happen.
NS_WARNING(viewSourcePath.get());
MOZ_ASSERT(false,
"Failed to create truncated form of URI with NS_NewURI.");
truncatedPrincipal = aPrincipal;
return truncatedPrincipal.forget();
}
nestedURI->GetScheme(scheme);
nestedURI->GetHostPort(hostPort);
nestedURI->GetFilePath(path);
uriString += "view-source:";
} else {
aPrincipal->GetScheme(scheme);
aPrincipal->GetHostPort(hostPort);
aPrincipal->GetFilePath(path);
}
uriString += scheme + separator + hostPort + path;
nsCOMPtr<nsIURI> truncatedURI;
nsresult rv = NS_NewURI(getter_AddRefs(truncatedURI), uriString);
if (NS_FAILED(rv)) {
NS_WARNING(uriString.get());
MOZ_ASSERT(false,
"Failed to create truncated form of URI with NS_NewURI.");
truncatedPrincipal = aPrincipal;
return truncatedPrincipal.forget();
}
return BasePrincipal::CreateContentPrincipal(
truncatedURI, aPrincipal->OriginAttributesRef());
}
// Null Principal Precursor URIs can also contain information that needs to
// be truncated.
if (aPrincipal->GetIsNullPrincipal()) {
nsCOMPtr<nsIPrincipal> precursorPrincipal =
aPrincipal->GetPrecursorPrincipal();
// If there is no precursor then nothing needs to be truncated.
if (!precursorPrincipal) {
truncatedPrincipal = aPrincipal;
return truncatedPrincipal.forget();
}
// Otherwise we return a new Null Principal with the original's Origin
// Attributes and a truncated version of the original's precursor URI.
nsCOMPtr<nsIPrincipal> truncatedPrecursor =
CreateTruncatedPrincipal(precursorPrincipal);
return NullPrincipal::CreateWithInheritedAttributes(truncatedPrecursor);
}
// If we hit this assertion we need to update this function to add the
// Principals and URIs seen as new corner cases to handle.
// For example we may need to do this for Expanded Principals and moz-icon
// URIs.
MOZ_ASSERT(false, "Unhandled Principal or URI type encountered.");
truncatedPrincipal = aPrincipal;
return truncatedPrincipal.forget();
}
NS_IMETHODIMP
LoadInfo::AppendRedirectHistoryEntry(nsIChannel* aChannel,
bool aIsInternalRedirect) {
@ -1408,8 +1520,11 @@ LoadInfo::AppendRedirectHistoryEntry(nsIChannel* aChannel,
Unused << intChannel->GetRemoteAddress(remoteAddress);
}
nsCOMPtr<nsIPrincipal> truncatedPrincipal =
CreateTruncatedPrincipal(uriPrincipal);
nsCOMPtr<nsIRedirectHistoryEntry> entry =
new nsRedirectHistoryEntry(uriPrincipal, referrer, remoteAddress);
new nsRedirectHistoryEntry(truncatedPrincipal, referrer, remoteAddress);
mRedirectChainIncludingInternalRedirects.AppendElement(entry);
if (!aIsInternalRedirect) {
@ -2023,5 +2138,4 @@ already_AddRefed<nsIContentSecurityPolicy> LoadInfo::GetCspToInherit() {
return cspToInherit.forget();
}
} // namespace net
} // namespace mozilla
} // namespace mozilla::net

View File

@ -350,6 +350,10 @@ class LoadInfo final : public nsILoadInfo {
nsCOMPtr<nsIURI> mUnstrippedURI;
};
// This is exposed solely for testing purposes and should not be used outside of
// LoadInfo
already_AddRefed<nsIPrincipal> CreateTruncatedPrincipal(nsIPrincipal*);
} // namespace net
} // namespace mozilla

View File

@ -4,8 +4,7 @@
*/
function createIframeContent(aQuery) {
var content =
`
var content = `
<!DOCTYPE HTML>
<html>
<head><meta charset="utf-8">
@ -14,29 +13,27 @@ function createIframeContent(aQuery) {
<body>
<script type="text/javascript">
var myXHR = new XMLHttpRequest();
myXHR.open("GET", "http://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?` +
aQuery +
`");
myXHR.open("GET", "http://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?${aQuery}");
myXHR.onload = function() {
var loadinfo = SpecialPowers.wrap(myXHR).channel.loadInfo;
var redirectChain = loadinfo.redirectChain;
var redirectChainIncludingInternalRedirects = loadinfo.redirectChainIncludingInternalRedirects;
var resultOBJ = { redirectChain : [], redirectChainIncludingInternalRedirects : [] };
for (var i = 0; i < redirectChain.length; i++) {
resultOBJ.redirectChain.push(redirectChain[i].principal.spec);
var loadinfo = SpecialPowers.wrap(myXHR).channel.loadInfo;
var redirectChain = loadinfo.redirectChain;
var redirectChainIncludingInternalRedirects = loadinfo.redirectChainIncludingInternalRedirects;
var resultOBJ = { redirectChain : [], redirectChainIncludingInternalRedirects : [] };
for (var i = 0; i < redirectChain.length; i++) {
resultOBJ.redirectChain.push(redirectChain[i].principal.spec);
}
for (var i = 0; i < redirectChainIncludingInternalRedirects.length; i++) {
resultOBJ.redirectChainIncludingInternalRedirects.push(redirectChainIncludingInternalRedirects[i].principal.spec);
}
var loadinfoJSON = JSON.stringify(resultOBJ);
window.parent.postMessage({ loadinfo: loadinfoJSON }, "*");
}
for (var i = 0; i < redirectChainIncludingInternalRedirects.length; i++) {
resultOBJ.redirectChainIncludingInternalRedirects.push(redirectChainIncludingInternalRedirects[i].principal.spec);
myXHR.onerror = function() {
var resultOBJ = { redirectChain : [], redirectChainIncludingInternalRedirects : [] };
var loadinfoJSON = JSON.stringify(resultOBJ);
window.parent.postMessage({ loadinfo: loadinfoJSON }, "*");
}
var loadinfoJSON = JSON.stringify(resultOBJ);
window.parent.postMessage({ loadinfo: loadinfoJSON }, "*");
}
myXHR.onerror = function() {
var resultOBJ = { redirectChain : [], redirectChainIncludingInternalRedirects : [] };
var loadinfoJSON = JSON.stringify(resultOBJ);
window.parent.postMessage({ loadinfo: loadinfoJSON }, "*");
}
myXHR.send();
myXHR.send();
</script>
</body>
</html>`;
@ -79,7 +76,7 @@ function handleRequest(request, response) {
}
// must be a redirect
var newLoaction = "";
var newLocation = "";
switch (queryString) {
case "redir-err-2":
newLocation =

View File

@ -25,10 +25,45 @@
* (4) checkLoadInfoWithInternalRedirectsAndFallback
* perform two redirects including CSPs upgrade-insecure-requests
* including a 404 repsonse and hence a fallback.
* (5) checkHTTPURITruncation
* perform a redirect to a URI with an HTTP scheme to check that unwanted
* URI components are removed before being added to the redirectchain.
* (6) checkHTTPSURITruncation
* perform a redirect to a URI with an HTTPS scheme to check that unwanted
* URI components are removed before being added to the redirectchain.
*/
SimpleTest.waitForExplicitFinish();
// ************** HELPERS ***************
function compareChains(aLoadInfo, aExpectedRedirectChain, aExpectedRedirectChainIncludingInternalRedirects) {
var redirectChain = aLoadInfo.redirectChain;
var redirectChainIncludingInternalRedirects = aLoadInfo.redirectChainIncludingInternalRedirects;
is(redirectChain.length,
aExpectedRedirectChain.length,
"confirming length of redirectChain is " + aExpectedRedirectChain.length);
is(redirectChainIncludingInternalRedirects.length,
aExpectedRedirectChainIncludingInternalRedirects.length,
"confirming length of redirectChainIncludingInternalRedirects is " +
aExpectedRedirectChainIncludingInternalRedirects.length);
}
function compareTruncatedChains(redirectChain, aExpectedRedirectChain) {
is(redirectChain.length,
aExpectedRedirectChain.length,
"confirming length of redirectChain is " + aExpectedRedirectChain.length);
for (var i = 0; i < redirectChain.length; i++) {
is(redirectChain[i],
aExpectedRedirectChain[i],
"redirect chain should match expected chain");
}
}
// *************** TEST 1 ***************
function checkLoadInfoWithoutRedirects() {
@ -77,10 +112,12 @@ function checkLoadInfoWithTwoRedirects() {
myXHR.open("GET", "http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-2");
const EXPECTED_REDIRECT_CHAIN = [
"http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-2",
"http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-1"
"http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs",
"http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs"
];
const EXPECTED_REDIRECT_CHAIN_INCLUDING_INTERNAL_REDIRECTS = EXPECTED_REDIRECT_CHAIN;
// Referrer header will not change when redirect
const EXPECTED_REFERRER =
"http://mochi.test:8888/tests/netwerk/test/mochitests/test_loadinfo_redirectchain.html";
@ -91,29 +128,12 @@ function checkLoadInfoWithTwoRedirects() {
is(myXHR.responseText, "checking redirectchain", "sanity check to make sure redirects succeeded");
var loadinfo = SpecialPowers.wrap(myXHR).channel.loadInfo;
var redirectChain = loadinfo.redirectChain;
var redirectChainIncludingInternalRedirects = loadinfo.redirectChainIncludingInternalRedirects;
is(redirectChain.length,
EXPECTED_REDIRECT_CHAIN.length,
"two redirects, chain should have length 2");
is(redirectChainIncludingInternalRedirects.length,
EXPECTED_REDIRECT_CHAIN.length,
"two redirect, chainInternal should have length 2");
compareChains(loadinfo, EXPECTED_REDIRECT_CHAIN, EXPECTED_REDIRECT_CHAIN_INCLUDING_INTERNAL_REDIRECTS);
for (var i = 0; i < redirectChain.length; i++) {
is(redirectChain[i].principal.spec,
EXPECTED_REDIRECT_CHAIN[i],
"redirectChain at index [" + i + "] should match");
is(redirectChainIncludingInternalRedirects[i].principal.spec,
EXPECTED_REDIRECT_CHAIN[i],
"redirectChainIncludingInternalRedirects at index [" + i + "] should match");
is(redirectChain[i].referrerURI.spec,
EXPECTED_REFERRER,
"referrer should match");
is(redirectChain[i].remoteAddress,
EXPECTED_REMOTE_IP,
"remote address should match");
for (var i = 0; i < loadinfo.redirectChain.length; i++) {
is(loadinfo.redirectChain[i].referrerURI.spec, EXPECTED_REFERRER, "referrer should match");
is(loadinfo.redirectChain[i].remoteAddress, EXPECTED_REMOTE_IP, "remote address should match");
}
// move on to the next test
@ -125,38 +145,9 @@ function checkLoadInfoWithTwoRedirects() {
myXHR.send();
}
// ************** HELPERS ***************
function compareChains(aLoadInfo, aExpectedRedirectChain, aExpectedRedirectChainIncludingInternalRedirects) {
var redirectChain = aLoadInfo.redirectChain;
var redirectChainIncludingInternalRedirects = aLoadInfo.redirectChainIncludingInternalRedirects;
is(redirectChain.length,
aExpectedRedirectChain.length,
"confirming length of redirectChain");
is(redirectChainIncludingInternalRedirects.length,
aExpectedRedirectChainIncludingInternalRedirects.length,
"confirming length of redirectChainIncludingInternalRedirects");
for (var i = 0; i < redirectChain.length; i++) {
is(redirectChain[i],
aExpectedRedirectChain[i],
"redirectChain at index [" + i + "] should match");
}
for (var i = 0; i < redirectChainIncludingInternalRedirects.length; i++) {
is(redirectChainIncludingInternalRedirects[i],
aExpectedRedirectChainIncludingInternalRedirects[i],
"redirectChainIncludingInternalRedirects at index [" + i + "] should match");
}
}
// *************** TEST 3 ***************
function confirmCheckLoadInfoWithInternalRedirects(event) {
const EXPECTED_REDIRECT_CHAIN = [
"https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-2",
"https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-1"
@ -189,7 +180,6 @@ function checkLoadInfoWithInternalRedirects() {
// *************** TEST 4 ***************
function confirmCheckLoadInfoWithInternalRedirectsAndFallback(event) {
var EXPECTED_REDIRECT_CHAIN = [
"https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-err-2",
];
@ -205,7 +195,7 @@ function confirmCheckLoadInfoWithInternalRedirectsAndFallback(event) {
// remove the postMessage listener and finish test
window.removeEventListener("message", confirmCheckLoadInfoWithInternalRedirectsAndFallback);
SimpleTest.finish();
checkHTTPURITruncation();
}
function checkLoadInfoWithInternalRedirectsAndFallback() {
@ -216,6 +206,60 @@ function checkLoadInfoWithInternalRedirectsAndFallback() {
"https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?iframe-redir-err-2";
}
// *************** TEST 5 ***************
function checkHTTPURITruncation() {
var myXHR = new XMLHttpRequest();
myXHR.open("GET", "http://root:toor@mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-1#baz");
const EXPECTED_REDIRECT_CHAIN = [
"http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs", // redir-1
];
var loadinfo = SpecialPowers.wrap(myXHR).channel.loadInfo;
myXHR.onload = function() {
var redirectChain = [];
for (var i = 0; i < loadinfo.redirectChain.length; i++) {
redirectChain[i] = loadinfo.redirectChain[i].principal.asciiSpec;
}
compareTruncatedChains(redirectChain, EXPECTED_REDIRECT_CHAIN);
// move on to the next test
checkHTTPSURITruncation();
}
myXHR.onerror = function(e) {
ok(false, "xhr problem within checkHTTPURITruncation()" + e);
}
myXHR.send();
}
// *************** TEST 6 ***************
function confirmCheckHTTPSURITruncation(event) {
const EXPECTED_REDIRECT_CHAIN = [
"https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs", // redir-https-2
"https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs", // redir-https-1
];
var loadinfo = JSON.parse(event.data.loadinfo);
compareTruncatedChains(loadinfo.redirectChain, EXPECTED_REDIRECT_CHAIN);
// remove the postMessage listener and move on to the next test
window.removeEventListener("message", confirmCheckHTTPSURITruncation);
SimpleTest.finish();
}
function checkHTTPSURITruncation() {
// load the XHR request into an iframe so we can apply a CSP to the iframe
// a postMessage returns the result back to the main page.
window.addEventListener("message", confirmCheckHTTPSURITruncation);
document.getElementById("testframe").src =
"https://root:toor@example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?iframe-redir-https-2#baz";
}
// *************** START TESTS ***************
checkLoadInfoWithoutRedirects();