/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=2 sw=2 et tw=80: */ /* 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/. */
// Takes a JSON string and parses it turning it into a principal of the // corresponding type // // Given a content principal: // // inner JSON object // | // --------------------------------------------------------- // | | // {"1": {"0": "https://mozilla.com", "2": "^privateBrowsingId=1"}} // | | | | | // | ----------------------------- | // | | | | // PrincipalKind | | | // | ---------------------------- // SerializableKeys | // Value //
already_AddRefed<BasePrincipal> BasePrincipal::FromJSON( const nsACString& aJSON) {
PrincipalJSONHandler handler;
if (!JS::ParseJSONWithHandler( reinterpret_cast<const JS::Latin1Char*>(aJSON.BeginReading()),
aJSON.Length(), &handler)) {
NS_WARNING(
nsPrintfCString("Unable to parse: %s", aJSON.BeginReading()).get());
MOZ_ASSERT(false, "Unable to parse string as JSON to deserialize as a principal"); return nullptr;
}
return handler.Get();
}
// Returns a JSON representation of the principal. // Calling BasePrincipal::FromJSON will deserialize the JSON into // the corresponding principal type.
nsresult BasePrincipal::ToJSON(nsACString& aJSON) {
MOZ_ASSERT(aJSON.IsEmpty(), "ToJSON only supports an empty result input");
aJSON.Truncate();
// NOTE: JSONWriter emits raw UTF-8 code units for non-ASCII range.
JSONStringRefWriteFunc func(aJSON);
JSONWriter writer(func, JSONWriter::CollectionStyle::SingleLineStyle);
// Expanded principals handle origin attributes for each of their // sub-principals individually, null principals do only simple checks for // pointer equality, and system principals are immune to origin attributes // checks, so only do this check for content principals. if (Kind() == eContentPrincipal &&
mOriginSuffix != Cast(aOther)->mOriginSuffix) { returnfalse;
}
// Certain origin attributes should not be used to isolate permissions. // Create a stripped copy of both OA sets to compare.
mozilla::OriginAttributes ourAttrs = mOriginAttributes;
PermissionManager::MaybeStripOriginAttributes(false, ourAttrs);
mozilla::OriginAttributes theirAttrs = aOther->OriginAttributesRef();
PermissionManager::MaybeStripOriginAttributes(false, theirAttrs);
// If we are matching with an exact host, we're done now - the permissions // don't match otherwise, we need to start comparing subdomains! if (aExactHost) { return NS_OK;
}
nsCOMPtr<nsIURI> ourURI;
nsresult rv = GetURI(getter_AddRefs(ourURI));
NS_ENSURE_SUCCESS(rv, rv); // Some principal types may indicate success, but still return nullptr for // URI.
NS_ENSURE_TRUE(ourURI, NS_ERROR_FAILURE);
// Check if the host or any subdomain of their host matches.
nsAutoCString otherHost;
rv = otherURI->GetHost(otherHost); if (NS_FAILED(rv) || otherHost.IsEmpty()) { return NS_OK;
}
nsCOMPtr<nsIEffectiveTLDService> tldService =
mozilla::components::EffectiveTLD::Service(); if (!tldService) {
NS_ERROR("Should have a tld service!"); return NS_ERROR_FAILURE;
}
// This loop will not loop forever, as GetNextSubDomain will eventually fail // with NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS. while (otherHost != ourHost) {
rv = tldService->GetNextSubDomain(otherHost, otherHost); if (NS_FAILED(rv)) { if (rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) { return NS_OK;
} return rv;
}
}
nsresult BasePrincipal::CheckMayLoadHelper(nsIURI* aURI, bool aAllowIfInheritsPrincipal, bool aReport,
uint64_t aInnerWindowID) {
NS_ENSURE_ARG_POINTER(aURI);
MOZ_ASSERT(
aReport || aInnerWindowID == 0, "Why do we have an inner window id if we're not supposed to report?");
MOZ_ASSERT(!aReport || NS_IsMainThread(), "Must be on main thread to report");
// Check the internal method first, which allows us to quickly approve loads // for the System Principal. if (MayLoadInternal(aURI)) { return NS_OK;
}
nsresult rv; if (aAllowIfInheritsPrincipal) { // If the caller specified to allow loads of URIs that inherit // our principal, allow the load if this URI inherits its principal. bool doesInheritSecurityContext;
rv = NS_URIChainHasFlags(aURI,
nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
&doesInheritSecurityContext); if (NS_SUCCEEDED(rv) && doesInheritSecurityContext) { return NS_OK;
}
}
// Get the principal uri for the WebExtension access check or error.
nsCOMPtr<nsIURI> prinURI;
rv = GetURI(getter_AddRefs(prinURI)); if (!(NS_SUCCEEDED(rv) && prinURI)) { return NS_ERROR_DOM_BAD_URI;
}
// If the URL being loaded corresponds to a WebExtension URL, ask the policy // if the path should be accessible. bool isWebExtensionResource;
rv = NS_URIChainHasFlags(aURI,
nsIProtocolHandler::URI_IS_WEBEXTENSION_RESOURCE,
&isWebExtensionResource); if (NS_SUCCEEDED(rv) && isWebExtensionResource) {
extensions::URLInfo urlInfo(aURI); if (RefPtr<extensions::WebExtensionPolicyCore> urlPolicyCore =
ExtensionPolicyService::GetCoreByURL(urlInfo)) {
extensions::URLInfo prinUrlInfo(prinURI); if (urlPolicyCore->SourceMayAccessPath(prinUrlInfo, urlInfo.FilePath())) { return NS_OK;
}
}
}
if (aReport) { // FIXME: Once bug 1900706 is complete, reporting can be updated to work // off-main-thread.
nsScriptSecurityManager::ReportError("CheckSameOriginError", prinURI, aURI,
mOriginAttributes.IsPrivateBrowsing(),
aInnerWindowID);
}
*aRes = true; // If we do not have a URI its always 3rd party.
nsCOMPtr<nsIURI> prinURI;
nsresult rv = GetURI(getter_AddRefs(prinURI)); if (NS_FAILED(rv) || !prinURI) { return NS_OK;
}
ThirdPartyUtil* thirdPartyUtil = ThirdPartyUtil::GetInstance(); return thirdPartyUtil->IsThirdPartyURI(prinURI, aURI, aRes);
}
NS_IMETHODIMP
BasePrincipal::IsThirdPartyChannel(nsIChannel* aChan, bool* aRes) {
AssertIsOnMainThread(); if (IsSystemPrincipal()) { // Nothing is 3rd party to the system principal.
*aRes = false; return NS_OK;
}
// Allow access to uris that cannot be loaded by web content.
rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_DANGEROUS_TO_LOAD,
&hasFlags);
NS_ENSURE_SUCCESS(rv, NS_OK); if (hasFlags) {
*aRes = true; return NS_OK;
}
// UI resources also get access.
rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_IS_UI_RESOURCE,
&hasFlags);
NS_ENSURE_SUCCESS(rv, NS_OK); if (hasFlags) {
*aRes = true; return NS_OK;
}
// Expanded principals override CSP if and only if they subsume the document // principal. if (mKind == eExpandedPrincipal) { return FastSubsumes(aDocumentPrincipal);
} // Extension principals always override the CSP of non-extension principals. // This is primarily for the sake of their stylesheets, which are usually // loaded from channels and cannot have expanded principals. return (AddonPolicyCore() &&
!BasePrincipal::Cast(aDocumentPrincipal)->AddonPolicyCore());
}
nsAutoCString originNoSuffix;
nsresult rv =
ContentPrincipal::GenerateOriginNoSuffixFromURI(aURI, originNoSuffix); if (NS_FAILED(rv)) { // If the generation of the origin fails, we still want to have a valid // principal. Better to return a null principal here. return NullPrincipal::Create(aAttrs);
}
// If the URI is supposed to inherit the security context of whoever loads it, // we shouldn't make a content principal for it. bool inheritsPrincipal;
nsresult rv = NS_URIChainHasFlags(
aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
&inheritsPrincipal); if (NS_FAILED(rv) || inheritsPrincipal) { return NullPrincipal::Create(aAttrs);
}
// Check whether the URI knows what its principal is supposed to be. #ifdefined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
nsCOMPtr<nsIURIWithSpecialOrigin> uriWithSpecialOrigin =
do_QueryInterface(aURI); if (uriWithSpecialOrigin) {
nsCOMPtr<nsIURI> origin;
rv = uriWithSpecialOrigin->GetOrigin(getter_AddRefs(origin)); if (NS_WARN_IF(NS_FAILED(rv))) { return nullptr;
}
MOZ_ASSERT(origin);
OriginAttributes attrs;
RefPtr<BasePrincipal> principal =
CreateContentPrincipal(origin, attrs, aInitialDomain); return principal.forget();
} #endif
nsCOMPtr<nsIPrincipal> blobPrincipal; if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(
aURI, getter_AddRefs(blobPrincipal))) {
MOZ_ASSERT(blobPrincipal);
MOZ_ASSERT(!aInitialDomain, "an initial domain for a blob URI makes no sense");
RefPtr<BasePrincipal> principal = Cast(blobPrincipal); return principal.forget();
}
// Mint a content principal.
RefPtr<ContentPrincipal> principal = new ContentPrincipal(aURI, aAttrs, aOriginNoSuffix, aInitialDomain); return principal.forget();
}
already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal( const nsACString& aOrigin) {
MOZ_ASSERT(!StringBeginsWith(aOrigin, "["_ns), "CreateContentPrincipal does not support System and Expanded " "principals");
MOZ_ASSERT(
!StringBeginsWith(aOrigin, nsLiteralCString(NS_NULLPRINCIPAL_SCHEME ":")), "CreateContentPrincipal does not support NullPrincipal");
// XXX: This does not copy over the domain. Should it?
RefPtr<ContentPrincipal> copy = new ContentPrincipal(uri, aOriginAttributes, originNoSuffix, nullptr); return copy.forget();
}
if (NS_FAILED(rv) || subDomain.IsEmpty()) { return NS_OK;
}
nsCOMPtr<nsIURI> subDomainURI;
rv = NS_MutateURI(uri).SetHost(subDomain).Finalize(subDomainURI); if (NS_FAILED(rv) || !subDomainURI) { return NS_OK;
} // Copy the attributes over
mozilla::OriginAttributes attrs = OriginAttributesRef();
if (!StaticPrefs::permissions_isolateBy_userContext()) { // Disable userContext for permissions.
attrs.StripAttributes(mozilla::OriginAttributes::STRIP_USER_CONTEXT_ID);
}
RefPtr<nsIPrincipal> principal =
mozilla::BasePrincipal::CreateContentPrincipal(subDomainURI, attrs);
if (!principal) { return NS_OK;
}
principal.forget(aNextSubDomainPrincipal); return NS_OK;
}
if (domainOrigin.IsEmpty()) { // For the file:/// protocol use the exact directory as domain. if (uri->SchemeIs("file")) {
nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = url->GetDirectory(domainOrigin);
NS_ENSURE_SUCCESS(rv, rv);
}
}
NS_IMETHODIMP
BasePrincipal::Deserializer::Write(nsIObjectOutputStream* aStream) { // Read is used still for legacy principals
MOZ_RELEASE_ASSERT(false, "Old style serialization is removed"); return NS_OK;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.