diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp index 61578196f6f9..8b0b3eda0094 100644 --- a/dom/base/Document.cpp +++ b/dom/base/Document.cpp @@ -5720,26 +5720,6 @@ void Document::SetCookie(const nsAString& aCookie, ErrorResult& aRv) { return; } - // The code for getting the URI matches Navigator::CookieEnabled - nsCOMPtr principalURI; - auto* basePrin = BasePrincipal::Cast(NodePrincipal()); - basePrin->GetURI(getter_AddRefs(principalURI)); - - if (!principalURI) { - // Document's principal is not a content or null (may be system), so - // can't set cookies - - return; - } - - nsCOMPtr channel(mChannel); - if (!channel) { - channel = CreateDummyChannelForCookies(principalURI); - if (!channel) { - return; - } - } - // not having a cookie service isn't an error nsCOMPtr service = do_GetService(NS_COOKIESERVICE_CONTRACTID); @@ -5748,7 +5728,7 @@ void Document::SetCookie(const nsAString& aCookie, ErrorResult& aRv) { } NS_ConvertUTF16toUTF8 cookie(aCookie); - nsresult rv = service->SetCookieString(principalURI, cookie, channel); + nsresult rv = service->SetCookieStringFromDocument(this, cookie); // No warning messages here. if (NS_FAILED(rv)) { @@ -5763,45 +5743,6 @@ void Document::SetCookie(const nsAString& aCookie, ErrorResult& aRv) { } } -already_AddRefed Document::CreateDummyChannelForCookies( - nsIURI* aContentURI) { - // The cookie service reads the privacy status of the channel we pass to it in - // order to determine which cookie database to query. In some cases we don't - // have a proper channel to hand it to the cookie service though. This - // function creates a dummy channel that is not used to load anything, for the - // sole purpose of handing it to the cookie service. DO NOT USE THIS CHANNEL - // FOR ANY OTHER PURPOSE. - MOZ_ASSERT(!mChannel); - - // The following channel is never openend, so it does not matter what - // securityFlags we pass; let's follow the principle of least privilege. - nsCOMPtr channel; - NS_NewChannel(getter_AddRefs(channel), aContentURI, this, - nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED, - nsIContentPolicy::TYPE_INVALID); - nsCOMPtr pbChannel = do_QueryInterface(channel); - nsCOMPtr docShell(mDocumentContainer); - nsCOMPtr loadContext = do_QueryInterface(docShell); - if (!pbChannel || !loadContext) { - return nullptr; - } - pbChannel->SetPrivate(loadContext->UsePrivateBrowsing()); - - // We need to set the hasStoragePermission for the dummy channel because we - // will use this channel to do a content blocking check. The channel URI - // is from the NodePrincipal of this document which is the inital document for - // the 'about:blank' content viewer. In this case, the NodePrincipal is the - // same as the parent document if the parent exists. So, we can copy the flag - // from the parent document directly. - bool parentDocHasStoragePermissin = - mParentDocument ? mParentDocument->HasStoragePermission() : false; - - nsCOMPtr loadInfo = channel->LoadInfo(); - Unused << loadInfo->SetHasStoragePermission(parentDocHasStoragePermissin); - - return channel.forget(); -} - ReferrerPolicy Document::GetReferrerPolicy() const { return mReferrerInfo ? mReferrerInfo->ReferrerPolicy() : ReferrerPolicy::_empty; diff --git a/dom/base/Document.h b/dom/base/Document.h index 402c37c6479e..efca53f39ee9 100644 --- a/dom/base/Document.h +++ b/dom/base/Document.h @@ -4202,10 +4202,6 @@ class Document : public nsINode, MOZ_MUST_USE RefPtr AutomaticStorageAccessCanBeGranted(); - // This should *ONLY* be used in GetCookie/SetCookie. - already_AddRefed CreateDummyChannelForCookies( - nsIURI* aContentURI); - static void AddToplevelLoadingDocument(Document* aDoc); static void RemoveToplevelLoadingDocument(Document* aDoc); static AutoTArray* sLoadingForegroundTopLevelContentDocument; diff --git a/netwerk/cookie/CookieCommons.cpp b/netwerk/cookie/CookieCommons.cpp index 14e749bcf4d7..569feb27fae2 100644 --- a/netwerk/cookie/CookieCommons.cpp +++ b/netwerk/cookie/CookieCommons.cpp @@ -5,13 +5,23 @@ #include "Cookie.h" #include "CookieCommons.h" +#include "CookieService.h" +#include "mozilla/ContentBlocking.h" +#include "mozilla/ConsoleReportCollector.h" #include "mozilla/ContentBlockingNotifier.h" +#include "mozilla/dom/nsMixedContentBlocker.h" +#include "mozIThirdPartyUtil.h" +#include "nsContentUtils.h" +#include "nsICookieJarSettings.h" #include "nsICookiePermission.h" #include "nsICookieService.h" #include "nsIEffectiveTLDService.h" #include "nsScriptSecurityManager.h" namespace mozilla { + +using dom::Document; + namespace net { // static @@ -64,7 +74,7 @@ bool CookieCommons::PathMatches(Cookie* aCookie, const nsACString& aPath) { // be the exact host, and aRequireHostMatch will be true to indicate that // substring matches should not be performed. nsresult CookieCommons::GetBaseDomain(nsIEffectiveTLDService* aTLDService, - nsIURI* aHostURI, nsCString& aBaseDomain, + nsIURI* aHostURI, nsACString& aBaseDomain, bool& aRequireHostMatch) { // get the base domain. this will fail if the host contains a leading dot, // more than one trailing dot, or is otherwise malformed. @@ -92,6 +102,18 @@ nsresult CookieCommons::GetBaseDomain(nsIEffectiveTLDService* aTLDService, return NS_OK; } +nsresult CookieCommons::GetBaseDomain(nsIPrincipal* aPrincipal, + nsACString& aBaseDomain) { + MOZ_ASSERT(aPrincipal); + + // for historical reasons we use ascii host for file:// URLs. + if (aPrincipal->SchemeIs("file")) { + return aPrincipal->GetAsciiHost(aBaseDomain); + } + + return aPrincipal->GetBaseDomain(aBaseDomain); +} + // Get the base domain for aHost; e.g. for "www.bbc.co.uk", this would be // "bbc.co.uk". This is done differently than GetBaseDomain(mTLDService, ): it // is assumed that aHost is already normalized, and it may contain a leading dot @@ -130,10 +152,9 @@ nsresult CookieCommons::GetBaseDomainFromHost( return rv; } -// Notify observers that a cookie was rejected due to the users' prefs. -void CookieCommons::NotifyRejected(nsIURI* aHostURI, nsIChannel* aChannel, - uint32_t aRejectedReason, - CookieOperation aOperation) { +namespace { + +void NotifyRejectionToObservers(nsIURI* aHostURI, CookieOperation aOperation) { if (aOperation == OPERATION_WRITE) { nsCOMPtr os = services::GetObserverService(); if (os) { @@ -142,6 +163,15 @@ void CookieCommons::NotifyRejected(nsIURI* aHostURI, nsIChannel* aChannel, } else { MOZ_ASSERT(aOperation == OPERATION_READ); } +} + +} // namespace + +// Notify observers that a cookie was rejected due to the users' prefs. +void CookieCommons::NotifyRejected(nsIURI* aHostURI, nsIChannel* aChannel, + uint32_t aRejectedReason, + CookieOperation aOperation) { + NotifyRejectionToObservers(aHostURI, aOperation); ContentBlockingNotifier::OnDecision( aChannel, ContentBlockingNotifier::BlockingDecision::eBlock, @@ -208,12 +238,24 @@ bool CookieCommons::CheckCookiePermission(nsIChannel* aChannel, return false; } - if (!channelPrincipal->GetIsContentPrincipal()) { + return CheckCookiePermission(channelPrincipal, cookieJarSettings, + aCookieData); +} + +// static +bool CookieCommons::CheckCookiePermission( + nsIPrincipal* aPrincipal, nsICookieJarSettings* aCookieJarSettings, + CookieStruct& aCookieData) { + MOZ_ASSERT(aPrincipal); + MOZ_ASSERT(aCookieJarSettings); + + if (!aPrincipal->GetIsContentPrincipal()) { return true; } uint32_t cookiePermission = nsICookiePermission::ACCESS_DEFAULT; - rv = cookieJarSettings->CookiePermission(channelPrincipal, &cookiePermission); + nsresult rv = + aCookieJarSettings->CookiePermission(aPrincipal, &cookiePermission); if (NS_WARN_IF(NS_FAILED(rv))) { return true; } @@ -257,5 +299,133 @@ bool CookieCommons::CheckCookiePermission(nsIChannel* aChannel, return true; } +namespace { + +CookieStatus CookieStatusForWindow(nsPIDOMWindowInner* aWindow, + nsIURI* aDocumentURI) { + MOZ_ASSERT(aWindow); + MOZ_ASSERT(aDocumentURI); + + if (!nsContentUtils::IsThirdPartyWindowOrChannel(aWindow, nullptr, + aDocumentURI)) { + return STATUS_ACCEPTED; + } + + if (StaticPrefs::network_cookie_thirdparty_sessionOnly()) { + return STATUS_ACCEPT_SESSION; + } + + if (StaticPrefs::network_cookie_thirdparty_nonsecureSessionOnly() && + !nsMixedContentBlocker::IsPotentiallyTrustworthyOrigin(aDocumentURI)) { + return STATUS_ACCEPT_SESSION; + } + + return STATUS_ACCEPTED; +} + +} // namespace + +// static +already_AddRefed CookieCommons::CreateCookieFromDocument( + Document* aDocument, const nsACString& aCookieString, + int64_t currentTimeInUsec, nsIEffectiveTLDService* aTLDService, + mozIThirdPartyUtil* aThirdPartyUtil, + std::function&& + aHasExistingCookiesLambda, + nsIURI** aDocumentURI, nsACString& aBaseDomain, OriginAttributes& aAttrs) { + nsCOMPtr storagePrincipal = + aDocument->EffectiveStoragePrincipal(); + MOZ_ASSERT(storagePrincipal); + + nsCOMPtr principalURI; + auto* basePrincipal = BasePrincipal::Cast(aDocument->NodePrincipal()); + basePrincipal->GetURI(getter_AddRefs(principalURI)); + if (NS_WARN_IF(!principalURI)) { + // Document's principal is not a content or null (may be system), so + // can't set cookies + return nullptr; + } + + nsAutoCString baseDomain; + bool requireHostMatch = false; + nsresult rv = CookieCommons::GetBaseDomain(aTLDService, principalURI, + baseDomain, requireHostMatch); + if (NS_WARN_IF(NS_FAILED(rv))) { + return nullptr; + } + + nsPIDOMWindowInner* innerWindow = aDocument->GetInnerWindow(); + if (NS_WARN_IF(!innerWindow)) { + return nullptr; + } + + // Check if limit-foreign is required. + uint32_t dummyRejectedReason = 0; + if (aDocument->CookieJarSettings()->GetLimitForeignContexts() && + !aHasExistingCookiesLambda(baseDomain, + storagePrincipal->OriginAttributesRef()) && + !ContentBlocking::ShouldAllowAccessFor(innerWindow, principalURI, + &dummyRejectedReason)) { + return nullptr; + } + + bool isForeignAndNotAddon = false; + if (!BasePrincipal::Cast(aDocument->NodePrincipal())->AddonPolicy()) { + rv = aThirdPartyUtil->IsThirdPartyWindow( + innerWindow->GetOuterWindow(), principalURI, &isForeignAndNotAddon); + if (NS_WARN_IF(NS_FAILED(rv))) { + isForeignAndNotAddon = true; + } + } + + // If we are here, we have been already accepted by the anti-tracking. + // We just need to check if we have to be in session-only mode. + CookieStatus cookieStatus = CookieStatusForWindow(innerWindow, principalURI); + MOZ_ASSERT(cookieStatus == STATUS_ACCEPTED || + cookieStatus == STATUS_ACCEPT_SESSION); + + // Console report takes care of the correct reporting at the exit of this + // method. + RefPtr crc = new ConsoleReportCollector(); + auto scopeExit = MakeScopeExit([&] { crc->FlushConsoleReports(aDocument); }); + + nsCString cookieString(aCookieString); + + CookieStruct cookieData; + bool canSetCookie = false; + CookieService::CanSetCookie(principalURI, baseDomain, cookieData, + requireHostMatch, cookieStatus, cookieString, + false, isForeignAndNotAddon, crc, canSetCookie); + + if (!canSetCookie) { + return nullptr; + } + + // check permissions from site permission list. + if (!CookieCommons::CheckCookiePermission(aDocument->NodePrincipal(), + aDocument->CookieJarSettings(), + cookieData)) { + NotifyRejectionToObservers(principalURI, OPERATION_WRITE); + ContentBlockingNotifier::OnDecision( + innerWindow, ContentBlockingNotifier::BlockingDecision::eBlock, + nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION); + return nullptr; + } + + RefPtr cookie = + Cookie::Create(cookieData, storagePrincipal->OriginAttributesRef()); + MOZ_ASSERT(cookie); + + cookie->SetLastAccessed(currentTimeInUsec); + cookie->SetCreationTime( + Cookie::GenerateUniqueCreationTime(currentTimeInUsec)); + + aBaseDomain = baseDomain; + aAttrs = storagePrincipal->OriginAttributesRef(); + principalURI.forget(aDocumentURI); + + return cookie.forget(); +} + } // namespace net } // namespace mozilla diff --git a/netwerk/cookie/CookieCommons.h b/netwerk/cookie/CookieCommons.h index e511c1d8f203..8aa64506484d 100644 --- a/netwerk/cookie/CookieCommons.h +++ b/netwerk/cookie/CookieCommons.h @@ -7,19 +7,39 @@ #define mozilla_net_CookieCommons_h #include +#include #include "prtime.h" #include "nsString.h" class nsIChannel; +class nsICookieJarSettings; class nsIEffectiveTLDService; +class nsIPrincipal; class nsIURI; namespace mozilla { + +namespace dom { +class Document; +} + namespace net { // these constants represent an operation being performed on cookies enum CookieOperation { OPERATION_READ, OPERATION_WRITE }; +// these constants represent a decision about a cookie based on user prefs. +enum CookieStatus { + STATUS_ACCEPTED, + STATUS_ACCEPT_SESSION, + STATUS_REJECTED, + // STATUS_REJECTED_WITH_ERROR indicates the cookie should be rejected because + // of an error (rather than something the user can control). this is used for + // notification purposes, since we only want to notify of rejections where + // the user can do something about it (e.g. whitelist the site). + STATUS_REJECTED_WITH_ERROR +}; + class Cookie; // pref string constants @@ -46,9 +66,12 @@ class CookieCommons final { static bool PathMatches(Cookie* aCookie, const nsACString& aPath); static nsresult GetBaseDomain(nsIEffectiveTLDService* aTLDService, - nsIURI* aHostURI, nsCString& aBaseDomain, + nsIURI* aHostURI, nsACString& aBaseDomain, bool& aRequireHostMatch); + static nsresult GetBaseDomain(nsIPrincipal* aPrincipal, + nsACString& aBaseDomain); + static nsresult GetBaseDomainFromHost(nsIEffectiveTLDService* aTLDService, const nsACString& aHost, nsCString& aBaseDomain); @@ -67,6 +90,18 @@ class CookieCommons final { static bool CheckCookiePermission(nsIChannel* aChannel, CookieStruct& aCookieData); + + static bool CheckCookiePermission(nsIPrincipal* aPrincipal, + nsICookieJarSettings* aCookieJarSettings, + CookieStruct& aCookieData); + + static already_AddRefed CreateCookieFromDocument( + dom::Document* aDocument, const nsACString& aCookieString, + int64_t aCurrentTimeInUsec, nsIEffectiveTLDService* aTLDService, + mozIThirdPartyUtil* aThirdPartyUtil, + std::function&& + aHasExistingCookiesLambda, + nsIURI** aDocumentURI, nsACString& aBaseDomain, OriginAttributes& aAttrs); }; } // namespace net diff --git a/netwerk/cookie/CookieService.cpp b/netwerk/cookie/CookieService.cpp index 5201517d9459..58d75957bf43 100644 --- a/netwerk/cookie/CookieService.cpp +++ b/netwerk/cookie/CookieService.cpp @@ -266,13 +266,7 @@ CookieService::GetCookieStringForPrincipal(nsIPrincipal* aPrincipal, CookieStorage* storage = PickStorage(aPrincipal->OriginAttributesRef()); nsAutoCString baseDomain; - // for historical reasons we use ascii host for file:// URLs. - if (aPrincipal->SchemeIs("file")) { - rv = aPrincipal->GetAsciiHost(baseDomain); - } else { - rv = aPrincipal->GetBaseDomain(baseDomain); - } - + rv = CookieCommons::GetBaseDomain(aPrincipal, baseDomain); if (NS_WARN_IF(NS_FAILED(rv))) { return NS_OK; } @@ -423,6 +417,43 @@ CookieService::SetCookieString(nsIURI* aHostURI, return SetCookieStringCommon(aHostURI, aCookieHeader, aChannel, false); } +NS_IMETHODIMP +CookieService::SetCookieStringFromDocument(Document* aDocument, + const nsACString& aCookieString) { + NS_ENSURE_ARG(aDocument); + + if (!IsInitialized()) { + return NS_OK; + } + + nsCOMPtr documentURI; + nsAutoCString baseDomain; + OriginAttributes attrs; + + int64_t currentTimeInUsec = PR_Now(); + + // This function is executed in this context, I don't need to keep objects + // alive. + auto hasExistingCookiesLambda = [&](const nsACString& aBaseDomain, + const OriginAttributes& aAttrs) { + CookieStorage* storage = PickStorage(aAttrs); + return !!storage->CountCookiesFromHost(aBaseDomain, + aAttrs.mPrivateBrowsingId); + }; + + RefPtr cookie = CookieCommons::CreateCookieFromDocument( + aDocument, aCookieString, currentTimeInUsec, mTLDService, mThirdPartyUtil, + hasExistingCookiesLambda, getter_AddRefs(documentURI), baseDomain, attrs); + if (!cookie) { + return NS_OK; + } + + // add the cookie to the list. AddCookie() takes care of logging. + PickStorage(attrs)->AddCookie(baseDomain, attrs, cookie, currentTimeInUsec, + documentURI, aCookieString, false); + return NS_OK; +} + NS_IMETHODIMP CookieService::SetCookieStringFromHttp(nsIURI* aHostURI, const nsACString& aCookieHeader, @@ -1077,8 +1108,6 @@ bool CookieService::SetCookieInternal(CookieStorage* aStorage, nsIURI* aHostURI, Cookie::GenerateUniqueCreationTime(currentTimeInUsec)); // add the cookie to the list. AddCookie() takes care of logging. - // we get the current time again here, since it may have changed during - // prompting aStorage->AddCookie(aBaseDomain, aOriginAttributes, cookie, currentTimeInUsec, aHostURI, savedCookieHeader, aFromHttp); return newCookie; diff --git a/netwerk/cookie/CookieService.h b/netwerk/cookie/CookieService.h index 8f0f19945997..132f0b05de85 100644 --- a/netwerk/cookie/CookieService.h +++ b/netwerk/cookie/CookieService.h @@ -12,6 +12,7 @@ #include "nsWeakReference.h" #include "Cookie.h" +#include "CookieCommons.h" #include "nsString.h" #include "nsIMemoryReporter.h" @@ -32,18 +33,6 @@ class CookiePersistentStorage; class CookiePrivateStorage; class CookieStorage; -// these constants represent a decision about a cookie based on user prefs. -enum CookieStatus { - STATUS_ACCEPTED, - STATUS_ACCEPT_SESSION, - STATUS_REJECTED, - // STATUS_REJECTED_WITH_ERROR indicates the cookie should be rejected because - // of an error (rather than something the user can control). this is used for - // notification purposes, since we only want to notify of rejections where - // the user can do something about it (e.g. whitelist the site). - STATUS_REJECTED_WITH_ERROR -}; - /****************************************************************************** * CookieService: * class declaration diff --git a/netwerk/cookie/CookieServiceChild.cpp b/netwerk/cookie/CookieServiceChild.cpp index 6e6f3b2daeaf..db887681d1e3 100644 --- a/netwerk/cookie/CookieServiceChild.cpp +++ b/netwerk/cookie/CookieServiceChild.cpp @@ -13,12 +13,10 @@ #include "mozilla/BasePrincipal.h" #include "mozilla/ClearOnShutdown.h" #include "mozilla/dom/ContentChild.h" -#include "mozilla/dom/nsMixedContentBlocker.h" #include "mozilla/ipc/URIUtils.h" #include "mozilla/net/NeckoChild.h" #include "mozilla/StaticPrefs_network.h" #include "mozilla/StoragePrincipalHelper.h" -#include "nsContentUtils.h" #include "nsNetCID.h" #include "nsNetUtil.h" #include "nsIChannel.h" @@ -225,7 +223,7 @@ void CookieServiceChild::PrefChanged(nsIPrefBranch* aPrefBranch) { } uint32_t CookieServiceChild::CountCookiesFromHashTable( - const nsCString& aBaseDomain, const OriginAttributes& aOriginAttrs) { + const nsACString& aBaseDomain, const OriginAttributes& aOriginAttrs) { CookiesList* cookiesList = nullptr; nsCString baseDomain; @@ -469,18 +467,10 @@ CookieServiceChild::GetCookieStringForPrincipal(nsIPrincipal* aPrincipal, nsACString& aCookieString) { NS_ENSURE_ARG(aPrincipal); - nsresult rv; - aCookieString.Truncate(); nsAutoCString baseDomain; - // for historical reasons we use ascii host for file:// URLs. - if (aPrincipal->SchemeIs("file")) { - rv = aPrincipal->GetAsciiHost(baseDomain); - } else { - rv = aPrincipal->GetBaseDomain(baseDomain); - } - + nsresult rv = CookieCommons::GetBaseDomain(aPrincipal, baseDomain); if (NS_WARN_IF(NS_FAILED(rv))) { return NS_OK; } @@ -564,6 +554,62 @@ CookieServiceChild::SetCookieString(nsIURI* aHostURI, return SetCookieStringInternal(aHostURI, aChannel, aCookieString, false); } +NS_IMETHODIMP +CookieServiceChild::SetCookieStringFromDocument( + Document* aDocument, const nsACString& aCookieString) { + NS_ENSURE_ARG(aDocument); + + nsCOMPtr documentURI; + nsAutoCString baseDomain; + OriginAttributes attrs; + + // This function is executed in this context, I don't need to keep objects + // alive. + auto hasExistingCookiesLambda = [&](const nsACString& aBaseDomain, + const OriginAttributes& aAttrs) { + return !!CountCookiesFromHashTable(aBaseDomain, aAttrs); + }; + + RefPtr cookie = CookieCommons::CreateCookieFromDocument( + aDocument, aCookieString, PR_Now(), mTLDService, mThirdPartyUtil, + hasExistingCookiesLambda, getter_AddRefs(documentURI), baseDomain, attrs); + if (!cookie) { + return NS_OK; + } + + CookieKey key(baseDomain, attrs); + CookiesList* cookies = mCookiesMap.Get(key); + + if (cookies) { + // We need to see if the cookie we're setting would overwrite an httponly + // one. This would not affect anything we send over the net (those come + // from the parent, which already checks this), but script could see an + // inconsistent view of things. + for (uint32_t i = 0; i < cookies->Length(); ++i) { + RefPtr existingCookie = cookies->ElementAt(i); + if (existingCookie->Name().Equals(cookie->Name()) && + existingCookie->Host().Equals(cookie->Host()) && + existingCookie->Path().Equals(cookie->Path()) && + existingCookie->IsHttpOnly()) { + // Can't overwrite an httponly cookie from a script context. + return NS_OK; + } + } + } + + RecordDocumentCookie(cookie, attrs); + + if (CanSend()) { + nsTArray cookiesToSend; + cookiesToSend.AppendElement(cookie->ToIPC()); + + // Asynchronously call the parent. + SendSetCookies(baseDomain, attrs, documentURI, false, cookiesToSend); + } + + return NS_OK; +} + NS_IMETHODIMP CookieServiceChild::SetCookieStringFromHttp(nsIURI* aHostURI, const nsACString& aCookieString, diff --git a/netwerk/cookie/CookieServiceChild.h b/netwerk/cookie/CookieServiceChild.h index 39e0aa2281d0..47b19f04f524 100644 --- a/netwerk/cookie/CookieServiceChild.h +++ b/netwerk/cookie/CookieServiceChild.h @@ -57,7 +57,7 @@ class CookieServiceChild final : public PCookieServiceChild, void RecordDocumentCookie(Cookie* aCookie, const OriginAttributes& aAttrs); - uint32_t CountCookiesFromHashTable(const nsCString& aBaseDomain, + uint32_t CountCookiesFromHashTable(const nsACString& aBaseDomain, const OriginAttributes& aOriginAttrs); void PrefChanged(nsIPrefBranch* aPrefBranch); diff --git a/netwerk/cookie/nsICookieService.idl b/netwerk/cookie/nsICookieService.idl index 5b21d3718759..00f969b3675c 100644 --- a/netwerk/cookie/nsICookieService.idl +++ b/netwerk/cookie/nsICookieService.idl @@ -8,6 +8,7 @@ interface nsIURI; interface nsIChannel; interface nsIPrincipal; +webidl Document; /** * @see nsICookieService::runInTransaction @@ -121,6 +122,18 @@ interface nsICookieService : nsISupports */ ACString getCookieStringFromHttp(in nsIURI aURI, in nsIChannel aChannel); + /* + * Set the cookie string associated with a Document. This method is meant to + * be used for `document.cookie` only. Any security check about + * storage-access permission and cookie behavior must be done by the caller. + * + * @param aDocument + * The document. + * @param aCookie + * the cookie string to set. + */ + void setCookieStringFromDocument(in Document aDocument, in ACString aCookie); + /* * Set the cookie string associated with the URI. *