CookieCommons.h (7932B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef mozilla_net_CookieCommons_h 7 #define mozilla_net_CookieCommons_h 8 9 #include <cstdint> 10 #include <functional> 11 #include "mozIThirdPartyUtil.h" 12 #include "prtime.h" 13 #include "nsString.h" 14 #include "nsICookie.h" 15 #include "mozilla/net/NeckoChannelParams.h" 16 17 class nsIChannel; 18 class nsICookieJarSettings; 19 class nsIEffectiveTLDService; 20 class nsIPrincipal; 21 class nsIURI; 22 23 namespace mozilla { 24 25 namespace dom { 26 class Document; 27 } 28 29 namespace net { 30 31 // these constants represent an operation being performed on cookies 32 enum CookieOperation { OPERATION_READ, OPERATION_WRITE }; 33 34 // these constants represent a decision about a cookie based on user prefs. 35 enum CookieStatus { 36 STATUS_ACCEPTED, 37 STATUS_ACCEPT_SESSION, 38 STATUS_REJECTED, 39 // STATUS_REJECTED_WITH_ERROR indicates the cookie should be rejected because 40 // of an error (rather than something the user can control). this is used for 41 // notification purposes, since we only want to notify of rejections where 42 // the user can do something about it (e.g. whitelist the site). 43 STATUS_REJECTED_WITH_ERROR 44 }; 45 46 class Cookie; 47 class CookieParser; 48 49 // pref string constants 50 static const char kPrefMaxNumberOfCookies[] = "network.cookie.maxNumber"; 51 static const char kPrefMaxCookiesPerHost[] = "network.cookie.maxPerHost"; 52 static const char kPrefCookieQuotaPerHost[] = "network.cookie.quotaPerHost"; 53 static const char kPrefCookiePurgeAge[] = "network.cookie.purgeAge"; 54 55 // default limits for the cookie list. these can be tuned by the 56 // network.cookie.maxNumber and network.cookie.maxPerHost prefs respectively. 57 static const uint32_t kMaxCookiesPerHost = 180; 58 static const uint32_t kCookieQuotaPerHost = 150; 59 static const uint32_t kMaxNumberOfCookies = 3000; 60 61 static const int64_t kCookiePurgeAge = 62 int64_t(30 * 24 * 60 * 60) * PR_USEC_PER_SEC; // 30 days in microseconds 63 64 class CookieCommons final { 65 public: 66 static bool DomainMatches(Cookie* aCookie, const nsACString& aHost); 67 68 static bool PathMatches(Cookie* aCookie, const nsACString& aPath); 69 70 static bool PathMatches(const nsACString& aCookiePath, 71 const nsACString& aPath); 72 73 static nsresult GetBaseDomain(nsIEffectiveTLDService* aTLDService, 74 nsIURI* aHostURI, nsACString& aBaseDomain, 75 bool& aRequireHostMatch); 76 77 static nsresult GetBaseDomain(nsIPrincipal* aPrincipal, 78 nsACString& aBaseDomain); 79 80 static nsresult GetBaseDomainFromHost(nsIEffectiveTLDService* aTLDService, 81 const nsACString& aHost, 82 nsCString& aBaseDomain); 83 84 // This method returns true if aBaseDomain contains any colons since only 85 // IPv6 baseDomains may contain colons. 86 static bool IsIPv6BaseDomain(const nsACString& aBaseDomain); 87 88 static void NotifyRejected(nsIURI* aHostURI, nsIChannel* aChannel, 89 uint32_t aRejectedReason, 90 CookieOperation aOperation); 91 92 static bool CheckCookiePermission(nsIChannel* aChannel, 93 CookieStruct& aCookieData); 94 95 static bool CheckCookiePermission(nsIPrincipal* aPrincipal, 96 nsICookieJarSettings* aCookieJarSettings, 97 CookieStruct& aCookieData); 98 99 static already_AddRefed<Cookie> CreateCookieFromDocument( 100 CookieParser& aCookieParser, dom::Document* aDocument, 101 const nsACString& aCookieString, int64_t aCurrentTimeInUsec, 102 nsIEffectiveTLDService* aTLDService, mozIThirdPartyUtil* aThirdPartyUtil, 103 nsACString& aBaseDomain, OriginAttributes& aAttrs); 104 105 static already_AddRefed<nsICookieJarSettings> GetCookieJarSettings( 106 nsIChannel* aChannel); 107 108 static bool ShouldIncludeCrossSiteCookie(Cookie* aCookie, nsIURI* aHostURI, 109 bool aPartitionForeign, 110 bool aInPrivateBrowsing, 111 bool aUsingStorageAccess, 112 bool aOn3pcbException); 113 114 static bool ShouldIncludeCrossSiteCookie( 115 nsIURI* aHostURI, int32_t aSameSiteAttr, bool aCookiePartitioned, 116 bool aPartitionForeign, bool aInPrivateBrowsing, bool aUsingStorageAccess, 117 bool aOn3pcbException); 118 119 static bool IsFirstPartyPartitionedCookieWithoutCHIPS( 120 Cookie* aCookie, const nsACString& aBaseDomain, 121 const OriginAttributes& aOriginAttributes); 122 123 static bool ShouldEnforceSessionForOriginAttributes( 124 const OriginAttributes& aOriginAttributes); 125 126 static bool IsSchemeSupported(nsIPrincipal* aPrincipal); 127 static bool IsSchemeSupported(nsIURI* aURI); 128 static bool IsSchemeSupported(const nsACString& aScheme); 129 130 static nsICookie::schemeType URIToSchemeType(nsIURI* aURI); 131 132 static nsICookie::schemeType PrincipalToSchemeType(nsIPrincipal* aPrincipal); 133 134 static nsICookie::schemeType SchemeToSchemeType(const nsACString& aScheme); 135 136 // Returns true if the channel is a safe top-level navigation or if it's a 137 // download request 138 static bool IsSafeTopLevelNav(nsIChannel* aChannel); 139 140 // Returns true if the channel is a foreign with respect to the host-uri. 141 // For loads of TYPE_DOCUMENT, this function returns true if it's a cross 142 // site navigation. 143 // `aHadCrossSiteRedirects` will be true iff the channel had a cross-site 144 // redirect before the final URI. 145 static bool IsSameSiteForeign(nsIChannel* aChannel, nsIURI* aHostURI, 146 bool* aHadCrossSiteRedirects); 147 148 static bool ChipsLimitEnabledAndChipsCookie( 149 const Cookie& cookie, dom::BrowsingContext* aBrowsingContext); 150 151 static void ComposeCookieString(nsTArray<RefPtr<Cookie>>& aCookieList, 152 nsACString& aCookieString); 153 154 static void GetServerDateHeader(nsIChannel* aChannel, 155 nsACString& aServerDateHeader); 156 157 enum class SecurityChecksResult { 158 // A sandboxed context detected. 159 eSandboxedError, 160 // A security error needs to be thrown. 161 eSecurityError, 162 // This context should not see cookies without returning errors. 163 eDoNotContinue, 164 // No security issues found. Proceed to expose cookies. 165 eContinue, 166 }; 167 168 // Runs the security checks requied by specs on the current context (Document 169 // or Worker) to see if it's allowed to set/get cookies. In case it does 170 // (eContinue), the cookie principals are returned. Use the 171 // `aCookiePartitionedPrincipal` to retrieve CHIP cookies. Use 172 // `aCookiePrincipal` to retrieve non-CHIP cookies. 173 static SecurityChecksResult CheckGlobalAndRetrieveCookiePrincipals( 174 mozilla::dom::Document* aDocument, nsIPrincipal** aCookiePrincipal, 175 nsIPrincipal** aCookiePartitionedPrincipal); 176 177 // Return a reduced expiry attribute value if needed. 178 static int64_t MaybeCapExpiry(int64_t aCurrentTimeInMSec, 179 int64_t aExpiryInMSec); 180 181 // Return a reduced expiry value starting from the max-age attribute and the 182 // current time. 183 static int64_t MaybeCapMaxAge(int64_t aCurrentTimeInMSec, 184 int64_t aMaxAgeInSec); 185 186 // returns true if 'a' is equal to or a subdomain of 'b', 187 // assuming no leading dots are present. 188 static bool IsSubdomainOf(const nsACString& a, const nsACString& b); 189 190 // Returns the current time in USecs using a nsIChannel, which corresponds to 191 // the response start time. 192 static int64_t GetCurrentTimeInUSecFromChannel(nsIChannel* aChannel); 193 }; 194 195 } // namespace net 196 } // namespace mozilla 197 198 #endif // mozilla_net_CookieCommons_h