Skip to content

Commit

Permalink
Backed out changeset 19de2822bc0c (bug 1711168) for causing Bug 1719063.
Browse files Browse the repository at this point in the history
CLOSED TREE
  • Loading branch information
Alexandru Michis committed Jul 8, 2021
1 parent 8fd90dd commit 183b0cf
Show file tree
Hide file tree
Showing 11 changed files with 53 additions and 316 deletions.
36 changes: 12 additions & 24 deletions caps/BasePrincipal.cpp
Expand Up @@ -18,7 +18,6 @@
#include "nsAboutProtocolUtils.h"
#include "ThirdPartyUtil.h"
#include "mozilla/ContentPrincipal.h"
#include "mozilla/ExtensionPolicyService.h"
#include "mozilla/NullPrincipal.h"
#include "mozilla/dom/BlobURLProtocolHandler.h"
#include "mozilla/dom/ChromeUtils.h"
Expand Down Expand Up @@ -571,32 +570,21 @@ nsresult BasePrincipal::CheckMayLoadHelper(nsIURI* aURI,
}
}

// Get the principal uri for the last flag check or error.
nsCOMPtr<nsIURI> prinURI;
rv = GetURI(getter_AddRefs(prinURI));
if (!(NS_SUCCEEDED(rv) && prinURI)) {
return NS_ERROR_DOM_BAD_URI;
}

// If Extension uris are web accessible by this principal it is allowed to
// load.
bool maybeWebAccessible = false;
NS_URIChainHasFlags(aURI, nsIProtocolHandler::WEBEXT_URI_WEB_ACCESSIBLE,
&maybeWebAccessible);
NS_ENSURE_SUCCESS(rv, rv);
if (maybeWebAccessible) {
bool isWebAccessible = false;
rv = ExtensionPolicyService::GetSingleton().SourceMayLoadExtensionURI(
prinURI, aURI, &isWebAccessible);
if (NS_SUCCEEDED(rv) && isWebAccessible) {
return NS_OK;
}
bool fetchableByAnyone;
rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_FETCHABLE_BY_ANYONE,
&fetchableByAnyone);
if (NS_SUCCEEDED(rv) && fetchableByAnyone) {
return NS_OK;
}

if (aReport) {
nsScriptSecurityManager::ReportError(
"CheckSameOriginError", prinURI, aURI,
mOriginAttributes.mPrivateBrowsingId > 0, aInnerWindowID);
nsCOMPtr<nsIURI> prinURI;
rv = GetURI(getter_AddRefs(prinURI));
if (NS_SUCCEEDED(rv) && prinURI) {
nsScriptSecurityManager::ReportError(
"CheckSameOriginError", prinURI, aURI,
mOriginAttributes.mPrivateBrowsingId > 0, aInnerWindowID);
}
}

return NS_ERROR_DOM_BAD_URI;
Expand Down
50 changes: 18 additions & 32 deletions caps/nsScriptSecurityManager.cpp
Expand Up @@ -670,6 +670,21 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
return NS_ERROR_DOM_BAD_URI;
}

// Extensions may allow access to a web accessible resource.
bool maybeWebAccessible = false;
NS_URIChainHasFlags(targetBaseURI,
nsIProtocolHandler::WEBEXT_URI_WEB_ACCESSIBLE,
&maybeWebAccessible);
NS_ENSURE_SUCCESS(rv, rv);
if (maybeWebAccessible) {
bool isWebAccessible = false;
rv = ExtensionPolicyService::GetSingleton().SourceMayLoadExtensionURI(
sourceURI, targetBaseURI, &isWebAccessible);
if (!(NS_SUCCEEDED(rv) && isWebAccessible)) {
return NS_ERROR_DOM_BAD_URI;
}
}

// Check for uris that are only loadable by principals that subsume them
bool targetURIIsLoadableBySubsumers = false;
rv = NS_URIChainHasFlags(targetBaseURI,
Expand Down Expand Up @@ -743,7 +758,6 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
bool schemesMatch =
scheme.Equals(otherScheme, nsCaseInsensitiveCStringComparator);
bool isSamePage = false;
bool isExtensionMismatch = false;
// about: URIs are special snowflakes.
if (scheme.EqualsLiteral("about") && schemesMatch) {
nsAutoCString moduleName, otherModuleName;
Expand Down Expand Up @@ -791,13 +805,6 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
}
}
}
} else if (schemesMatch && scheme.EqualsLiteral("moz-extension")) {
// If it is not the same exension, we want to ensure we end up
// calling CheckLoadURIFlags
nsAutoCString host, otherHost;
currentURI->GetHost(host);
currentOtherURI->GetHost(otherHost);
isExtensionMismatch = !host.Equals(otherHost);
} else {
bool equalExceptRef = false;
rv = currentURI->EqualsExceptRef(currentOtherURI, &equalExceptRef);
Expand All @@ -806,12 +813,10 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,

// If schemes are not equal, or they're equal but the target URI
// is different from the source URI and doesn't always allow linking
// from the same scheme, or this is two different extensions, check
// if the URI flags of the current target URI allow the current
// source URI to link to it.
// from the same scheme, check if the URI flags of the current target
// URI allow the current source URI to link to it.
// The policy is specified by the protocol flags on both URIs.
if (!schemesMatch || (denySameSchemeLinks && !isSamePage) ||
isExtensionMismatch) {
if (!schemesMatch || (denySameSchemeLinks && !isSamePage)) {
return CheckLoadURIFlags(
currentURI, currentOtherURI, sourceBaseURI, targetBaseURI, aFlags,
aPrincipal->OriginAttributesRef().mPrivateBrowsingId > 0,
Expand Down Expand Up @@ -886,25 +891,6 @@ nsresult nsScriptSecurityManager::CheckLoadURIFlags(
}
}

// If Extension uris are web accessible they have WEBEXT_URI_WEB_ACCESSIBLE.
bool maybeWebAccessible = false;
NS_URIChainHasFlags(aTargetURI, nsIProtocolHandler::WEBEXT_URI_WEB_ACCESSIBLE,
&maybeWebAccessible);
NS_ENSURE_SUCCESS(rv, rv);
if (maybeWebAccessible) {
bool isWebAccessible = false;
rv = ExtensionPolicyService::GetSingleton().SourceMayLoadExtensionURI(
aSourceURI, aTargetURI, &isWebAccessible);
if (NS_SUCCEEDED(rv) && isWebAccessible) {
return NS_OK;
}
if (reportErrors) {
ReportError(errorTag, aSourceURI, aTargetURI, aFromPrivateWindow,
aInnerWindowID);
}
return NS_ERROR_DOM_BAD_URI;
}

// Check for chrome target URI
bool targetURIIsUIResource = false;
rv = NS_URIChainHasFlags(aTargetURI, nsIProtocolHandler::URI_IS_UI_RESOURCE,
Expand Down
3 changes: 1 addition & 2 deletions dom/chrome-webidl/WebExtensionPolicy.webidl
Expand Up @@ -268,8 +268,7 @@ interface WebExtensionPolicy {

dictionary WebAccessibleResourceInit {
required sequence<MatchGlobOrString> resources;
MatchPatternSetOrStringSequence? matches = null;
sequence<DOMString>? extensions = null;
MatchPatternSetOrStringSequence matches;
};

dictionary WebExtensionInit {
Expand Down
5 changes: 1 addition & 4 deletions dom/security/nsContentSecurityManager.cpp
Expand Up @@ -1080,7 +1080,7 @@ nsresult nsContentSecurityManager::CheckAllowLoadInSystemPrivilegedContext(
}

/*
* Every protocol handler must set one of the six security flags
* Every protocol handler must set one of the five security flags
* defined in nsIProtocolHandler - if not - deny the load.
*/
nsresult nsContentSecurityManager::CheckChannelHasProtocolSecurityFlag(
Expand All @@ -1105,9 +1105,6 @@ nsresult nsContentSecurityManager::CheckChannelHasProtocolSecurityFlag(
NS_ENSURE_SUCCESS(rv, rv);

uint32_t securityFlagsSet = 0;
if (flags & nsIProtocolHandler::WEBEXT_URI_WEB_ACCESSIBLE) {
securityFlagsSet += 1;
}
if (flags & nsIProtocolHandler::URI_LOADABLE_BY_ANYONE) {
securityFlagsSet += 1;
}
Expand Down
9 changes: 8 additions & 1 deletion netwerk/base/nsIProtocolHandler.idl
Expand Up @@ -272,6 +272,13 @@ interface nsIProtocolHandler : nsISupports
*/
const unsigned long URI_IS_POTENTIALLY_TRUSTWORTHY = (1<<17);

/**
* This URI may be fetched and the contents are visible to anyone. This is
* semantically equivalent to the resource being served with all-access CORS
* headers.
*/
const unsigned long URI_FETCHABLE_BY_ANYONE = (1 << 18);

/**
* If this flag is set, then the origin for this protocol is the full URI
* spec, not just the scheme + host + port.
Expand Down Expand Up @@ -305,7 +312,7 @@ interface nsIProtocolHandler : nsISupports

/**
* This is an extension web accessible uri that is loadable if checked
* against an allow whitelist using ExtensionPolicyService::SourceMayLoadExtensionURI.
* against an allow whitelist.
*/
const unsigned long WEBEXT_URI_WEB_ACCESSIBLE = (1 << 24);
};
13 changes: 8 additions & 5 deletions netwerk/protocol/res/ExtensionProtocolHandler.cpp
Expand Up @@ -368,12 +368,15 @@ nsresult ExtensionProtocolHandler::GetFlagsForURI(nsIURI* aURI,

URLInfo url(aURI);
if (auto* policy = EPS().GetByURL(url)) {
// In general a moz-extension URI is only loadable by chrome, but an
// allowlist subset are web-accessible (and cross-origin fetchable).
// The allowlist is checked using EPS.SourceMayLoadExtensionURI in
// BasePrincipal and nsScriptSecurityManager.
// In general a moz-extension URI is only loadable by chrome, but a
// whitelisted subset are web-accessible (and cross-origin fetchable). Check
// that whitelist. For Manifest V3 extensions, an additional whitelist
// for the source loading the url must be checked so we add the flag
// WEBEXT_URI_WEB_ACCESSIBLE, which is then checked in
// nsScriptSecurityManager.
if (policy->IsWebAccessiblePath(url.FilePath())) {
flags |= WEBEXT_URI_WEB_ACCESSIBLE;
flags |= URI_LOADABLE_BY_ANYONE | URI_FETCHABLE_BY_ANYONE |
WEBEXT_URI_WEB_ACCESSIBLE;
} else {
flags |= URI_DANGEROUS_TO_LOAD;
}
Expand Down
12 changes: 0 additions & 12 deletions toolkit/components/extensions/Schemas.jsm
Expand Up @@ -306,18 +306,6 @@ const POSTPROCESSORS = {
context.logError(context.makeError(msg));
throw new Error(msg);
},

webAcessibleMatching(value, context) {
// Ensure each object has at least one of matches or extensions array.
for (let obj of value) {
if (!obj.matches && !obj.extensions) {
const msg = `web_accessible_resources requires one of "matches" or "extensions"`;
context.logError(context.makeError(msg));
throw new Error(msg);
}
}
return value;
},
};

// Parses a regular expression, with support for the Python extended
Expand Down
14 changes: 1 addition & 13 deletions toolkit/components/extensions/WebExtensionPolicy.cpp
Expand Up @@ -143,24 +143,12 @@ WebAccessibleResource::WebAccessibleResource(
return;
}

if (!aInit.mMatches.IsNull()) {
if (aInit.mMatches.WasPassed()) {
MatchPatternOptions options;
options.mRestrictSchemes = true;
mMatches = ParseMatches(aGlobal, aInit.mMatches.Value(), options,
ErrorBehavior::CreateEmptyPattern, aRv);
}

if (!aInit.mExtensions.IsNull()) {
mExtensions = new AtomSet(aInit.mExtensions.Value());
}
}

bool WebAccessibleResource::IsExtensionMatch(const URLInfo& aURI) {
if (!mExtensions) {
return false;
}
WebExtensionPolicy* policy = EPS().GetByHost(aURI.Host());
return policy && mExtensions->Contains(policy->Id());
}

NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebAccessibleResource)
Expand Down
11 changes: 2 additions & 9 deletions toolkit/components/extensions/WebExtensionPolicy.h
Expand Up @@ -50,23 +50,16 @@ class WebAccessibleResource final : public nsISupports {
}

bool SourceMayAccessPath(const URLInfo& aURI, const nsAString& aPath) {
return mWebAccessiblePaths.Matches(aPath) &&
(IsHostMatch(aURI) || IsExtensionMatch(aURI));
return mWebAccessiblePaths.Matches(aPath) && mMatches &&
mMatches->Matches(aURI);
}

bool IsHostMatch(const URLInfo& aURI) {
return mMatches && mMatches->Matches(aURI);
}

bool IsExtensionMatch(const URLInfo& aURI);

protected:
virtual ~WebAccessibleResource() = default;

private:
MatchGlobSet mWebAccessiblePaths;
RefPtr<MatchPatternSet> mMatches;
RefPtr<AtomSet> mExtensions;
};

class WebExtensionPolicy final : public nsISupports,
Expand Down
7 changes: 0 additions & 7 deletions toolkit/components/extensions/schemas/manifest.json
Expand Up @@ -243,7 +243,6 @@
{
"min_manifest_version": 3,
"type": "array",
"postprocess": "webAcessibleMatching",
"items": {
"type": "object",
"properties": {
Expand All @@ -252,14 +251,8 @@
"items": { "type": "string" }
},
"matches": {
"optional": true,
"type": "array",
"items": { "$ref": "MatchPatternRestricted" }
},
"extensions": {
"optional": true,
"type": "array",
"items": { "$ref": "ExtensionID" }
}
}
}
Expand Down

0 comments on commit 183b0cf

Please sign in to comment.