diff options
-rw-r--r-- | dom/base/nsContentSink.cpp | 5 | ||||
-rw-r--r-- | dom/base/nsIDocument.h | 28 | ||||
-rw-r--r-- | dom/html/nsHTMLDocument.cpp | 10 |
3 files changed, 43 insertions, 0 deletions
diff --git a/dom/base/nsContentSink.cpp b/dom/base/nsContentSink.cpp index 3d6f069d2..85b3d07bf 100644 --- a/dom/base/nsContentSink.cpp +++ b/dom/base/nsContentSink.cpp @@ -305,6 +305,11 @@ nsContentSink::ProcessHeaderData(nsIAtom* aHeader, const nsAString& aValue, mDocument->SetHeaderData(aHeader, aValue); if (aHeader == nsGkAtoms::setcookie) { + // Don't allow setting cookies in cookie-averse documents. + if (mDocument->IsCookieAverse()) { + return NS_OK; + } + // Note: Necko already handles cookies set via the channel. We can't just // call SetCookie on the channel because we want to do some security checks // here. diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index 5b10c9914..8f35e9ba5 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -1923,6 +1923,34 @@ public: return mMarkedCCGeneration; } + /** + * Returns whether this document is cookie-averse. See + * https://html.spec.whatwg.org/multipage/dom.html#cookie-averse-document-object + */ + bool IsCookieAverse() const + { + // If we are a document that "has no browsing context." + if (!GetInnerWindow()) { + return true; + } + + // If we are a document "whose URL's scheme is not a network scheme." + // NB: Explicitly allow file: URIs to store cookies. + nsCOMPtr<nsIURI> codebaseURI; + NodePrincipal()->GetURI(getter_AddRefs(codebaseURI)); + + if (!codebaseURI) { + return true; + } + + nsAutoCString scheme; + codebaseURI->GetScheme(scheme); + return !scheme.EqualsLiteral("http") && + !scheme.EqualsLiteral("https") && + !scheme.EqualsLiteral("ftp") && + !scheme.EqualsLiteral("file"); + } + bool IsLoadedAsData() { return mLoadedAsData; diff --git a/dom/html/nsHTMLDocument.cpp b/dom/html/nsHTMLDocument.cpp index 5e6302941..7d66aab04 100644 --- a/dom/html/nsHTMLDocument.cpp +++ b/dom/html/nsHTMLDocument.cpp @@ -1255,6 +1255,11 @@ nsHTMLDocument::GetCookie(nsAString& aCookie, ErrorResult& rv) rv.Throw(NS_ERROR_DOM_SECURITY_ERR); return; } + + // If the document is a cookie-averse document, return an empty string. + if (IsCookieAverse()) { + return; + } // not having a cookie service isn't an error nsCOMPtr<nsICookieService> service = do_GetService(NS_COOKIESERVICE_CONTRACTID); @@ -1310,6 +1315,11 @@ nsHTMLDocument::SetCookie(const nsAString& aCookie, ErrorResult& rv) return; } + // If the document is a cookie-averse document, do nothing. + if (IsCookieAverse()) { + return; + } + // not having a cookie service isn't an error nsCOMPtr<nsICookieService> service = do_GetService(NS_COOKIESERVICE_CONTRACTID); if (service && mDocumentURI) { |