mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
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:
parent
91cacbd5ef
commit
600ce18f08
172
caps/tests/gtest/TestRedirectChainURITruncation.cpp
Normal file
172
caps/tests/gtest/TestRedirectChainURITruncation.cpp
Normal 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
|
@ -9,6 +9,7 @@ UNIFIED_SOURCES += [
|
||||
"TestOriginAttributes.cpp",
|
||||
"TestPrincipalAttributes.cpp",
|
||||
"TestPrincipalSerialization.cpp",
|
||||
"TestRedirectChainURITruncation.cpp",
|
||||
]
|
||||
|
||||
include("/ipc/chromium/chromium-config.mozbuild")
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 =
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user