зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1904557 - part 2 - Improve cookie logging - Move the warning/reject logic in CookieParser, r=timhuang,cookie-reviewers,edgul
Differential Revision: https://phabricator.services.mozilla.com/D214807
This commit is contained in:
Родитель
6c8772e17c
Коммит
e10558d5a0
|
@ -8,14 +8,13 @@
|
|||
#include "CookieLogging.h"
|
||||
#include "CookieParser.h"
|
||||
#include "CookieService.h"
|
||||
#include "mozilla/ConsoleReportCollector.h"
|
||||
#include "mozilla/ContentBlockingNotifier.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/StaticPrefs_network.h"
|
||||
#include "mozilla/StorageAccess.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/nsMixedContentBlocker.h"
|
||||
#include "mozilla/net/CookieJarSettings.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozIThirdPartyUtil.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsICookiePermission.h"
|
||||
|
@ -335,29 +334,20 @@ CookieStatus CookieStatusForWindow(nsPIDOMWindowInner* aWindow,
|
|||
|
||||
// static
|
||||
already_AddRefed<Cookie> CookieCommons::CreateCookieFromDocument(
|
||||
Document* aDocument, const nsACString& aCookieString,
|
||||
int64_t currentTimeInUsec, nsIEffectiveTLDService* aTLDService,
|
||||
mozIThirdPartyUtil* aThirdPartyUtil,
|
||||
CookieParser& aCookieParser, Document* aDocument,
|
||||
const nsACString& aCookieString, int64_t currentTimeInUsec,
|
||||
nsIEffectiveTLDService* aTLDService, mozIThirdPartyUtil* aThirdPartyUtil,
|
||||
std::function<bool(const nsACString&, const OriginAttributes&)>&&
|
||||
aHasExistingCookiesLambda,
|
||||
nsIURI** aDocumentURI, nsACString& aBaseDomain, OriginAttributes& aAttrs) {
|
||||
nsCOMPtr<nsIURI> 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;
|
||||
}
|
||||
|
||||
if (!CookieCommons::IsSchemeSupported(principalURI)) {
|
||||
nsACString& aBaseDomain, OriginAttributes& aAttrs) {
|
||||
if (!CookieCommons::IsSchemeSupported(aCookieParser.HostURI())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsAutoCString baseDomain;
|
||||
bool requireHostMatch = false;
|
||||
nsresult rv = CookieCommons::GetBaseDomain(aTLDService, principalURI,
|
||||
baseDomain, requireHostMatch);
|
||||
nsresult rv = CookieCommons::GetBaseDomain(
|
||||
aTLDService, aCookieParser.HostURI(), baseDomain, requireHostMatch);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -369,8 +359,9 @@ already_AddRefed<Cookie> CookieCommons::CreateCookieFromDocument(
|
|||
|
||||
bool isForeignAndNotAddon = false;
|
||||
if (!BasePrincipal::Cast(aDocument->NodePrincipal())->AddonPolicy()) {
|
||||
rv = aThirdPartyUtil->IsThirdPartyWindow(
|
||||
innerWindow->GetOuterWindow(), principalURI, &isForeignAndNotAddon);
|
||||
rv = aThirdPartyUtil->IsThirdPartyWindow(innerWindow->GetOuterWindow(),
|
||||
aCookieParser.HostURI(),
|
||||
&isForeignAndNotAddon);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
isForeignAndNotAddon = true;
|
||||
}
|
||||
|
@ -384,34 +375,26 @@ already_AddRefed<Cookie> CookieCommons::CreateCookieFromDocument(
|
|||
|
||||
// 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);
|
||||
CookieStatus cookieStatus =
|
||||
CookieStatusForWindow(innerWindow, aCookieParser.HostURI());
|
||||
MOZ_ASSERT(cookieStatus == STATUS_ACCEPTED ||
|
||||
cookieStatus == STATUS_ACCEPT_SESSION);
|
||||
|
||||
// Console report takes care of the correct reporting at the exit of this
|
||||
// method.
|
||||
RefPtr<ConsoleReportCollector> crc = new ConsoleReportCollector();
|
||||
auto scopeExit = MakeScopeExit([&] { crc->FlushConsoleReports(aDocument); });
|
||||
|
||||
nsCString cookieString(aCookieString);
|
||||
|
||||
CookieStruct cookieData;
|
||||
MOZ_ASSERT(cookieData.creationTime() == 0, "Must be initialized to 0");
|
||||
bool canSetCookie = false;
|
||||
CookieParser::CanSetCookie(
|
||||
principalURI, baseDomain, cookieData, requireHostMatch, cookieStatus,
|
||||
cookieString, false, isForeignAndNotAddon, mustBePartitioned,
|
||||
aDocument->IsInPrivateBrowsing(), crc, canSetCookie);
|
||||
aCookieParser.Parse(baseDomain, requireHostMatch, cookieStatus, cookieString,
|
||||
false, isForeignAndNotAddon, mustBePartitioned,
|
||||
aDocument->IsInPrivateBrowsing());
|
||||
|
||||
if (!canSetCookie) {
|
||||
if (!aCookieParser.ContainsCookie()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// check permissions from site permission list.
|
||||
if (!CookieCommons::CheckCookiePermission(aDocument->NodePrincipal(),
|
||||
aDocument->CookieJarSettings(),
|
||||
cookieData)) {
|
||||
NotifyRejectionToObservers(principalURI, OPERATION_WRITE);
|
||||
aCookieParser.CookieData())) {
|
||||
NotifyRejectionToObservers(aCookieParser.HostURI(), OPERATION_WRITE);
|
||||
ContentBlockingNotifier::OnDecision(
|
||||
innerWindow, ContentBlockingNotifier::BlockingDecision::eBlock,
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION);
|
||||
|
@ -422,8 +405,8 @@ already_AddRefed<Cookie> CookieCommons::CreateCookieFromDocument(
|
|||
// cookie jar independent of context. If the cookies are stored in the
|
||||
// partitioned cookie jar anyway no special treatment of CHIPS cookies
|
||||
// necessary.
|
||||
bool needPartitioned =
|
||||
StaticPrefs::network_cookie_CHIPS_enabled() && cookieData.isPartitioned();
|
||||
bool needPartitioned = StaticPrefs::network_cookie_CHIPS_enabled() &&
|
||||
aCookieParser.CookieData().isPartitioned();
|
||||
nsCOMPtr<nsIPrincipal> cookiePrincipal =
|
||||
needPartitioned ? aDocument->PartitionedPrincipal()
|
||||
: aDocument->EffectiveCookiePrincipal();
|
||||
|
@ -434,12 +417,13 @@ already_AddRefed<Cookie> CookieCommons::CreateCookieFromDocument(
|
|||
if (aDocument->CookieJarSettings()->GetLimitForeignContexts() &&
|
||||
!aHasExistingCookiesLambda(baseDomain,
|
||||
cookiePrincipal->OriginAttributesRef()) &&
|
||||
!ShouldAllowAccessFor(innerWindow, principalURI, &dummyRejectedReason)) {
|
||||
!ShouldAllowAccessFor(innerWindow, aCookieParser.HostURI(),
|
||||
&dummyRejectedReason)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<Cookie> cookie =
|
||||
Cookie::Create(cookieData, cookiePrincipal->OriginAttributesRef());
|
||||
RefPtr<Cookie> cookie = Cookie::Create(
|
||||
aCookieParser.CookieData(), cookiePrincipal->OriginAttributesRef());
|
||||
MOZ_ASSERT(cookie);
|
||||
|
||||
cookie->SetLastAccessed(currentTimeInUsec);
|
||||
|
@ -448,7 +432,6 @@ already_AddRefed<Cookie> CookieCommons::CreateCookieFromDocument(
|
|||
|
||||
aBaseDomain = baseDomain;
|
||||
aAttrs = cookiePrincipal->OriginAttributesRef();
|
||||
principalURI.forget(aDocumentURI);
|
||||
|
||||
return cookie.forget();
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ enum CookieStatus {
|
|||
};
|
||||
|
||||
class Cookie;
|
||||
class CookieParser;
|
||||
|
||||
// pref string constants
|
||||
static const char kPrefMaxNumberOfCookies[] = "network.cookie.maxNumber";
|
||||
|
@ -99,12 +100,12 @@ class CookieCommons final {
|
|||
CookieStruct& aCookieData);
|
||||
|
||||
static already_AddRefed<Cookie> CreateCookieFromDocument(
|
||||
dom::Document* aDocument, const nsACString& aCookieString,
|
||||
int64_t aCurrentTimeInUsec, nsIEffectiveTLDService* aTLDService,
|
||||
mozIThirdPartyUtil* aThirdPartyUtil,
|
||||
CookieParser& aCookieParser, dom::Document* aDocument,
|
||||
const nsACString& aCookieString, int64_t aCurrentTimeInUsec,
|
||||
nsIEffectiveTLDService* aTLDService, mozIThirdPartyUtil* aThirdPartyUtil,
|
||||
std::function<bool(const nsACString&, const OriginAttributes&)>&&
|
||||
aHasExistingCookiesLambda,
|
||||
nsIURI** aDocumentURI, nsACString& aBaseDomain, OriginAttributes& aAttrs);
|
||||
nsACString& aBaseDomain, OriginAttributes& aAttrs);
|
||||
|
||||
static already_AddRefed<nsICookieJarSettings> GetCookieJarSettings(
|
||||
nsIChannel* aChannel);
|
||||
|
|
|
@ -4,12 +4,20 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "CookieParser.h"
|
||||
#include "CookieLogging.h"
|
||||
|
||||
#include "mozilla/dom/nsMixedContentBlocker.h"
|
||||
#include "mozilla/glean/GleanMetrics.h"
|
||||
#include "mozilla/StaticPrefs_network.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "nsIConsoleReportCollector.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIURL.h"
|
||||
#include "prprf.h"
|
||||
|
||||
constexpr char ATTRIBUTE_PATH[] = "path";
|
||||
constexpr uint64_t ATTRIBUTE_MAX_LENGTH = 1024;
|
||||
|
||||
constexpr auto CONSOLE_CHIPS_CATEGORY = "cookiesCHIPS"_ns;
|
||||
constexpr auto CONSOLE_OVERSIZE_CATEGORY = "cookiesOversize"_ns;
|
||||
|
@ -22,6 +30,180 @@ constexpr auto SAMESITE_MDN_URL =
|
|||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
CookieParser::CookieParser(nsIConsoleReportCollector* aCRC, nsIURI* aHostURI)
|
||||
: mCRC(aCRC), mHostURI(aHostURI) {
|
||||
MOZ_COUNT_CTOR(CookieParser);
|
||||
MOZ_ASSERT(aCRC);
|
||||
MOZ_ASSERT(aHostURI);
|
||||
}
|
||||
|
||||
CookieParser::~CookieParser() {
|
||||
MOZ_COUNT_DTOR(CookieParser);
|
||||
|
||||
#define COOKIE_LOGGING_WITH_NAME(category, x) \
|
||||
CookieLogging::LogMessageToConsole( \
|
||||
mCRC, mHostURI, nsIScriptError::errorFlag, category, x, \
|
||||
AutoTArray<nsString, 1>{NS_ConvertUTF8toUTF16(mCookieData.name())});
|
||||
|
||||
switch (mRejection) {
|
||||
case NoRejection:
|
||||
break;
|
||||
|
||||
case RejectedInvalidCharAttributes:
|
||||
COOKIE_LOGGING_WITH_NAME(CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedInvalidCharAttributes"_ns);
|
||||
break;
|
||||
|
||||
case RejectedNoneRequiresSecure:
|
||||
COOKIE_LOGGING_WITH_NAME(CONSOLE_SAMESITE_CATEGORY,
|
||||
"CookieRejectedNonRequiresSecure2"_ns);
|
||||
break;
|
||||
|
||||
case RejectedPartitionedRequiresSecure:
|
||||
COOKIE_LOGGING_WITH_NAME(CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedPartitionedRequiresSecure"_ns);
|
||||
break;
|
||||
|
||||
case RejectedEmptyNameAndValue:
|
||||
CookieLogging::LogMessageToConsole(
|
||||
mCRC, mHostURI, nsIScriptError::warningFlag,
|
||||
CONSOLE_REJECTION_CATEGORY, "CookieRejectedEmptyNameAndValue"_ns,
|
||||
nsTArray<nsString>());
|
||||
|
||||
break;
|
||||
|
||||
case RejectedNameValueOversize: {
|
||||
AutoTArray<nsString, 2> params = {
|
||||
NS_ConvertUTF8toUTF16(mCookieData.name())};
|
||||
|
||||
nsString size;
|
||||
size.AppendInt(kMaxBytesPerCookie);
|
||||
params.AppendElement(size);
|
||||
|
||||
CookieLogging::LogMessageToConsole(
|
||||
mCRC, mHostURI, nsIScriptError::warningFlag,
|
||||
CONSOLE_OVERSIZE_CATEGORY, "CookieOversize"_ns, params);
|
||||
break;
|
||||
}
|
||||
|
||||
case RejectedInvalidCharName:
|
||||
COOKIE_LOGGING_WITH_NAME(CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedInvalidCharName"_ns);
|
||||
break;
|
||||
|
||||
case RejectedInvalidDomain:
|
||||
COOKIE_LOGGING_WITH_NAME(CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedInvalidDomain"_ns);
|
||||
break;
|
||||
|
||||
case RejectedInvalidPrefix:
|
||||
COOKIE_LOGGING_WITH_NAME(CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedInvalidPrefix"_ns);
|
||||
break;
|
||||
|
||||
case RejectedInvalidCharValue:
|
||||
COOKIE_LOGGING_WITH_NAME(CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedInvalidCharValue"_ns);
|
||||
break;
|
||||
|
||||
case RejectedHttpOnlyButFromScript:
|
||||
COOKIE_LOGGING_WITH_NAME(CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedHttpOnlyButFromScript"_ns);
|
||||
break;
|
||||
|
||||
case RejectedSecureButNonHttps:
|
||||
COOKIE_LOGGING_WITH_NAME(CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedSecureButNonHttps"_ns);
|
||||
break;
|
||||
|
||||
case RejectedForNonSameSiteness:
|
||||
COOKIE_LOGGING_WITH_NAME(CONSOLE_SAMESITE_CATEGORY,
|
||||
"CookieRejectedForNonSameSiteness"_ns);
|
||||
break;
|
||||
|
||||
case RejectedForeignNoPartitionedError:
|
||||
COOKIE_LOGGING_WITH_NAME(CONSOLE_CHIPS_CATEGORY,
|
||||
"CookieForeignNoPartitionedError"_ns);
|
||||
break;
|
||||
|
||||
case RejectedByPermissionManager:
|
||||
COOKIE_LOGGING_WITH_NAME(CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedByPermissionManager"_ns);
|
||||
break;
|
||||
|
||||
case RejectedNonsecureOverSecure:
|
||||
COOKIE_LOGGING_WITH_NAME(CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedNonsecureOverSecure"_ns);
|
||||
break;
|
||||
}
|
||||
|
||||
#undef COOKIE_LOGGING_WITH_NAME
|
||||
|
||||
if (mRejection != NoRejection || !mContainsCookie) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const char* attribute : mWarnings.mAttributeOversize) {
|
||||
AutoTArray<nsString, 3> params = {NS_ConvertUTF8toUTF16(mCookieData.name()),
|
||||
NS_ConvertUTF8toUTF16(attribute)};
|
||||
|
||||
nsString size;
|
||||
size.AppendInt(ATTRIBUTE_MAX_LENGTH);
|
||||
params.AppendElement(size);
|
||||
|
||||
CookieLogging::LogMessageToConsole(
|
||||
mCRC, mHostURI, nsIScriptError::warningFlag, CONSOLE_OVERSIZE_CATEGORY,
|
||||
"CookieAttributeIgnored"_ns, params);
|
||||
}
|
||||
|
||||
for (const char* attribute : mWarnings.mAttributeOverwritten) {
|
||||
CookieLogging::LogMessageToConsole(
|
||||
mCRC, mHostURI, nsIScriptError::warningFlag, CONSOLE_OVERSIZE_CATEGORY,
|
||||
"CookieAttributeOverwritten"_ns,
|
||||
AutoTArray<nsString, 2>{NS_ConvertUTF8toUTF16(mCookieData.name()),
|
||||
NS_ConvertUTF8toUTF16(attribute)});
|
||||
}
|
||||
|
||||
if (mWarnings.mInvalidSameSiteAttribute) {
|
||||
CookieLogging::LogMessageToConsole(
|
||||
mCRC, mHostURI, nsIScriptError::infoFlag, CONSOLE_SAMESITE_CATEGORY,
|
||||
"CookieSameSiteValueInvalid2"_ns,
|
||||
AutoTArray<nsString, 1>{NS_ConvertUTF8toUTF16(mCookieData.name())});
|
||||
}
|
||||
|
||||
if (mWarnings.mSameSiteNoneRequiresSecureForBeta) {
|
||||
CookieLogging::LogMessageToConsole(
|
||||
mCRC, mHostURI, nsIScriptError::warningFlag, CONSOLE_SAMESITE_CATEGORY,
|
||||
"CookieRejectedNonRequiresSecureForBeta3"_ns,
|
||||
AutoTArray<nsString, 2>{NS_ConvertUTF8toUTF16(mCookieData.name()),
|
||||
SAMESITE_MDN_URL});
|
||||
}
|
||||
|
||||
if (mWarnings.mSameSiteLaxForced) {
|
||||
CookieLogging::LogMessageToConsole(
|
||||
mCRC, mHostURI, nsIScriptError::infoFlag, CONSOLE_SAMESITE_CATEGORY,
|
||||
"CookieLaxForced2"_ns,
|
||||
AutoTArray<nsString, 1>{NS_ConvertUTF8toUTF16(mCookieData.name())});
|
||||
}
|
||||
|
||||
if (mWarnings.mSameSiteLaxForcedForBeta) {
|
||||
CookieLogging::LogMessageToConsole(
|
||||
mCRC, mHostURI, nsIScriptError::warningFlag, CONSOLE_SAMESITE_CATEGORY,
|
||||
"CookieLaxForcedForBeta2"_ns,
|
||||
AutoTArray<nsString, 2>{NS_ConvertUTF8toUTF16(mCookieData.name()),
|
||||
SAMESITE_MDN_URL});
|
||||
}
|
||||
|
||||
if (mWarnings.mForeignNoPartitionedWarning) {
|
||||
CookieLogging::LogMessageToConsole(
|
||||
mCRC, mHostURI, nsIScriptError::warningFlag, CONSOLE_CHIPS_CATEGORY,
|
||||
"CookieForeignNoPartitionedWarning"_ns,
|
||||
AutoTArray<nsString, 1>{
|
||||
NS_ConvertUTF8toUTF16(mCookieData.name()),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
// The following comment block elucidates the function of ParseAttributes.
|
||||
/******************************************************************************
|
||||
|
@ -193,36 +375,25 @@ static inline void SetSameSiteAttributeDefault(CookieStruct& aCookieData) {
|
|||
aCookieData.rawSameSite() = nsICookie::SAMESITE_NONE;
|
||||
}
|
||||
|
||||
bool CheckAttributeSize(nsIConsoleReportCollector* aCRC, nsIURI* aHostURI,
|
||||
const CookieStruct& aCookieData, const char* aAttribute,
|
||||
const nsACString& aValue) {
|
||||
static uint16_t kMaxAttributeLength = 1024;
|
||||
|
||||
if (aValue.Length() > kMaxAttributeLength) {
|
||||
AutoTArray<nsString, 3> params = {NS_ConvertUTF8toUTF16(aCookieData.name()),
|
||||
NS_ConvertUTF8toUTF16(aAttribute)};
|
||||
|
||||
nsString size;
|
||||
size.AppendInt(kMaxAttributeLength);
|
||||
params.AppendElement(size);
|
||||
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::warningFlag, CONSOLE_OVERSIZE_CATEGORY,
|
||||
"CookieAttributeIgnored"_ns, params);
|
||||
|
||||
bool CookieParser::CheckAttributeSize(const nsACString& currentValue,
|
||||
const char* aAttribute,
|
||||
const nsACString& aValue) {
|
||||
if (aValue.Length() > ATTRIBUTE_MAX_LENGTH) {
|
||||
mWarnings.mAttributeOversize.AppendElement(aAttribute);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!currentValue.IsEmpty()) {
|
||||
mWarnings.mAttributeOverwritten.AppendElement(aAttribute);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Parses attributes from cookie header. expires/max-age attributes aren't
|
||||
// folded into the cookie struct here, because we don't know which one to use
|
||||
// until we've parsed the header.
|
||||
// static
|
||||
bool CookieParser::ParseAttributes(nsIConsoleReportCollector* aCRC,
|
||||
nsIURI* aHostURI, nsCString& aCookieHeader,
|
||||
CookieStruct& aCookieData,
|
||||
bool CookieParser::ParseAttributes(nsCString& aCookieHeader,
|
||||
nsACString& aExpires, nsACString& aMaxage,
|
||||
bool& aAcceptedByParser) {
|
||||
aAcceptedByParser = false;
|
||||
|
@ -244,10 +415,10 @@ bool CookieParser::ParseAttributes(nsIConsoleReportCollector* aCRC,
|
|||
nsACString::const_char_iterator cookieEnd;
|
||||
aCookieHeader.EndReading(cookieEnd);
|
||||
|
||||
aCookieData.isSecure() = false;
|
||||
aCookieData.isHttpOnly() = false;
|
||||
mCookieData.isSecure() = false;
|
||||
mCookieData.isHttpOnly() = false;
|
||||
|
||||
SetSameSiteAttributeDefault(aCookieData);
|
||||
SetSameSiteAttributeDefault(mCookieData);
|
||||
|
||||
nsDependentCSubstring tokenString(cookieStart, cookieStart);
|
||||
nsDependentCSubstring tokenValue(cookieStart, cookieStart);
|
||||
|
@ -262,10 +433,10 @@ bool CookieParser::ParseAttributes(nsIConsoleReportCollector* aCRC,
|
|||
newCookie = GetTokenValue(cookieStart, cookieEnd, tokenString, tokenValue,
|
||||
equalsFound);
|
||||
if (equalsFound) {
|
||||
aCookieData.name() = tokenString;
|
||||
aCookieData.value() = tokenValue;
|
||||
mCookieData.name() = tokenString;
|
||||
mCookieData.value() = tokenValue;
|
||||
} else {
|
||||
aCookieData.value() = tokenString;
|
||||
mCookieData.value() = tokenString;
|
||||
}
|
||||
|
||||
// extract remaining attributes
|
||||
|
@ -274,65 +445,55 @@ bool CookieParser::ParseAttributes(nsIConsoleReportCollector* aCRC,
|
|||
equalsFound);
|
||||
|
||||
if (ContainsControlChars(tokenString) || ContainsControlChars(tokenValue)) {
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::errorFlag, CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedInvalidCharAttributes"_ns,
|
||||
AutoTArray<nsString, 1>{NS_ConvertUTF8toUTF16(aCookieData.name())});
|
||||
RejectCookie(RejectedInvalidCharAttributes);
|
||||
return newCookie;
|
||||
}
|
||||
|
||||
// decide which attribute we have, and copy the string
|
||||
if (tokenString.LowerCaseEqualsLiteral(ATTRIBUTE_PATH)) {
|
||||
if (CheckAttributeSize(aCRC, aHostURI, aCookieData, ATTRIBUTE_PATH,
|
||||
tokenValue)) {
|
||||
aCookieData.path() = tokenValue;
|
||||
if (CheckAttributeSize(mCookieData.path(), ATTRIBUTE_PATH, tokenValue)) {
|
||||
mCookieData.path() = tokenValue;
|
||||
}
|
||||
|
||||
} else if (tokenString.LowerCaseEqualsLiteral(kDomain)) {
|
||||
if (CheckAttributeSize(aCRC, aHostURI, aCookieData, kDomain,
|
||||
tokenValue)) {
|
||||
aCookieData.host() = tokenValue;
|
||||
if (CheckAttributeSize(mCookieData.host(), kDomain, tokenValue)) {
|
||||
mCookieData.host() = tokenValue;
|
||||
}
|
||||
|
||||
} else if (tokenString.LowerCaseEqualsLiteral(kExpires)) {
|
||||
if (CheckAttributeSize(aCRC, aHostURI, aCookieData, kExpires,
|
||||
tokenValue)) {
|
||||
if (CheckAttributeSize(aExpires, kExpires, tokenValue)) {
|
||||
aExpires = tokenValue;
|
||||
}
|
||||
|
||||
} else if (tokenString.LowerCaseEqualsLiteral(kMaxage)) {
|
||||
if (CheckAttributeSize(aCRC, aHostURI, aCookieData, kMaxage,
|
||||
tokenValue)) {
|
||||
if (CheckAttributeSize(aMaxage, kMaxage, tokenValue)) {
|
||||
aMaxage = tokenValue;
|
||||
}
|
||||
|
||||
// ignore any tokenValue for isSecure; just set the boolean
|
||||
} else if (tokenString.LowerCaseEqualsLiteral(kSecure)) {
|
||||
aCookieData.isSecure() = true;
|
||||
mCookieData.isSecure() = true;
|
||||
|
||||
// ignore any tokenValue for isPartitioned; just set the boolean
|
||||
} else if (tokenString.LowerCaseEqualsLiteral(kPartitioned)) {
|
||||
aCookieData.isPartitioned() = true;
|
||||
mCookieData.isPartitioned() = true;
|
||||
|
||||
// ignore any tokenValue for isHttpOnly (see bug 178993);
|
||||
// just set the boolean
|
||||
} else if (tokenString.LowerCaseEqualsLiteral(kHttpOnly)) {
|
||||
aCookieData.isHttpOnly() = true;
|
||||
mCookieData.isHttpOnly() = true;
|
||||
|
||||
} else if (tokenString.LowerCaseEqualsLiteral(kSameSite)) {
|
||||
if (tokenValue.LowerCaseEqualsLiteral(kSameSiteLax)) {
|
||||
SetSameSiteAttribute(aCookieData, nsICookie::SAMESITE_LAX);
|
||||
SetSameSiteAttribute(mCookieData, nsICookie::SAMESITE_LAX);
|
||||
} else if (tokenValue.LowerCaseEqualsLiteral(kSameSiteStrict)) {
|
||||
SetSameSiteAttribute(aCookieData, nsICookie::SAMESITE_STRICT);
|
||||
SetSameSiteAttribute(mCookieData, nsICookie::SAMESITE_STRICT);
|
||||
} else if (tokenValue.LowerCaseEqualsLiteral(kSameSiteNone)) {
|
||||
SetSameSiteAttribute(aCookieData, nsICookie::SAMESITE_NONE);
|
||||
SetSameSiteAttribute(mCookieData, nsICookie::SAMESITE_NONE);
|
||||
} else {
|
||||
// Reset to Default if unknown token value (see Bug 1682450)
|
||||
SetSameSiteAttributeDefault(aCookieData);
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::infoFlag, CONSOLE_SAMESITE_CATEGORY,
|
||||
"CookieSameSiteValueInvalid2"_ns,
|
||||
AutoTArray<nsString, 1>{NS_ConvertUTF8toUTF16(aCookieData.name())});
|
||||
SetSameSiteAttributeDefault(mCookieData);
|
||||
mWarnings.mInvalidSameSiteAttribute = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -342,60 +503,42 @@ bool CookieParser::ParseAttributes(nsIConsoleReportCollector* aCRC,
|
|||
|
||||
// If same-site is explicitly set to 'none' but this is not a secure context,
|
||||
// let's abort the parsing.
|
||||
if (!aCookieData.isSecure() &&
|
||||
aCookieData.sameSite() == nsICookie::SAMESITE_NONE) {
|
||||
if (!mCookieData.isSecure() &&
|
||||
mCookieData.sameSite() == nsICookie::SAMESITE_NONE) {
|
||||
if (StaticPrefs::network_cookie_sameSite_noneRequiresSecure()) {
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::errorFlag, CONSOLE_SAMESITE_CATEGORY,
|
||||
"CookieRejectedNonRequiresSecure2"_ns,
|
||||
AutoTArray<nsString, 1>{NS_ConvertUTF8toUTF16(aCookieData.name())});
|
||||
RejectCookie(RejectedNoneRequiresSecure);
|
||||
return newCookie;
|
||||
}
|
||||
|
||||
// Still warn about the missing Secure attribute when not enforcing.
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::warningFlag, CONSOLE_SAMESITE_CATEGORY,
|
||||
"CookieRejectedNonRequiresSecureForBeta3"_ns,
|
||||
AutoTArray<nsString, 2>{NS_ConvertUTF8toUTF16(aCookieData.name()),
|
||||
SAMESITE_MDN_URL});
|
||||
mWarnings.mSameSiteNoneRequiresSecureForBeta = true;
|
||||
}
|
||||
|
||||
// Ensure the partitioned cookie is set with the secure attribute if CHIPS
|
||||
// is enabled.
|
||||
if (StaticPrefs::network_cookie_CHIPS_enabled() &&
|
||||
aCookieData.isPartitioned() && !aCookieData.isSecure()) {
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::errorFlag, CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedPartitionedRequiresSecure"_ns,
|
||||
AutoTArray<nsString, 1>{NS_ConvertUTF8toUTF16(aCookieData.name())});
|
||||
|
||||
mCookieData.isPartitioned() && !mCookieData.isSecure()) {
|
||||
RejectCookie(RejectedPartitionedRequiresSecure);
|
||||
return newCookie;
|
||||
}
|
||||
|
||||
if (aCookieData.rawSameSite() == nsICookie::SAMESITE_NONE &&
|
||||
aCookieData.sameSite() == nsICookie::SAMESITE_LAX) {
|
||||
if (mCookieData.rawSameSite() == nsICookie::SAMESITE_NONE &&
|
||||
mCookieData.sameSite() == nsICookie::SAMESITE_LAX) {
|
||||
bool laxByDefault =
|
||||
StaticPrefs::network_cookie_sameSite_laxByDefault() &&
|
||||
!nsContentUtils::IsURIInPrefList(
|
||||
aHostURI, "network.cookie.sameSite.laxByDefault.disabledHosts");
|
||||
mHostURI, "network.cookie.sameSite.laxByDefault.disabledHosts");
|
||||
if (laxByDefault) {
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::infoFlag, CONSOLE_SAMESITE_CATEGORY,
|
||||
"CookieLaxForced2"_ns,
|
||||
AutoTArray<nsString, 1>{NS_ConvertUTF8toUTF16(aCookieData.name())});
|
||||
mWarnings.mSameSiteLaxForced = true;
|
||||
} else {
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::warningFlag,
|
||||
CONSOLE_SAMESITE_CATEGORY, "CookieLaxForcedForBeta2"_ns,
|
||||
AutoTArray<nsString, 2>{NS_ConvertUTF8toUTF16(aCookieData.name()),
|
||||
SAMESITE_MDN_URL});
|
||||
mWarnings.mSameSiteLaxForcedForBeta = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Cookie accepted.
|
||||
aAcceptedByParser = true;
|
||||
|
||||
MOZ_ASSERT(Cookie::ValidateSameSite(aCookieData));
|
||||
MOZ_ASSERT(Cookie::ValidateSameSite(mCookieData));
|
||||
return newCookie;
|
||||
}
|
||||
|
||||
|
@ -432,20 +575,18 @@ nsAutoCString GetPathFromURI(nsIURI* aHostURI) {
|
|||
|
||||
} // namespace
|
||||
|
||||
bool CookieParser::CheckPath(CookieStruct& aCookieData,
|
||||
nsIConsoleReportCollector* aCRC,
|
||||
nsIURI* aHostURI) {
|
||||
bool CookieParser::CheckPath() {
|
||||
// if a path is given, check the host has permission
|
||||
if (aCookieData.path().IsEmpty() || aCookieData.path().First() != '/') {
|
||||
nsAutoCString path = GetPathFromURI(aHostURI);
|
||||
if (CheckAttributeSize(aCRC, aHostURI, aCookieData, ATTRIBUTE_PATH, path)) {
|
||||
aCookieData.path() = path;
|
||||
if (mCookieData.path().IsEmpty() || mCookieData.path().First() != '/') {
|
||||
nsAutoCString path = GetPathFromURI(mHostURI);
|
||||
if (CheckAttributeSize(mCookieData.path(), ATTRIBUTE_PATH, path)) {
|
||||
mCookieData.path() = path;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(CookieCommons::CheckPathSize(aCookieData));
|
||||
MOZ_ASSERT(CookieCommons::CheckPathSize(mCookieData));
|
||||
|
||||
return !aCookieData.path().Contains('\t');
|
||||
return !mCookieData.path().Contains('\t');
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -655,20 +796,16 @@ static void RecordPartitionedTelemetry(const CookieStruct& aCookieData,
|
|||
|
||||
// processes a single cookie, and returns true if there are more cookies
|
||||
// to be processed
|
||||
bool CookieParser::CanSetCookie(
|
||||
nsIURI* aHostURI, const nsACString& aBaseDomain, CookieStruct& aCookieData,
|
||||
bool aRequireHostMatch, CookieStatus aStatus, nsCString& aCookieHeader,
|
||||
bool aFromHttp, bool aIsForeignAndNotAddon, bool aPartitionedOnly,
|
||||
bool aIsInPrivateBrowsing, nsIConsoleReportCollector* aCRC,
|
||||
bool& aSetCookie) {
|
||||
MOZ_ASSERT(aHostURI);
|
||||
|
||||
aSetCookie = false;
|
||||
bool CookieParser::Parse(const nsACString& aBaseDomain, bool aRequireHostMatch,
|
||||
CookieStatus aStatus, nsCString& aCookieHeader,
|
||||
bool aFromHttp, bool aIsForeignAndNotAddon,
|
||||
bool aPartitionedOnly, bool aIsInPrivateBrowsing) {
|
||||
MOZ_ASSERT(!mContainsCookie);
|
||||
|
||||
// init expiryTime such that session cookies won't prematurely expire
|
||||
aCookieData.expiry() = INT64_MAX;
|
||||
mCookieData.expiry() = INT64_MAX;
|
||||
|
||||
aCookieData.schemeMap() = CookieCommons::URIToSchemeType(aHostURI);
|
||||
mCookieData.schemeMap() = CookieCommons::URIToSchemeType(mHostURI);
|
||||
|
||||
// aCookieHeader is an in/out param to point to the next cookie, if
|
||||
// there is one. Save the present value for logging purposes
|
||||
|
@ -679,8 +816,8 @@ bool CookieParser::CanSetCookie(
|
|||
nsAutoCString expires;
|
||||
nsAutoCString maxage;
|
||||
bool acceptedByParser = false;
|
||||
bool newCookie = ParseAttributes(aCRC, aHostURI, aCookieHeader, aCookieData,
|
||||
expires, maxage, acceptedByParser);
|
||||
bool newCookie =
|
||||
ParseAttributes(aCookieHeader, expires, maxage, acceptedByParser);
|
||||
if (!acceptedByParser) {
|
||||
return newCookie;
|
||||
}
|
||||
|
@ -693,153 +830,106 @@ bool CookieParser::CanSetCookie(
|
|||
// 2 = secure and "http:"
|
||||
// 3 = secure and "https:"
|
||||
bool potentiallyTrustworthy =
|
||||
nsMixedContentBlocker::IsPotentiallyTrustworthyOrigin(aHostURI);
|
||||
nsMixedContentBlocker::IsPotentiallyTrustworthyOrigin(mHostURI);
|
||||
|
||||
int64_t currentTimeInUsec = PR_Now();
|
||||
|
||||
// calculate expiry time of cookie.
|
||||
aCookieData.isSession() =
|
||||
GetExpiry(aCookieData, expires, maxage,
|
||||
mCookieData.isSession() =
|
||||
GetExpiry(mCookieData, expires, maxage,
|
||||
currentTimeInUsec / PR_USEC_PER_SEC, aFromHttp);
|
||||
if (aStatus == STATUS_ACCEPT_SESSION) {
|
||||
// force lifetime to session. note that the expiration time, if set above,
|
||||
// will still apply.
|
||||
aCookieData.isSession() = true;
|
||||
mCookieData.isSession() = true;
|
||||
}
|
||||
|
||||
// reject cookie if name and value are empty, per RFC6265bis
|
||||
if (aCookieData.name().IsEmpty() && aCookieData.value().IsEmpty()) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader,
|
||||
if (mCookieData.name().IsEmpty() && mCookieData.value().IsEmpty()) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, mHostURI, savedCookieHeader,
|
||||
"cookie name and value are empty");
|
||||
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::warningFlag, CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedEmptyNameAndValue"_ns, nsTArray<nsString>());
|
||||
RejectCookie(RejectedEmptyNameAndValue);
|
||||
return newCookie;
|
||||
}
|
||||
|
||||
// reject cookie if it's over the size limit, per RFC2109
|
||||
if (!CookieCommons::CheckNameAndValueSize(aCookieData)) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader,
|
||||
if (!CookieCommons::CheckNameAndValueSize(mCookieData)) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, mHostURI, savedCookieHeader,
|
||||
"cookie too big (> 4kb)");
|
||||
|
||||
AutoTArray<nsString, 2> params = {
|
||||
NS_ConvertUTF8toUTF16(aCookieData.name())};
|
||||
|
||||
nsString size;
|
||||
size.AppendInt(kMaxBytesPerCookie);
|
||||
params.AppendElement(size);
|
||||
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::warningFlag, CONSOLE_OVERSIZE_CATEGORY,
|
||||
"CookieOversize"_ns, params);
|
||||
RejectCookie(RejectedNameValueOversize);
|
||||
return newCookie;
|
||||
}
|
||||
|
||||
CookieCommons::RecordUnicodeTelemetry(aCookieData);
|
||||
CookieCommons::RecordUnicodeTelemetry(mCookieData);
|
||||
|
||||
// We count SetCookie operations in the parent process only for HTTP set
|
||||
// cookies to prevent double counting.
|
||||
if (XRE_IsParentProcess() || !aFromHttp) {
|
||||
RecordPartitionedTelemetry(aCookieData, aIsForeignAndNotAddon);
|
||||
RecordPartitionedTelemetry(mCookieData, aIsForeignAndNotAddon);
|
||||
}
|
||||
|
||||
if (!CookieCommons::CheckName(aCookieData)) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader,
|
||||
if (!CookieCommons::CheckName(mCookieData)) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, mHostURI, savedCookieHeader,
|
||||
"invalid name character");
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::warningFlag, CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedInvalidCharName"_ns,
|
||||
AutoTArray<nsString, 1>{
|
||||
NS_ConvertUTF8toUTF16(aCookieData.name()),
|
||||
});
|
||||
RejectCookie(RejectedInvalidCharName);
|
||||
return newCookie;
|
||||
}
|
||||
|
||||
// domain & path checks
|
||||
if (!CheckDomain(aCookieData, aHostURI, aBaseDomain, aRequireHostMatch)) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader,
|
||||
if (!CheckDomain(mCookieData, mHostURI, aBaseDomain, aRequireHostMatch)) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, mHostURI, savedCookieHeader,
|
||||
"failed the domain tests");
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::warningFlag, CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedInvalidDomain"_ns,
|
||||
AutoTArray<nsString, 1>{
|
||||
NS_ConvertUTF8toUTF16(aCookieData.name()),
|
||||
});
|
||||
RejectCookie(RejectedInvalidDomain);
|
||||
return newCookie;
|
||||
}
|
||||
|
||||
if (!CheckPath(aCookieData, aCRC, aHostURI)) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader,
|
||||
if (!CheckPath()) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, mHostURI, savedCookieHeader,
|
||||
"failed the path tests");
|
||||
return newCookie;
|
||||
}
|
||||
|
||||
// If a cookie is nameless, then its value must not start with
|
||||
// `__Host-` or `__Secure-`
|
||||
if (aCookieData.name().IsEmpty() && (HasSecurePrefix(aCookieData.value()) ||
|
||||
HasHostPrefix(aCookieData.value()))) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader,
|
||||
if (mCookieData.name().IsEmpty() && (HasSecurePrefix(mCookieData.value()) ||
|
||||
HasHostPrefix(mCookieData.value()))) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, mHostURI, savedCookieHeader,
|
||||
"failed hidden prefix tests");
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::warningFlag, CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedInvalidPrefix"_ns,
|
||||
AutoTArray<nsString, 1>{
|
||||
NS_ConvertUTF8toUTF16(aCookieData.name()),
|
||||
});
|
||||
RejectCookie(RejectedInvalidPrefix);
|
||||
return newCookie;
|
||||
}
|
||||
|
||||
// magic prefix checks. MUST be run after CheckDomain() and CheckPath()
|
||||
if (!CheckPrefixes(aCookieData, potentiallyTrustworthy)) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader,
|
||||
if (!CheckPrefixes(mCookieData, potentiallyTrustworthy)) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, mHostURI, savedCookieHeader,
|
||||
"failed the prefix tests");
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::warningFlag, CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedInvalidPrefix"_ns,
|
||||
AutoTArray<nsString, 1>{
|
||||
NS_ConvertUTF8toUTF16(aCookieData.name()),
|
||||
});
|
||||
RejectCookie(RejectedInvalidPrefix);
|
||||
return newCookie;
|
||||
}
|
||||
|
||||
if (!CookieCommons::CheckValue(aCookieData)) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader,
|
||||
if (!CookieCommons::CheckValue(mCookieData)) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, mHostURI, savedCookieHeader,
|
||||
"invalid value character");
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::warningFlag, CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedInvalidCharValue"_ns,
|
||||
AutoTArray<nsString, 1>{
|
||||
NS_ConvertUTF8toUTF16(aCookieData.name()),
|
||||
});
|
||||
RejectCookie(RejectedInvalidCharValue);
|
||||
return newCookie;
|
||||
}
|
||||
|
||||
// if the new cookie is httponly, make sure we're not coming from script
|
||||
if (!aFromHttp && aCookieData.isHttpOnly()) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader,
|
||||
if (!aFromHttp && mCookieData.isHttpOnly()) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, mHostURI, savedCookieHeader,
|
||||
"cookie is httponly; coming from script");
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::warningFlag, CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedHttpOnlyButFromScript"_ns,
|
||||
AutoTArray<nsString, 1>{
|
||||
NS_ConvertUTF8toUTF16(aCookieData.name()),
|
||||
});
|
||||
RejectCookie(RejectedHttpOnlyButFromScript);
|
||||
return newCookie;
|
||||
}
|
||||
|
||||
// If the new cookie is non-https and wants to set secure flag,
|
||||
// browser have to ignore this new cookie.
|
||||
// (draft-ietf-httpbis-cookie-alone section 3.1)
|
||||
if (aCookieData.isSecure() && !potentiallyTrustworthy) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader,
|
||||
if (mCookieData.isSecure() && !potentiallyTrustworthy) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, mHostURI, aCookieHeader,
|
||||
"non-https cookie can't set secure flag");
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::warningFlag, CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedSecureButNonHttps"_ns,
|
||||
AutoTArray<nsString, 1>{
|
||||
NS_ConvertUTF8toUTF16(aCookieData.name()),
|
||||
});
|
||||
RejectCookie(RejectedSecureButNonHttps);
|
||||
return newCookie;
|
||||
}
|
||||
|
||||
|
@ -848,20 +938,14 @@ bool CookieParser::CanSetCookie(
|
|||
bool laxByDefault =
|
||||
StaticPrefs::network_cookie_sameSite_laxByDefault() &&
|
||||
!nsContentUtils::IsURIInPrefList(
|
||||
aHostURI, "network.cookie.sameSite.laxByDefault.disabledHosts");
|
||||
mHostURI, "network.cookie.sameSite.laxByDefault.disabledHosts");
|
||||
auto effectiveSameSite =
|
||||
laxByDefault ? aCookieData.sameSite() : aCookieData.rawSameSite();
|
||||
laxByDefault ? mCookieData.sameSite() : mCookieData.rawSameSite();
|
||||
if ((effectiveSameSite != nsICookie::SAMESITE_NONE) &&
|
||||
aIsForeignAndNotAddon) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader,
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, mHostURI, savedCookieHeader,
|
||||
"failed the samesite tests");
|
||||
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::warningFlag, CONSOLE_SAMESITE_CATEGORY,
|
||||
"CookieRejectedForNonSameSiteness"_ns,
|
||||
AutoTArray<nsString, 1>{
|
||||
NS_ConvertUTF8toUTF16(aCookieData.name()),
|
||||
});
|
||||
RejectCookie(RejectedForNonSameSiteness);
|
||||
return newCookie;
|
||||
}
|
||||
|
||||
|
@ -869,33 +953,29 @@ bool CookieParser::CanSetCookie(
|
|||
// but is foreign we should give the developer a message.
|
||||
// If CHIPS isn't required yet, we will warn the console
|
||||
// that we have upcoming changes. Otherwise we give a rejection message.
|
||||
if (aPartitionedOnly && !aCookieData.isPartitioned() &&
|
||||
if (aPartitionedOnly && !mCookieData.isPartitioned() &&
|
||||
aIsForeignAndNotAddon) {
|
||||
if (StaticPrefs::network_cookie_cookieBehavior_optInPartitioning() ||
|
||||
(aIsInPrivateBrowsing &&
|
||||
StaticPrefs::
|
||||
network_cookie_cookieBehavior_optInPartitioning_pbmode())) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader,
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, mHostURI, savedCookieHeader,
|
||||
"foreign cookies must be partitioned");
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::warningFlag, CONSOLE_CHIPS_CATEGORY,
|
||||
"CookieForeignNoPartitionedError"_ns,
|
||||
AutoTArray<nsString, 1>{
|
||||
NS_ConvertUTF8toUTF16(aCookieData.name()),
|
||||
});
|
||||
RejectCookie(RejectedForeignNoPartitionedError);
|
||||
return newCookie;
|
||||
}
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::warningFlag, CONSOLE_CHIPS_CATEGORY,
|
||||
"CookieForeignNoPartitionedWarning"_ns,
|
||||
AutoTArray<nsString, 1>{
|
||||
NS_ConvertUTF8toUTF16(aCookieData.name()),
|
||||
});
|
||||
mWarnings.mForeignNoPartitionedWarning = true;
|
||||
}
|
||||
|
||||
aSetCookie = true;
|
||||
mContainsCookie = true;
|
||||
return newCookie;
|
||||
}
|
||||
|
||||
void CookieParser::RejectCookie(Rejection aRejection) {
|
||||
MOZ_ASSERT(mRejection == NoRejection);
|
||||
MOZ_ASSERT(aRejection != NoRejection);
|
||||
mRejection = aRejection;
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -6,7 +6,11 @@
|
|||
#ifndef mozilla_net_CookieParser_h
|
||||
#define mozilla_net_CookieParser_h
|
||||
|
||||
#include <nsCOMPtr.h>
|
||||
#include "CookieCommons.h"
|
||||
|
||||
#include "mozilla/net/NeckoChannelParams.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsIConsoleReportCollector;
|
||||
class nsIURI;
|
||||
|
@ -16,12 +20,48 @@ namespace net {
|
|||
|
||||
class CookieParser final {
|
||||
public:
|
||||
static bool CanSetCookie(nsIURI* aHostURI, const nsACString& aBaseDomain,
|
||||
CookieStruct& aCookieData, bool aRequireHostMatch,
|
||||
CookieStatus aStatus, nsCString& aCookieHeader,
|
||||
bool aFromHttp, bool aIsForeignAndNotAddon,
|
||||
bool aPartitionedOnly, bool aIsInPrivateBrowsing,
|
||||
nsIConsoleReportCollector* aCRC, bool& aSetCookie);
|
||||
enum Rejection {
|
||||
// The cookie is OK or not parsed yet.
|
||||
NoRejection,
|
||||
|
||||
RejectedInvalidCharAttributes,
|
||||
RejectedNoneRequiresSecure,
|
||||
RejectedPartitionedRequiresSecure,
|
||||
RejectedEmptyNameAndValue,
|
||||
RejectedNameValueOversize,
|
||||
RejectedInvalidCharName,
|
||||
RejectedInvalidDomain,
|
||||
RejectedInvalidPrefix,
|
||||
RejectedInvalidCharValue,
|
||||
RejectedHttpOnlyButFromScript,
|
||||
RejectedSecureButNonHttps,
|
||||
RejectedForNonSameSiteness,
|
||||
RejectedForeignNoPartitionedError,
|
||||
RejectedByPermissionManager,
|
||||
RejectedNonsecureOverSecure,
|
||||
};
|
||||
|
||||
CookieParser(nsIConsoleReportCollector* aCRC, nsIURI* aHostURI);
|
||||
~CookieParser();
|
||||
|
||||
nsIURI* HostURI() const { return mHostURI; }
|
||||
|
||||
bool Parse(const nsACString& aBaseDomain, bool aRequireHostMatch,
|
||||
CookieStatus aStatus, nsCString& aCookieHeader, bool aFromHttp,
|
||||
bool aIsForeignAndNotAddon, bool aPartitionedOnly,
|
||||
bool aIsInPrivateBrowsing);
|
||||
|
||||
bool ContainsCookie() const {
|
||||
MOZ_ASSERT_IF(mContainsCookie, mRejection == NoRejection);
|
||||
return mContainsCookie;
|
||||
}
|
||||
|
||||
void RejectCookie(Rejection aRejection);
|
||||
|
||||
CookieStruct& CookieData() {
|
||||
MOZ_ASSERT(ContainsCookie());
|
||||
return mCookieData;
|
||||
}
|
||||
|
||||
private:
|
||||
static bool GetTokenValue(nsACString::const_char_iterator& aIter,
|
||||
|
@ -30,23 +70,44 @@ class CookieParser final {
|
|||
nsDependentCSubstring& aTokenValue,
|
||||
bool& aEqualsFound);
|
||||
|
||||
static bool ParseAttributes(nsIConsoleReportCollector* aCRC, nsIURI* aHostURI,
|
||||
nsCString& aCookieHeader,
|
||||
CookieStruct& aCookieData, nsACString& aExpires,
|
||||
nsACString& aMaxage, bool& aAcceptedByParser);
|
||||
bool ParseAttributes(nsCString& aCookieHeader, nsACString& aExpires,
|
||||
nsACString& aMaxage, bool& aAcceptedByParser);
|
||||
|
||||
static bool GetExpiry(CookieStruct& aCookieData, const nsACString& aExpires,
|
||||
const nsACString& aMaxage, int64_t aCurrentTime,
|
||||
bool aFromHttp);
|
||||
|
||||
static bool CheckPath(CookieStruct& aCookieData,
|
||||
nsIConsoleReportCollector* aCRC, nsIURI* aHostURI);
|
||||
bool CheckPath();
|
||||
bool CheckAttributeSize(const nsACString& currentValue,
|
||||
const char* aAttribute, const nsACString& aValue);
|
||||
|
||||
static bool CheckPrefixes(CookieStruct& aCookieData, bool aSecureRequest);
|
||||
static bool CheckDomain(CookieStruct& aCookieData, nsIURI* aHostURI,
|
||||
const nsACString& aBaseDomain,
|
||||
bool aRequireHostMatch);
|
||||
static bool HasSecurePrefix(const nsACString& aString);
|
||||
static bool HasHostPrefix(const nsACString& aString);
|
||||
|
||||
nsCOMPtr<nsIConsoleReportCollector> mCRC;
|
||||
nsCOMPtr<nsIURI> mHostURI;
|
||||
|
||||
// True if the parsing succeeded.
|
||||
bool mContainsCookie = false;
|
||||
|
||||
Rejection mRejection = NoRejection;
|
||||
|
||||
struct Warnings {
|
||||
nsTArray<const char*> mAttributeOversize;
|
||||
nsTArray<const char*> mAttributeOverwritten;
|
||||
|
||||
bool mInvalidSameSiteAttribute = false;
|
||||
bool mSameSiteNoneRequiresSecureForBeta = false;
|
||||
bool mSameSiteLaxForced = false;
|
||||
bool mSameSiteLaxForcedForBeta = false;
|
||||
bool mForeignNoPartitionedWarning = false;
|
||||
} mWarnings;
|
||||
|
||||
CookieStruct mCookieData;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -6,15 +6,16 @@
|
|||
|
||||
#include "CookieCommons.h"
|
||||
#include "CookieLogging.h"
|
||||
#include "CookieParser.h"
|
||||
#include "mozilla/AppShutdown.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/Components.h"
|
||||
#include "mozilla/ConsoleReportCollector.h"
|
||||
#include "mozilla/ContentBlockingNotifier.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/nsMixedContentBlocker.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/glean/GleanMetrics.h"
|
||||
#include "mozilla/net/CookieJarSettings.h"
|
||||
#include "mozilla/net/CookiePersistentStorage.h"
|
||||
#include "mozilla/net/CookiePrivateStorage.h"
|
||||
|
@ -632,9 +633,24 @@ CookieService::SetCookieStringFromDocument(Document* aDocument,
|
|||
aAttrs.mPrivateBrowsingId);
|
||||
};
|
||||
|
||||
auto* basePrincipal = BasePrincipal::Cast(aDocument->NodePrincipal());
|
||||
basePrincipal->GetURI(getter_AddRefs(documentURI));
|
||||
if (NS_WARN_IF(!documentURI)) {
|
||||
// Document's principal is not a content or null (may be system), so
|
||||
// can't set cookies
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Console report takes care of the correct reporting at the exit of this
|
||||
// method.
|
||||
RefPtr<ConsoleReportCollector> crc = new ConsoleReportCollector();
|
||||
auto scopeExit = MakeScopeExit([&] { crc->FlushConsoleReports(aDocument); });
|
||||
|
||||
CookieParser cookieParser(crc, documentURI);
|
||||
|
||||
RefPtr<Cookie> cookie = CookieCommons::CreateCookieFromDocument(
|
||||
aDocument, aCookieString, currentTimeInUsec, mTLDService, mThirdPartyUtil,
|
||||
hasExistingCookiesLambda, getter_AddRefs(documentURI), baseDomain, attrs);
|
||||
cookieParser, aDocument, aCookieString, currentTimeInUsec, mTLDService,
|
||||
mThirdPartyUtil, hasExistingCookiesLambda, baseDomain, attrs);
|
||||
if (!cookie) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -657,12 +673,9 @@ CookieService::SetCookieStringFromDocument(Document* aDocument,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIConsoleReportCollector> crc =
|
||||
do_QueryInterface(aDocument->GetChannel());
|
||||
|
||||
// add the cookie to the list. AddCookie() takes care of logging.
|
||||
PickStorage(attrs)->AddCookie(
|
||||
crc, baseDomain, attrs, cookie, currentTimeInUsec, documentURI,
|
||||
&cookieParser, baseDomain, attrs, cookie, currentTimeInUsec, documentURI,
|
||||
aCookieString, false, thirdParty, aDocument->GetBrowsingContext());
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -808,33 +821,27 @@ CookieService::SetCookieStringFromHttp(nsIURI* aHostURI,
|
|||
// process each cookie in the header
|
||||
bool moreCookieToRead = true;
|
||||
while (moreCookieToRead) {
|
||||
CookieStruct cookieData;
|
||||
bool canSetCookie = false;
|
||||
CookieParser cookieParser(crc, aHostURI);
|
||||
|
||||
moreCookieToRead = CookieParser::CanSetCookie(
|
||||
aHostURI, baseDomain, cookieData, requireHostMatch, cookieStatus,
|
||||
cookieHeader, true, isForeignAndNotAddon, mustBePartitioned,
|
||||
storagePrincipalOriginAttributes.IsPrivateBrowsing(), crc,
|
||||
canSetCookie);
|
||||
moreCookieToRead = cookieParser.Parse(
|
||||
baseDomain, requireHostMatch, cookieStatus, cookieHeader, true,
|
||||
isForeignAndNotAddon, mustBePartitioned,
|
||||
storagePrincipalOriginAttributes.IsPrivateBrowsing());
|
||||
|
||||
if (!canSetCookie) {
|
||||
if (!cookieParser.ContainsCookie()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check permissions from site permission list.
|
||||
if (!CookieCommons::CheckCookiePermission(aChannel, cookieData)) {
|
||||
if (!CookieCommons::CheckCookiePermission(aChannel,
|
||||
cookieParser.CookieData())) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader,
|
||||
"cookie rejected by permission manager");
|
||||
CookieCommons::NotifyRejected(
|
||||
aHostURI, aChannel,
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION,
|
||||
OPERATION_WRITE);
|
||||
CookieLogging::LogMessageToConsole(
|
||||
crc, aHostURI, nsIScriptError::warningFlag,
|
||||
CONSOLE_REJECTION_CATEGORY, "CookieRejectedByPermissionManager"_ns,
|
||||
AutoTArray<nsString, 1>{
|
||||
NS_ConvertUTF8toUTF16(cookieData.name()),
|
||||
});
|
||||
cookieParser.RejectCookie(CookieParser::RejectedByPermissionManager);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -842,8 +849,9 @@ CookieService::SetCookieStringFromHttp(nsIURI* aHostURI,
|
|||
// cookie jar independent of context. If the cookies are stored in the
|
||||
// partitioned cookie jar anyway no special treatment of CHIPS cookies
|
||||
// necessary.
|
||||
bool needPartitioned =
|
||||
isCHIPS && cookieData.isPartitioned() && !isPartitionedPrincipal;
|
||||
bool needPartitioned = isCHIPS &&
|
||||
cookieParser.CookieData().isPartitioned() &&
|
||||
!isPartitionedPrincipal;
|
||||
OriginAttributes& cookieOriginAttributes =
|
||||
needPartitioned ? partitionedPrincipalOriginAttributes
|
||||
: storagePrincipalOriginAttributes;
|
||||
|
@ -853,7 +861,8 @@ CookieService::SetCookieStringFromHttp(nsIURI* aHostURI,
|
|||
!partitionedPrincipalOriginAttributes.mPartitionKey.IsEmpty());
|
||||
|
||||
// create a new Cookie
|
||||
RefPtr<Cookie> cookie = Cookie::Create(cookieData, cookieOriginAttributes);
|
||||
RefPtr<Cookie> cookie =
|
||||
Cookie::Create(cookieParser.CookieData(), cookieOriginAttributes);
|
||||
MOZ_ASSERT(cookie);
|
||||
|
||||
int64_t currentTimeInUsec = PR_Now();
|
||||
|
@ -865,8 +874,8 @@ CookieService::SetCookieStringFromHttp(nsIURI* aHostURI,
|
|||
RefPtr<BrowsingContext> bc = loadInfo->GetTargetBrowsingContext();
|
||||
|
||||
// add the cookie to the list. AddCookie() takes care of logging.
|
||||
storage->AddCookie(crc, baseDomain, cookieOriginAttributes, cookie,
|
||||
currentTimeInUsec, aHostURI, aCookieHeader, true,
|
||||
storage->AddCookie(&cookieParser, baseDomain, cookieOriginAttributes,
|
||||
cookie, currentTimeInUsec, aHostURI, aCookieHeader, true,
|
||||
isForeignAndNotAddon, bc);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "mozilla/LoadInfo.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/ConsoleReportCollector.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/ipc/URIUtils.h"
|
||||
|
@ -34,7 +35,6 @@
|
|||
#include "nsIWebProgressListener.h"
|
||||
#include "nsQueryObject.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "ThirdPartyUtil.h"
|
||||
#include "nsIConsoleReportCollector.h"
|
||||
|
@ -501,9 +501,24 @@ CookieServiceChild::SetCookieStringFromDocument(
|
|||
return !!CountCookiesFromHashTable(aBaseDomain, aAttrs);
|
||||
};
|
||||
|
||||
auto* basePrincipal = BasePrincipal::Cast(aDocument->NodePrincipal());
|
||||
basePrincipal->GetURI(getter_AddRefs(documentURI));
|
||||
if (NS_WARN_IF(!documentURI)) {
|
||||
// Document's principal is not a content or null (may be system), so
|
||||
// can't set cookies
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Console report takes care of the correct reporting at the exit of this
|
||||
// method.
|
||||
RefPtr<ConsoleReportCollector> crc = new ConsoleReportCollector();
|
||||
auto scopeExit = MakeScopeExit([&] { crc->FlushConsoleReports(aDocument); });
|
||||
|
||||
CookieParser cookieParser(crc, documentURI);
|
||||
|
||||
RefPtr<Cookie> cookie = CookieCommons::CreateCookieFromDocument(
|
||||
aDocument, aCookieString, PR_Now(), mTLDService, mThirdPartyUtil,
|
||||
hasExistingCookiesLambda, getter_AddRefs(documentURI), baseDomain, attrs);
|
||||
cookieParser, aDocument, aCookieString, PR_Now(), mTLDService,
|
||||
mThirdPartyUtil, hasExistingCookiesLambda, baseDomain, attrs);
|
||||
if (!cookie) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -696,28 +711,20 @@ CookieServiceChild::SetCookieStringFromHttp(nsIURI* aHostURI,
|
|||
nsTArray<CookieStruct> cookiesToSend, partitionedCookiesToSend;
|
||||
bool moreCookies;
|
||||
do {
|
||||
CookieStruct cookieData;
|
||||
bool canSetCookie = false;
|
||||
moreCookies = CookieParser::CanSetCookie(
|
||||
aHostURI, baseDomain, cookieData, requireHostMatch, cookieStatus,
|
||||
cookieString, true, isForeignAndNotAddon, mustBePartitioned,
|
||||
storagePrincipalOriginAttributes.IsPrivateBrowsing(), crc,
|
||||
canSetCookie);
|
||||
if (!canSetCookie) {
|
||||
CookieParser parser(crc, aHostURI);
|
||||
moreCookies =
|
||||
parser.Parse(baseDomain, requireHostMatch, cookieStatus, cookieString,
|
||||
true, isForeignAndNotAddon, mustBePartitioned,
|
||||
storagePrincipalOriginAttributes.IsPrivateBrowsing());
|
||||
if (!parser.ContainsCookie()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check permissions from site permission list.
|
||||
if (!CookieCommons::CheckCookiePermission(aChannel, cookieData)) {
|
||||
if (!CookieCommons::CheckCookiePermission(aChannel, parser.CookieData())) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieString,
|
||||
"cookie rejected by permission manager");
|
||||
constexpr auto CONSOLE_REJECTION_CATEGORY = "cookiesRejection"_ns;
|
||||
CookieLogging::LogMessageToConsole(
|
||||
crc, aHostURI, nsIScriptError::warningFlag,
|
||||
CONSOLE_REJECTION_CATEGORY, "CookieRejectedByPermissionManager"_ns,
|
||||
AutoTArray<nsString, 1>{
|
||||
NS_ConvertUTF8toUTF16(cookieData.name()),
|
||||
});
|
||||
parser.RejectCookie(CookieParser::RejectedByPermissionManager);
|
||||
CookieCommons::NotifyRejected(
|
||||
aHostURI, aChannel,
|
||||
nsIWebProgressListener::STATE_COOKIES_BLOCKED_BY_PERMISSION,
|
||||
|
@ -729,8 +736,8 @@ CookieServiceChild::SetCookieStringFromHttp(nsIURI* aHostURI,
|
|||
// cookie jar independent of context. If the cookies are stored in the
|
||||
// partitioned cookie jar anyway no special treatment of CHIPS cookies
|
||||
// necessary.
|
||||
bool needPartitioned =
|
||||
isCHIPS && cookieData.isPartitioned() && !isPartitionedPrincipal;
|
||||
bool needPartitioned = isCHIPS && parser.CookieData().isPartitioned() &&
|
||||
!isPartitionedPrincipal;
|
||||
nsTArray<CookieStruct>& cookiesToSendRef =
|
||||
needPartitioned ? partitionedCookiesToSend : cookiesToSend;
|
||||
OriginAttributes& cookieOriginAttributes =
|
||||
|
@ -741,7 +748,8 @@ CookieServiceChild::SetCookieStringFromHttp(nsIURI* aHostURI,
|
|||
needPartitioned,
|
||||
!partitionedPrincipalOriginAttributes.mPartitionKey.IsEmpty());
|
||||
|
||||
RefPtr<Cookie> cookie = Cookie::Create(cookieData, cookieOriginAttributes);
|
||||
RefPtr<Cookie> cookie =
|
||||
Cookie::Create(parser.CookieData(), cookieOriginAttributes);
|
||||
MOZ_ASSERT(cookie);
|
||||
|
||||
cookie->SetLastAccessed(currentTimeInUsec);
|
||||
|
@ -749,7 +757,7 @@ CookieServiceChild::SetCookieStringFromHttp(nsIURI* aHostURI,
|
|||
Cookie::GenerateUniqueCreationTime(currentTimeInUsec));
|
||||
|
||||
RecordDocumentCookie(cookie, cookieOriginAttributes);
|
||||
cookiesToSendRef.AppendElement(cookieData);
|
||||
cookiesToSendRef.AppendElement(parser.CookieData());
|
||||
} while (moreCookies);
|
||||
|
||||
// Asynchronously call the parent.
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "Cookie.h"
|
||||
#include "CookieCommons.h"
|
||||
#include "CookieLogging.h"
|
||||
#include "CookieParser.h"
|
||||
#include "CookieNotification.h"
|
||||
#include "mozilla/net/MozURL_ffi.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
@ -498,7 +499,7 @@ void CookieStorage::NotifyChanged(nsISupports* aSubject,
|
|||
// replaces an existing cookie; or adds the cookie to the hashtable, and
|
||||
// deletes a cookie (if maximum number of cookies has been reached). also
|
||||
// performs list maintenance by removing expired cookies.
|
||||
void CookieStorage::AddCookie(nsIConsoleReportCollector* aCRC,
|
||||
void CookieStorage::AddCookie(CookieParser* aCookieParser,
|
||||
const nsACString& aBaseDomain,
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
Cookie* aCookie, int64_t aCurrentTimeInUsec,
|
||||
|
@ -517,7 +518,6 @@ void CookieStorage::AddCookie(nsIConsoleReportCollector* aCRC,
|
|||
potentiallyTrustworthy =
|
||||
nsMixedContentBlocker::IsPotentiallyTrustworthyOrigin(aHostURI);
|
||||
}
|
||||
constexpr auto CONSOLE_REJECTION_CATEGORY = "cookiesRejection"_ns;
|
||||
bool oldCookieIsSession = false;
|
||||
// Step1, call FindSecureCookie(). FindSecureCookie() would
|
||||
// find the existing cookie with the security flag and has
|
||||
|
@ -536,12 +536,9 @@ void CookieStorage::AddCookie(nsIConsoleReportCollector* aCRC,
|
|||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader,
|
||||
"cookie can't save because older cookie is secure "
|
||||
"cookie but newer cookie is non-secure cookie");
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::warningFlag, CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedNonsecureOverSecure"_ns,
|
||||
AutoTArray<nsString, 1>{
|
||||
NS_ConvertUTF8toUTF16(aCookie->Name()),
|
||||
});
|
||||
if (aCookieParser) {
|
||||
aCookieParser->RejectCookie(CookieParser::RejectedNonsecureOverSecure);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -581,13 +578,10 @@ void CookieStorage::AddCookie(nsIConsoleReportCollector* aCRC,
|
|||
COOKIE_LOGFAILURE(
|
||||
SET_COOKIE, aHostURI, aCookieHeader,
|
||||
"previously stored cookie is httponly; coming from script");
|
||||
CookieLogging::LogMessageToConsole(
|
||||
aCRC, aHostURI, nsIScriptError::warningFlag,
|
||||
CONSOLE_REJECTION_CATEGORY,
|
||||
"CookieRejectedHttpOnlyButFromScript"_ns,
|
||||
AutoTArray<nsString, 1>{
|
||||
NS_ConvertUTF8toUTF16(aCookie->Name()),
|
||||
});
|
||||
if (aCookieParser) {
|
||||
aCookieParser->RejectCookie(
|
||||
CookieParser::RejectedHttpOnlyButFromScript);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include "CookieCommons.h"
|
||||
|
||||
class nsIArray;
|
||||
class nsIConsoleReportCollector;
|
||||
class nsICookie;
|
||||
class nsICookieTransactionCallback;
|
||||
class nsIPrefBranch;
|
||||
|
@ -25,6 +24,7 @@ namespace mozilla {
|
|||
namespace net {
|
||||
|
||||
class Cookie;
|
||||
class CookieParser;
|
||||
|
||||
// Inherit from CookieKey so this can be stored in nsTHashTable
|
||||
// TODO: why aren't we using nsClassHashTable<CookieKey, ArrayType>?
|
||||
|
@ -123,7 +123,7 @@ class CookieStorage : public nsIObserver, public nsSupportsWeakReference {
|
|||
dom::BrowsingContext* aBrowsingContext = nullptr,
|
||||
bool aOldCookieIsSession = false);
|
||||
|
||||
void AddCookie(nsIConsoleReportCollector* aCRC, const nsACString& aBaseDomain,
|
||||
void AddCookie(CookieParser* aCookieParser, const nsACString& aBaseDomain,
|
||||
const OriginAttributes& aOriginAttributes, Cookie* aCookie,
|
||||
int64_t aCurrentTimeInUsec, nsIURI* aHostURI,
|
||||
const nsACString& aCookieHeader, bool aFromHttp,
|
||||
|
|
|
@ -91,6 +91,7 @@ CookieRejectedForNonSameSiteness=Cookie “%1$S” has been rejected because it
|
|||
CookieRejectedPartitionedRequiresSecure=Cookie “%1$S” has been rejected because it has the “Partitioned” attribute but is missing the “secure” attribute.
|
||||
# LOCALIZATION NOTE (CookieAttributeIgnored): %1$S is the cookie name. %2$S is the attribute name. %3$S is the number of bytes. "B" means bytes.
|
||||
CookieAttributeIgnored=The value of the attribute “%2$S” for the cookie “%1$S” has been rejected because its size is too big. Max size is %3$S B.
|
||||
CookieAttributeOverwritten=The value of the attribute “%2$S” for the cookie “%1$S” has been overwritten.
|
||||
|
||||
# LOCALIZATION NOTE (CookieForeignNoPartitionedWarning): %1$S is the cookie name. Do not translate "Partitioned"
|
||||
CookieForeignNoPartitionedWarning=Cookie “%1$S” will soon be rejected because it is foreign and does not have the “Partitioned“ attribute.
|
||||
|
|
Загрузка…
Ссылка в новой задаче