Bug 1402530 - Use IsOriginPotentiallyTrustworthy in ShouldLoad r=ckerschb,jkt

Differential Revision: https://phabricator.services.mozilla.com/D28870

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Sebastian Streich 2019-05-07 18:08:19 +00:00
Родитель 77e6f296b4
Коммит db1660661f
5 изменённых файлов: 102 добавлений и 88 удалений

Просмотреть файл

@ -3,7 +3,7 @@
<html>
<head>
<meta charset="utf8">
<title>Bug 903966</title>
<title>Bug 903966, Bug 1402530</title>
</head>
<style>
@ -32,19 +32,24 @@
<img src="http://127.0.0.1:8/test.png">
<img src="http://[::1]:8/test.png">
<img src="http://localhost:8/test.png">
<iframe src="http://127.0.0.1:8/test.html"></iframe>
<iframe src="http://[::1]:8/test.html"></iframe>
<iframe src="http://localhost:8/test.html"></iframe>
</body>
<script src="http://127.0.0.1:8/test.js"></script>
<script src="http://[::1]:8/test.js"></script>
<script src="http://localhost:8/test.js"></script>
<link href="http://127.0.0.1:8/test.css" rel="stylesheet"></link>
<link href="http://[::1]:8/test.css" rel="stylesheet"></link>
<link href="http://localhost:8/test.css" rel="stylesheet"></link>
<script>
fetch("http://127.0.0.1:8");
fetch("http://localhost:8");
fetch("http://[::1]:8");
</script>
</html>

Просмотреть файл

@ -298,5 +298,8 @@ https://mochitest.youtube.com:443
# Host for U2F localhost tests
https://localhost:443
# Bug 1402530
http://localhost:80 privileged
# Host for testing APIs whitelisted for mozilla.org
https://www.mozilla.org:443

Просмотреть файл

@ -1079,12 +1079,7 @@ nsContentSecurityManager::IsOriginPotentiallyTrustworthy(
*aIsTrustWorthy = true;
return NS_OK;
}
// The following implements:
// https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy
*aIsTrustWorthy = false;
if (aPrincipal->GetIsNullPrincipal()) {
return NS_OK;
}
@ -1094,78 +1089,11 @@ nsContentSecurityManager::IsOriginPotentiallyTrustworthy(
nsCOMPtr<nsIURI> uri;
nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
rv = nsMixedContentBlocker::IsOriginPotentiallyTrustworthy(uri,
aIsTrustWorthy);
if (NS_FAILED(rv)) {
return NS_OK;
}
nsAutoCString scheme;
rv = uri->GetScheme(scheme);
if (NS_FAILED(rv)) {
return NS_OK;
}
// Blobs are expected to inherit their principal so we don't expect to have
// a codebase principal with scheme 'blob' here. We can't assert that though
// since someone could mess with a non-blob URI to give it that scheme.
NS_WARNING_ASSERTION(!scheme.EqualsLiteral("blob"),
"IsOriginPotentiallyTrustworthy ignoring blob scheme");
// According to the specification, the user agent may choose to extend the
// trust to other, vendor-specific URL schemes. We use this for "resource:",
// which is technically a substituting protocol handler that is not limited to
// local resource mapping, but in practice is never mapped remotely as this
// would violate assumptions a lot of code makes.
// We use nsIProtocolHandler flags to determine which protocols we consider a
// priori authenticated.
bool aPrioriAuthenticated = false;
if (NS_FAILED(NS_URIChainHasFlags(
uri, nsIProtocolHandler::URI_IS_POTENTIALLY_TRUSTWORTHY,
&aPrioriAuthenticated))) {
return NS_ERROR_UNEXPECTED;
}
if (aPrioriAuthenticated) {
*aIsTrustWorthy = true;
return NS_OK;
}
nsAutoCString host;
rv = uri->GetHost(host);
if (NS_FAILED(rv)) {
return NS_OK;
}
if (host.EqualsLiteral("127.0.0.1") || host.EqualsLiteral("localhost") ||
host.EqualsLiteral("::1")) {
*aIsTrustWorthy = true;
return NS_OK;
}
// If a host is not considered secure according to the default algorithm, then
// check to see if it has been whitelisted by the user. We only apply this
// whitelist for network resources, i.e., those with scheme "http" or "ws".
// The pref should contain a comma-separated list of hostnames.
if (scheme.EqualsLiteral("http") || scheme.EqualsLiteral("ws")) {
nsAutoCString whitelist;
nsresult rv =
Preferences::GetCString("dom.securecontext.whitelist", whitelist);
if (NS_SUCCEEDED(rv)) {
nsCCharSeparatedTokenizer tokenizer(whitelist, ',');
while (tokenizer.hasMoreTokens()) {
const nsACString& allowedHost = tokenizer.nextToken();
if (host.Equals(allowedHost)) {
*aIsTrustWorthy = true;
return NS_OK;
}
}
}
// Maybe we have a .onion URL. Treat it as whitelisted as well if
// `dom.securecontext.whitelist_onions` is `true`.
if (nsMixedContentBlocker::IsPotentiallyTrustworthyOnion(uri)) {
*aIsTrustWorthy = true;
return NS_OK;
}
}
return NS_OK;
}

Просмотреть файл

@ -378,7 +378,9 @@ bool nsMixedContentBlocker::IsPotentiallyTrustworthyLoopbackURL(nsIURI* aURL) {
// We could also allow 'localhost' (if we can guarantee that it resolves
// to a loopback address), but Chrome doesn't support it as of writing. For
// web compat, lets only allow what Chrome allows.
return host.EqualsLiteral("127.0.0.1") || host.EqualsLiteral("::1");
// see also https://bugzilla.mozilla.org/show_bug.cgi?id=1220810
return host.EqualsLiteral("127.0.0.1") || host.EqualsLiteral("::1") ||
host.EqualsLiteral("localhost");
}
/* Maybe we have a .onion URL. Treat it as whitelisted as well if
@ -402,6 +404,85 @@ bool nsMixedContentBlocker::IsPotentiallyTrustworthyOnion(nsIURI* aURL) {
return StringEndsWith(host, NS_LITERAL_CSTRING(".onion"));
}
NS_IMETHODIMP
nsMixedContentBlocker::IsOriginPotentiallyTrustworthy(nsIURI* aURI,
bool* aIsTrustWorthy) {
// The following implements:
// https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy
*aIsTrustWorthy = false;
nsAutoCString scheme;
nsresult rv = aURI->GetScheme(scheme);
if (NS_FAILED(rv)) {
return NS_OK;
}
// Blobs are expected to inherit their principal so we don't expect to have
// a codebase principal with scheme 'blob' here. We can't assert that though
// since someone could mess with a non-blob URI to give it that scheme.
NS_WARNING_ASSERTION(!scheme.EqualsLiteral("blob"),
"IsOriginPotentiallyTrustworthy ignoring blob scheme");
// According to the specification, the user agent may choose to extend the
// trust to other, vendor-specific URL schemes. We use this for "resource:",
// which is technically a substituting protocol handler that is not limited to
// local resource mapping, but in practice is never mapped remotely as this
// would violate assumptions a lot of code makes.
// We use nsIProtocolHandler flags to determine which protocols we consider a
// priori authenticated.
bool aPrioriAuthenticated = false;
if (NS_FAILED(NS_URIChainHasFlags(
aURI, nsIProtocolHandler::URI_IS_POTENTIALLY_TRUSTWORTHY,
&aPrioriAuthenticated))) {
return NS_ERROR_UNEXPECTED;
}
if (aPrioriAuthenticated) {
*aIsTrustWorthy = true;
return NS_OK;
}
nsAutoCString host;
rv = aURI->GetHost(host);
if (NS_FAILED(rv)) {
return NS_OK;
}
if (IsPotentiallyTrustworthyLoopbackURL(aURI)) {
*aIsTrustWorthy = true;
return NS_OK;
}
// If a host is not considered secure according to the default algorithm, then
// check to see if it has been whitelisted by the user. We only apply this
// whitelist for network resources, i.e., those with scheme "http" or "ws".
// The pref should contain a comma-separated list of hostnames.
if (!scheme.EqualsLiteral("http") && !scheme.EqualsLiteral("ws")) {
return NS_OK;
}
nsAutoCString whitelist;
rv = Preferences::GetCString("dom.securecontext.whitelist", whitelist);
if (NS_SUCCEEDED(rv)) {
nsCCharSeparatedTokenizer tokenizer(whitelist, ',');
while (tokenizer.hasMoreTokens()) {
const nsACString& allowedHost = tokenizer.nextToken();
if (host.Equals(allowedHost)) {
*aIsTrustWorthy = true;
return NS_OK;
}
}
}
// Maybe we have a .onion URL. Treat it as whitelisted as well if
// `dom.securecontext.whitelist_onions` is `true`.
if (nsMixedContentBlocker::IsPotentiallyTrustworthyOnion(aURI)) {
*aIsTrustWorthy = true;
return NS_OK;
}
return NS_OK;
}
/* Static version of ShouldLoad() that contains all the Mixed Content Blocker
* logic. Called from non-static ShouldLoad().
*/
@ -738,17 +819,12 @@ nsresult nsMixedContentBlocker::ShouldLoad(
rv = innerContentLocation->SchemeIs("http", &isHttpScheme);
NS_ENSURE_SUCCESS(rv, rv);
// Loopback origins are not considered mixed content even over HTTP. See:
// https://w3c.github.io/webappsec-mixed-content/#should-block-fetch
if (isHttpScheme &&
IsPotentiallyTrustworthyLoopbackURL(innerContentLocation)) {
*aDecision = ACCEPT;
return NS_OK;
}
bool IsPotentiallyTrustworthy = false;
rv = IsOriginPotentiallyTrustworthy(innerContentLocation,
&IsPotentiallyTrustworthy);
NS_ENSURE_SUCCESS(rv, rv);
// .onion URLs are encrypted and authenticated. Don't treat them as mixed
// content if potentially trustworthy (i.e. whitelisted).
if (isHttpScheme && IsPotentiallyTrustworthyOnion(innerContentLocation)) {
if (isHttpScheme && IsPotentiallyTrustworthy) {
*aDecision = ACCEPT;
return NS_OK;
}

Просмотреть файл

@ -51,6 +51,8 @@ class nsMixedContentBlocker : public nsIContentPolicy,
// https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy
static bool IsPotentiallyTrustworthyLoopbackURL(nsIURI* aURL);
static bool IsPotentiallyTrustworthyOnion(nsIURI* aURL);
static nsresult IsOriginPotentiallyTrustworthy(nsIURI* aURI,
bool* aIsTrustWorthy);
/* Static version of ShouldLoad() that contains all the Mixed Content Blocker
* logic. Called from non-static ShouldLoad().