diff --git a/caps/BasePrincipal.cpp b/caps/BasePrincipal.cpp index 7e11455d943c..c12678a7bfcd 100644 --- a/caps/BasePrincipal.cpp +++ b/caps/BasePrincipal.cpp @@ -671,6 +671,7 @@ BasePrincipal::AllowsRelaxStrictFileOriginPolicy(nsIURI* aURI, bool* aRes) { NS_IMETHODIMP BasePrincipal::GetPrefLightCacheKey(nsIURI* aURI, bool aWithCredentials, + const OriginAttributes& aOriginAttributes, nsACString& _retval) { _retval.Truncate(); constexpr auto space = " "_ns; @@ -696,7 +697,11 @@ BasePrincipal::GetPrefLightCacheKey(nsIURI* aURI, bool aWithCredentials, rv = aURI->GetSpec(spec); NS_ENSURE_SUCCESS(rv, rv); - _retval.Append(space + scheme + space + host + space + port + space + spec); + nsAutoCString originAttributesSuffix; + aOriginAttributes.CreateSuffix(originAttributesSuffix); + + _retval.Append(space + scheme + space + host + space + port + space + spec + + space + originAttributesSuffix); return NS_OK; } diff --git a/caps/BasePrincipal.h b/caps/BasePrincipal.h index 54928c24b43b..6f0edbe1b106 100644 --- a/caps/BasePrincipal.h +++ b/caps/BasePrincipal.h @@ -154,6 +154,7 @@ class BasePrincipal : public nsJSPrincipals { NS_IMETHOD IsSameOrigin(nsIURI* aURI, bool aIsPrivateWin, bool* aRes) override; NS_IMETHOD GetPrefLightCacheKey(nsIURI* aURI, bool aWithCredentials, + const OriginAttributes& aOriginAttributes, nsACString& _retval) override; NS_IMETHOD HasFirstpartyStorageAccess(mozIDOMWindow* aCheckWindow, uint32_t* aRejectedReason, diff --git a/caps/nsIPrincipal.idl b/caps/nsIPrincipal.idl index 9869565aba97..5332259a4320 100644 --- a/caps/nsIPrincipal.idl +++ b/caps/nsIPrincipal.idl @@ -341,7 +341,9 @@ interface nsIPrincipal : nsISerializable /* * Generates a Cache-Key for the Cors-Preflight Cache */ - ACString getPrefLightCacheKey(in nsIURI aURI ,in bool aWithCredentials); + [noscript] + ACString getPrefLightCacheKey(in nsIURI aURI ,in bool aWithCredentials, + in const_OriginAttributes aOriginAttributes); /* diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp index a6ddc851d2b2..8369e1f1e8d0 100644 --- a/netwerk/protocol/http/HttpChannelChild.cpp +++ b/netwerk/protocol/http/HttpChannelChild.cpp @@ -2761,8 +2761,9 @@ void HttpChannelChild::GetClientSetCorsPreflightParameters( } NS_IMETHODIMP -HttpChannelChild::RemoveCorsPreflightCacheEntry(nsIURI* aURI, - nsIPrincipal* aPrincipal) { +HttpChannelChild::RemoveCorsPreflightCacheEntry( + nsIURI* aURI, nsIPrincipal* aPrincipal, + const OriginAttributes& aOriginAttributes) { URIParams uri; SerializeURI(aURI, uri); PrincipalInfo principalInfo; @@ -2774,7 +2775,8 @@ HttpChannelChild::RemoveCorsPreflightCacheEntry(nsIURI* aURI, // Be careful to not attempt to send a message to the parent after the // actor has been destroyed. if (CanSend()) { - result = SendRemoveCorsPreflightCacheEntry(uri, principalInfo); + result = SendRemoveCorsPreflightCacheEntry(uri, principalInfo, + aOriginAttributes); } return result ? NS_OK : NS_ERROR_FAILURE; } diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp index df71578ecd71..8cd1c1e0b45c 100644 --- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -1045,7 +1045,8 @@ HttpChannelParent::RecvMarkOfflineCacheEntryAsForeign() { mozilla::ipc::IPCResult HttpChannelParent::RecvRemoveCorsPreflightCacheEntry( const URIParams& uri, - const mozilla::ipc::PrincipalInfo& requestingPrincipal) { + const mozilla::ipc::PrincipalInfo& requestingPrincipal, + const OriginAttributes& originAttributes) { nsCOMPtr deserializedURI = DeserializeURI(uri); if (!deserializedURI) { return IPC_FAIL_NO_REASON(this); @@ -1055,7 +1056,8 @@ mozilla::ipc::IPCResult HttpChannelParent::RecvRemoveCorsPreflightCacheEntry( return IPC_FAIL_NO_REASON(this); } nsCOMPtr principal = principalOrErr.unwrap(); - nsCORSListenerProxy::RemoveFromCorsPreflightCache(deserializedURI, principal); + nsCORSListenerProxy::RemoveFromCorsPreflightCache(deserializedURI, principal, + originAttributes); return IPC_OK(); } diff --git a/netwerk/protocol/http/HttpChannelParent.h b/netwerk/protocol/http/HttpChannelParent.h index ada4a2b3b4ea..3b42ced2b18c 100644 --- a/netwerk/protocol/http/HttpChannelParent.h +++ b/netwerk/protocol/http/HttpChannelParent.h @@ -195,7 +195,8 @@ class HttpChannelParent final : public nsIInterfaceRequestor, virtual mozilla::ipc::IPCResult RecvMarkOfflineCacheEntryAsForeign() override; virtual mozilla::ipc::IPCResult RecvRemoveCorsPreflightCacheEntry( const URIParams& uri, - const mozilla::ipc::PrincipalInfo& requestingPrincipal) override; + const mozilla::ipc::PrincipalInfo& requestingPrincipal, + const OriginAttributes& originAttributes) override; virtual mozilla::ipc::IPCResult RecvBytesRead(const int32_t& aCount) override; virtual mozilla::ipc::IPCResult RecvOpenOriginalCacheInputStream() override; virtual mozilla::ipc::IPCResult RecvOpenAltDataCacheInputStream( diff --git a/netwerk/protocol/http/PHttpChannel.ipdl b/netwerk/protocol/http/PHttpChannel.ipdl index dc398f71e884..223c94369939 100644 --- a/netwerk/protocol/http/PHttpChannel.ipdl +++ b/netwerk/protocol/http/PHttpChannel.ipdl @@ -16,6 +16,8 @@ include HttpChannelParams; include "mozilla/net/NeckoMessageUtils.h"; +using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h"; + namespace mozilla { namespace net { @@ -69,7 +71,8 @@ parent: // Child has detected a CORS check failure, so needs to tell the parent // to remove any matching entry from the CORS preflight cache. async RemoveCorsPreflightCacheEntry(URIParams uri, - PrincipalInfo requestingPrincipal); + PrincipalInfo requestingPrincipal, + OriginAttributes originAttributes); // After receiving this message, the parent calls SendDeleteSelf, and makes // sure not to send any more messages after that. diff --git a/netwerk/protocol/http/nsCORSListenerProxy.cpp b/netwerk/protocol/http/nsCORSListenerProxy.cpp index 3501fb640da5..35acacad85a5 100644 --- a/netwerk/protocol/http/nsCORSListenerProxy.cpp +++ b/netwerk/protocol/http/nsCORSListenerProxy.cpp @@ -7,6 +7,7 @@ #include "mozilla/Assertions.h" #include "mozilla/LinkedList.h" #include "mozilla/StaticPrefs_content.h" +#include "mozilla/StoragePrincipalHelper.h" #include "nsCORSListenerProxy.h" #include "nsIChannel.h" @@ -168,8 +169,10 @@ class nsPreflightCache { bool Initialize() { return true; } CacheEntry* GetEntry(nsIURI* aURI, nsIPrincipal* aPrincipal, - bool aWithCredentials, bool aCreate); - void RemoveEntries(nsIURI* aURI, nsIPrincipal* aPrincipal); + bool aWithCredentials, + const OriginAttributes& aOriginAttributes, bool aCreate); + void RemoveEntries(nsIURI* aURI, nsIPrincipal* aPrincipal, + const OriginAttributes& aOriginAttributes); void Clear(); @@ -243,10 +246,10 @@ bool nsPreflightCache::CacheEntry::CheckRequest( nsPreflightCache::CacheEntry* nsPreflightCache::GetEntry( nsIURI* aURI, nsIPrincipal* aPrincipal, bool aWithCredentials, - bool aCreate) { + const OriginAttributes& aOriginAttributes, bool aCreate) { nsCString key; - if (NS_FAILED( - aPrincipal->GetPrefLightCacheKey(aURI, aWithCredentials, key))) { + if (NS_FAILED(aPrincipal->GetPrefLightCacheKey(aURI, aWithCredentials, + aOriginAttributes, key))) { NS_WARNING("Invalid cache key!"); return nullptr; } @@ -313,16 +316,20 @@ nsPreflightCache::CacheEntry* nsPreflightCache::GetEntry( return newEntry; } -void nsPreflightCache::RemoveEntries(nsIURI* aURI, nsIPrincipal* aPrincipal) { +void nsPreflightCache::RemoveEntries( + nsIURI* aURI, nsIPrincipal* aPrincipal, + const OriginAttributes& aOriginAttributes) { CacheEntry* entry; nsCString key; - if (NS_SUCCEEDED(aPrincipal->GetPrefLightCacheKey(aURI, true, key)) && + if (NS_SUCCEEDED(aPrincipal->GetPrefLightCacheKey(aURI, true, + aOriginAttributes, key)) && mTable.Get(key, &entry)) { entry->removeFrom(mList); mTable.Remove(key); } - if (NS_SUCCEEDED(aPrincipal->GetPrefLightCacheKey(aURI, false, key)) && + if (NS_SUCCEEDED(aPrincipal->GetPrefLightCacheKey(aURI, false, + aOriginAttributes, key)) && mTable.Get(key, &entry)) { entry->removeFrom(mList); mTable.Remove(key); @@ -396,16 +403,20 @@ nsCORSListenerProxy::OnStartRequest(nsIRequest* aRequest) { nsCOMPtr uri; NS_GetFinalChannelURI(channel, getter_AddRefs(uri)); if (uri) { + OriginAttributes attrs; + StoragePrincipalHelper::GetOriginAttributesForNetworkState(channel, + attrs); + if (sPreflightCache) { // OK to use mRequestingPrincipal since preflights never get // redirected. - sPreflightCache->RemoveEntries(uri, mRequestingPrincipal); + sPreflightCache->RemoveEntries(uri, mRequestingPrincipal, attrs); } else { nsCOMPtr httpChannelChild = do_QueryInterface(channel); if (httpChannelChild) { rv = httpChannelChild->RemoveCorsPreflightCacheEntry( - uri, mRequestingPrincipal); + uri, mRequestingPrincipal, attrs); if (NS_FAILED(rv)) { // Only warn here to ensure we fall through the request Cancel() // and outer listener OnStartRequest() calls. @@ -681,16 +692,19 @@ nsCORSListenerProxy::AsyncOnChannelRedirect( nsCOMPtr oldURI; NS_GetFinalChannelURI(aOldChannel, getter_AddRefs(oldURI)); if (oldURI) { + OriginAttributes attrs; + StoragePrincipalHelper::GetOriginAttributesForNetworkState(aOldChannel, + attrs); if (sPreflightCache) { // OK to use mRequestingPrincipal since preflights never get // redirected. - sPreflightCache->RemoveEntries(oldURI, mRequestingPrincipal); + sPreflightCache->RemoveEntries(oldURI, mRequestingPrincipal, attrs); } else { nsCOMPtr httpChannelChild = do_QueryInterface(aOldChannel); if (httpChannelChild) { rv = httpChannelChild->RemoveCorsPreflightCacheEntry( - oldURI, mRequestingPrincipal); + oldURI, mRequestingPrincipal, attrs); if (NS_FAILED(rv)) { // Only warn here to ensure we call the channel Cancel() below NS_WARNING("Failed to remove CORS preflight cache entry!"); @@ -1120,8 +1134,11 @@ void nsCORSPreflightListener::AddResultToCache(nsIRequest* aRequest) { TimeStamp expirationTime = TimeStamp::NowLoRes() + TimeDuration::FromSeconds(age); + OriginAttributes attrs; + StoragePrincipalHelper::GetOriginAttributesForNetworkState(http, attrs); + nsPreflightCache::CacheEntry* entry = sPreflightCache->GetEntry( - uri, mReferrerPrincipal, mWithCredentials, true); + uri, mReferrerPrincipal, mWithCredentials, attrs, true); if (!entry) { return; } @@ -1357,10 +1374,12 @@ nsCORSPreflightListener::GetInterface(const nsIID& aIID, void** aResult) { } void nsCORSListenerProxy::RemoveFromCorsPreflightCache( - nsIURI* aURI, nsIPrincipal* aRequestingPrincipal) { + nsIURI* aURI, nsIPrincipal* aRequestingPrincipal, + const OriginAttributes& aOriginAttributes) { MOZ_ASSERT(XRE_IsParentProcess()); if (sPreflightCache) { - sPreflightCache->RemoveEntries(aURI, aRequestingPrincipal); + sPreflightCache->RemoveEntries(aURI, aRequestingPrincipal, + aOriginAttributes); } } @@ -1405,7 +1424,11 @@ nsresult nsCORSListenerProxy::StartCORSPreflight( bool disableCache = Preferences::GetBool("devtools.cache.disabled"); if (sPreflightCache && !disableCache) { - entry = sPreflightCache->GetEntry(uri, principal, withCredentials, false); + OriginAttributes attrs; + StoragePrincipalHelper::GetOriginAttributesForNetworkState(aRequestChannel, + attrs); + entry = sPreflightCache->GetEntry(uri, principal, withCredentials, attrs, + false); } if (entry && entry->CheckRequest(method, aUnsafeHeaders)) { diff --git a/netwerk/protocol/http/nsCORSListenerProxy.h b/netwerk/protocol/http/nsCORSListenerProxy.h index 65ada4e7996f..db5100f42c0b 100644 --- a/netwerk/protocol/http/nsCORSListenerProxy.h +++ b/netwerk/protocol/http/nsCORSListenerProxy.h @@ -79,8 +79,9 @@ class nsCORSListenerProxy final : public nsIStreamListener, // Only nsHttpChannel can invoke CORS preflights friend class mozilla::net::nsHttpChannel; - static void RemoveFromCorsPreflightCache(nsIURI* aURI, - nsIPrincipal* aRequestingPrincipal); + static void RemoveFromCorsPreflightCache( + nsIURI* aURI, nsIPrincipal* aRequestingPrincipal, + const mozilla::OriginAttributes& aOriginAttributes); [[nodiscard]] static nsresult StartCORSPreflight( nsIChannel* aRequestChannel, nsICorsPreflightCallback* aCallback, nsTArray& aACUnsafeHeaders, nsIChannel** aPreflightChannel); diff --git a/netwerk/protocol/http/nsIHttpChannelChild.idl b/netwerk/protocol/http/nsIHttpChannelChild.idl index c4a8b794a714..c5509f011d15 100644 --- a/netwerk/protocol/http/nsIHttpChannelChild.idl +++ b/netwerk/protocol/http/nsIHttpChannelChild.idl @@ -5,8 +5,15 @@ #include "nsISupports.idl" +%{ C++ +namespace mozilla { +class OriginAttributes; +} // mozilla namespace +%} + [ptr] native RequestHeaderTuples(mozilla::net::RequestHeaderTuples); [ref] native MaybeCorsPreflightArgsRef(mozilla::Maybe); +[ref] native const_OriginAttributes(const mozilla::OriginAttributes); interface nsIPrincipal; interface nsIURI; @@ -26,5 +33,6 @@ interface nsIHttpChannelChild : nsISupports // This method is called by nsCORSListenerProxy if we need to remove // an entry from the CORS preflight cache in the parent process. [must_use] - void removeCorsPreflightCacheEntry(in nsIURI aURI, in nsIPrincipal aRequestingPrincipal); + void removeCorsPreflightCacheEntry(in nsIURI aURI, in nsIPrincipal aRequestingPrincipal, + in const_OriginAttributes aOriginAttributes); };