Loading dom/base/ThirdPartyUtil.cpp +15 −6 Original line number Diff line number Diff line Loading @@ -501,20 +501,28 @@ ThirdPartyUtil::GetBaseDomain(nsIURI* aHostURI, return NS_OK; } // Returns true if First Party Isolation is currently active for the given nsIChannel. // Depends on Preference setting and possibly the state of Private Browsing mode. bool ThirdPartyUtil::IsFirstPartyIsolationActive(nsIChannel *aChannel, nsIDocument *aDoc) // Determine if First Party Isolation is currently active for the given // nsIChannel or nsIDocument. Depends on preference setting and // possibly the state of Private Browsing mode. NS_IMETHODIMP ThirdPartyUtil::IsFirstPartyIsolationActive(nsIChannel *aChannel, nsIDocument *aDoc, bool* aResult) { NS_ASSERTION(aResult, "null outparam pointer"); int32_t isolationState = mozilla::Preferences::GetInt("privacy.thirdparty.isolate"); if (isolationState == 1) { if (!aChannel && aDoc) { // No channel passed directly. Can we get a channel from aDoc? aChannel = aDoc->GetChannel(); } return aChannel && NS_UsePrivateBrowsing(aChannel); *aResult = aChannel && NS_UsePrivateBrowsing(aChannel); } else { // (isolationState == 0) || (isolationState == 2) return (isolationState == 2); *aResult = (isolationState == 2); } return NS_OK; } // Produces a URI that uniquely identifies the first party to which Loading @@ -524,7 +532,8 @@ bool ThirdPartyUtil::IsFirstPartyIsolationActive(nsIChannel *aChannel, nsIDocume NS_IMETHODIMP ThirdPartyUtil::GetFirstPartyIsolationURI(nsIChannel *aChannel, nsIDocument *aDoc, nsIURI **aOutput) { bool isolationActive = IsFirstPartyIsolationActive(aChannel, aDoc); bool isolationActive = false; (void)IsFirstPartyIsolationActive(aChannel, aDoc, &isolationActive); if (isolationActive) { return GetFirstPartyURI(aChannel, aDoc, aOutput); } else { Loading netwerk/base/mozIThirdPartyUtil.idl +21 −1 Original line number Diff line number Diff line Loading @@ -13,7 +13,7 @@ interface nsIDocument; * Utility functions for determining whether a given URI, channel, or window * hierarchy is third party with respect to a known URI. */ [scriptable, uuid(b711bd7f-0674-49be-ae77-f221db5f7b6c)] [scriptable, uuid(b538074d-5e00-40b3-b5c4-e060ae010b83)] interface mozIThirdPartyUtil : nsISupports { /** Loading Loading @@ -178,6 +178,26 @@ interface mozIThirdPartyUtil : nsISupports [noscript] nsIURI getFirstPartyURI(in nsIChannel aChannel, in nsIDocument aDoc); /** * isFirstPartyIsolationActive * * Determine if First Party Isolation is currently active for the given * nsIChannel or nsIDocument. Depends on preference setting and * possibly the state of Private Browsing mode. * * @param aChannel * An arbitrary channel for some content element of a first party * load. Can be null. * * @param aDoc * An arbitrary third party document. Can be null. * * @return true if first party isolation is active. */ [noscript] bool isFirstPartyIsolationActive(in nsIChannel aChannel, in nsIDocument aDoc); /** * getFirstPartyIsolationURI * Loading netwerk/protocol/http/nsHttpChannel.cpp +70 −0 Original line number Diff line number Diff line Loading @@ -4907,6 +4907,8 @@ nsHttpChannel::BeginConnect() // notify "http-on-modify-request" observers CallOnModifyRequestObservers(); RemoveAuthorizationHeaderIfAppropriate(); // Check to see if we should redirect this channel elsewhere by // nsIHttpChannel.redirectTo API request if (mAPIRedirectToURI) { Loading Loading @@ -6168,6 +6170,72 @@ nsHttpChannel::ResumeAt(uint64_t aStartPos, return NS_OK; } // Remove the Authorization header if first party isolation is active and // this channel is processing a third party request. This prevents user // tracking via HTTP Basic Authentication. // Note that this approach disables authentication for 3rd party domains. It // would be better if we could isolate the authentication while still allowing // it to be transmitted... but HTTP authentication is rarely used anyway. void nsHttpChannel::RemoveAuthorizationHeaderIfAppropriate() { if (!mRequestHead.PeekHeader(nsHttp::Authorization)) { return; // No Authorization header is present. } nsCOMPtr<mozIThirdPartyUtil> thirdPartySvc = do_GetService(THIRDPARTYUTIL_CONTRACTID); bool isolationActive = true; (void)thirdPartySvc->IsFirstPartyIsolationActive(this, nullptr, &isolationActive); if (!isolationActive) return; // First party isolation is disabled for this channel. bool isAuthAllowed = false; nsCOMPtr<nsIURI> firstPartyURI; nsresult rv = thirdPartySvc->GetFirstPartyURIFromChannel(this, false, getter_AddRefs(firstPartyURI)); if (NS_SUCCEEDED(rv) && firstPartyURI) { isAuthAllowed = (mURI == firstPartyURI) || HostPartIsTheSame(firstPartyURI); } else { // We failed to get the first party URI. Check the document URI so // that we can allow authentication if the request originates from the // the browser chrome, e.g., some favicon requests. If there is no // document URI associated with this request, it cannot be associated // with a content document, so it must be a special request (e.g., // favicon fetch or OSCP), for which we also allow authenication. nsCOMPtr<nsIURI> docURI; rv = GetDocumentURI(getter_AddRefs(docURI)); if (NS_FAILED(rv) || !docURI) { isAuthAllowed = true; } else { nsAutoCString docURISpec; docURI->GetAsciiSpec(docURISpec); if (docURISpec == "chrome://browser/content/browser.xul") isAuthAllowed = true; } } if (!isAuthAllowed) { mRequestHead.ClearHeader(nsHttp::Authorization); mRequestHead.ClearHeader(nsHttp::Cache_Control); mRequestHead.ClearHeader(nsHttp::Pragma); #ifdef PR_LOGGING nsAutoCString requestURIStr, firstPartyURIStr; mURI->GetAsciiSpec(requestURIStr); if (firstPartyURI) firstPartyURI->GetAsciiSpec(firstPartyURIStr); else firstPartyURIStr = "--N/A--"; LOG(("Removed Authorization header from third party request" " [Request URI=%s, First Party URI=%s]\n", requestURIStr.get(), firstPartyURIStr.get())); #endif } } nsresult nsHttpChannel::DoAuthRetry(nsAHttpConnection *conn) { Loading @@ -6189,6 +6257,8 @@ nsHttpChannel::DoAuthRetry(nsAHttpConnection *conn) // notify "http-on-modify-request" observers CallOnModifyRequestObservers(); RemoveAuthorizationHeaderIfAppropriate(); mIsPending = true; // get rid of the old response headers Loading netwerk/protocol/http/nsHttpChannel.h +1 −0 Original line number Diff line number Diff line Loading @@ -310,6 +310,7 @@ private: nsresult ProcessPartialContent(); nsresult OnDoneReadingPartialCacheEntry(bool *streamDone); void RemoveAuthorizationHeaderIfAppropriate(); nsresult DoAuthRetry(nsAHttpConnection *); void HandleAsyncRedirectChannelToHttps(); Loading Loading
dom/base/ThirdPartyUtil.cpp +15 −6 Original line number Diff line number Diff line Loading @@ -501,20 +501,28 @@ ThirdPartyUtil::GetBaseDomain(nsIURI* aHostURI, return NS_OK; } // Returns true if First Party Isolation is currently active for the given nsIChannel. // Depends on Preference setting and possibly the state of Private Browsing mode. bool ThirdPartyUtil::IsFirstPartyIsolationActive(nsIChannel *aChannel, nsIDocument *aDoc) // Determine if First Party Isolation is currently active for the given // nsIChannel or nsIDocument. Depends on preference setting and // possibly the state of Private Browsing mode. NS_IMETHODIMP ThirdPartyUtil::IsFirstPartyIsolationActive(nsIChannel *aChannel, nsIDocument *aDoc, bool* aResult) { NS_ASSERTION(aResult, "null outparam pointer"); int32_t isolationState = mozilla::Preferences::GetInt("privacy.thirdparty.isolate"); if (isolationState == 1) { if (!aChannel && aDoc) { // No channel passed directly. Can we get a channel from aDoc? aChannel = aDoc->GetChannel(); } return aChannel && NS_UsePrivateBrowsing(aChannel); *aResult = aChannel && NS_UsePrivateBrowsing(aChannel); } else { // (isolationState == 0) || (isolationState == 2) return (isolationState == 2); *aResult = (isolationState == 2); } return NS_OK; } // Produces a URI that uniquely identifies the first party to which Loading @@ -524,7 +532,8 @@ bool ThirdPartyUtil::IsFirstPartyIsolationActive(nsIChannel *aChannel, nsIDocume NS_IMETHODIMP ThirdPartyUtil::GetFirstPartyIsolationURI(nsIChannel *aChannel, nsIDocument *aDoc, nsIURI **aOutput) { bool isolationActive = IsFirstPartyIsolationActive(aChannel, aDoc); bool isolationActive = false; (void)IsFirstPartyIsolationActive(aChannel, aDoc, &isolationActive); if (isolationActive) { return GetFirstPartyURI(aChannel, aDoc, aOutput); } else { Loading
netwerk/base/mozIThirdPartyUtil.idl +21 −1 Original line number Diff line number Diff line Loading @@ -13,7 +13,7 @@ interface nsIDocument; * Utility functions for determining whether a given URI, channel, or window * hierarchy is third party with respect to a known URI. */ [scriptable, uuid(b711bd7f-0674-49be-ae77-f221db5f7b6c)] [scriptable, uuid(b538074d-5e00-40b3-b5c4-e060ae010b83)] interface mozIThirdPartyUtil : nsISupports { /** Loading Loading @@ -178,6 +178,26 @@ interface mozIThirdPartyUtil : nsISupports [noscript] nsIURI getFirstPartyURI(in nsIChannel aChannel, in nsIDocument aDoc); /** * isFirstPartyIsolationActive * * Determine if First Party Isolation is currently active for the given * nsIChannel or nsIDocument. Depends on preference setting and * possibly the state of Private Browsing mode. * * @param aChannel * An arbitrary channel for some content element of a first party * load. Can be null. * * @param aDoc * An arbitrary third party document. Can be null. * * @return true if first party isolation is active. */ [noscript] bool isFirstPartyIsolationActive(in nsIChannel aChannel, in nsIDocument aDoc); /** * getFirstPartyIsolationURI * Loading
netwerk/protocol/http/nsHttpChannel.cpp +70 −0 Original line number Diff line number Diff line Loading @@ -4907,6 +4907,8 @@ nsHttpChannel::BeginConnect() // notify "http-on-modify-request" observers CallOnModifyRequestObservers(); RemoveAuthorizationHeaderIfAppropriate(); // Check to see if we should redirect this channel elsewhere by // nsIHttpChannel.redirectTo API request if (mAPIRedirectToURI) { Loading Loading @@ -6168,6 +6170,72 @@ nsHttpChannel::ResumeAt(uint64_t aStartPos, return NS_OK; } // Remove the Authorization header if first party isolation is active and // this channel is processing a third party request. This prevents user // tracking via HTTP Basic Authentication. // Note that this approach disables authentication for 3rd party domains. It // would be better if we could isolate the authentication while still allowing // it to be transmitted... but HTTP authentication is rarely used anyway. void nsHttpChannel::RemoveAuthorizationHeaderIfAppropriate() { if (!mRequestHead.PeekHeader(nsHttp::Authorization)) { return; // No Authorization header is present. } nsCOMPtr<mozIThirdPartyUtil> thirdPartySvc = do_GetService(THIRDPARTYUTIL_CONTRACTID); bool isolationActive = true; (void)thirdPartySvc->IsFirstPartyIsolationActive(this, nullptr, &isolationActive); if (!isolationActive) return; // First party isolation is disabled for this channel. bool isAuthAllowed = false; nsCOMPtr<nsIURI> firstPartyURI; nsresult rv = thirdPartySvc->GetFirstPartyURIFromChannel(this, false, getter_AddRefs(firstPartyURI)); if (NS_SUCCEEDED(rv) && firstPartyURI) { isAuthAllowed = (mURI == firstPartyURI) || HostPartIsTheSame(firstPartyURI); } else { // We failed to get the first party URI. Check the document URI so // that we can allow authentication if the request originates from the // the browser chrome, e.g., some favicon requests. If there is no // document URI associated with this request, it cannot be associated // with a content document, so it must be a special request (e.g., // favicon fetch or OSCP), for which we also allow authenication. nsCOMPtr<nsIURI> docURI; rv = GetDocumentURI(getter_AddRefs(docURI)); if (NS_FAILED(rv) || !docURI) { isAuthAllowed = true; } else { nsAutoCString docURISpec; docURI->GetAsciiSpec(docURISpec); if (docURISpec == "chrome://browser/content/browser.xul") isAuthAllowed = true; } } if (!isAuthAllowed) { mRequestHead.ClearHeader(nsHttp::Authorization); mRequestHead.ClearHeader(nsHttp::Cache_Control); mRequestHead.ClearHeader(nsHttp::Pragma); #ifdef PR_LOGGING nsAutoCString requestURIStr, firstPartyURIStr; mURI->GetAsciiSpec(requestURIStr); if (firstPartyURI) firstPartyURI->GetAsciiSpec(firstPartyURIStr); else firstPartyURIStr = "--N/A--"; LOG(("Removed Authorization header from third party request" " [Request URI=%s, First Party URI=%s]\n", requestURIStr.get(), firstPartyURIStr.get())); #endif } } nsresult nsHttpChannel::DoAuthRetry(nsAHttpConnection *conn) { Loading @@ -6189,6 +6257,8 @@ nsHttpChannel::DoAuthRetry(nsAHttpConnection *conn) // notify "http-on-modify-request" observers CallOnModifyRequestObservers(); RemoveAuthorizationHeaderIfAppropriate(); mIsPending = true; // get rid of the old response headers Loading
netwerk/protocol/http/nsHttpChannel.h +1 −0 Original line number Diff line number Diff line Loading @@ -310,6 +310,7 @@ private: nsresult ProcessPartialContent(); nsresult OnDoneReadingPartialCacheEntry(bool *streamDone); void RemoveAuthorizationHeaderIfAppropriate(); nsresult DoAuthRetry(nsAHttpConnection *); void HandleAsyncRedirectChannelToHttps(); Loading