Loading dom/base/ThirdPartyUtil.cpp +304 −0 Original line number Diff line number Diff line Loading @@ -9,12 +9,18 @@ #include "nsIServiceManager.h" #include "nsIHttpChannelInternal.h" #include "nsIDOMWindow.h" #include "nsICookiePermission.h" #include "nsIDOMDocument.h" #include "nsIDocument.h" #include "nsILoadContext.h" #include "nsIPrincipal.h" #include "nsIScriptObjectPrincipal.h" #include "nsIURI.h" #include "nsThreadUtils.h" #include "prlog.h" #include "nsPrintfCString.h" #include "nsIConsoleService.h" #include "nsContentUtils.h" NS_IMPL_ISUPPORTS(ThirdPartyUtil, mozIThirdPartyUtil) Loading @@ -32,6 +38,7 @@ ThirdPartyUtil::Init() nsresult rv; mTLDService = do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv); mCookiePermissions = do_GetService(NS_COOKIEPERMISSION_CONTRACTID); if (!gThirdPartyLog) gThirdPartyLog = PR_NewLogModule("thirdPartyUtil"); Loading Loading @@ -60,6 +67,21 @@ ThirdPartyUtil::IsThirdPartyInternal(const nsCString& aFirstDomain, return NS_OK; } // Return true if aURI's scheme is white listed, in which case // getFirstPartyURI() will not require that the firstPartyURI contains a host. bool ThirdPartyUtil::SchemeIsWhiteListed(nsIURI *aURI) { if (!aURI) return false; nsAutoCString scheme; nsresult rv = aURI->GetScheme(scheme); NS_ENSURE_SUCCESS(rv, false); return (scheme.Equals("about") || scheme.Equals("moz-safe-about") || scheme.Equals("chrome")); } // Get the URI associated with a window. NS_IMETHODIMP ThirdPartyUtil::GetURIFromWindow(nsIDOMWindow* aWin, nsIURI** result) Loading @@ -84,6 +106,106 @@ ThirdPartyUtil::GetURIFromWindow(nsIDOMWindow* aWin, nsIURI** result) return rv; } nsresult ThirdPartyUtil::GetOriginatingURI(nsIChannel *aChannel, nsIURI **aURI) { /* to find the originating URI, we use the loadgroup of the channel to obtain * the window owning the load, and from there, we find the top same-type * window and its URI. there are several possible cases: * * 1) no channel. * * 2) a channel with the "force allow third party cookies" option set. * since we may not have a window, we return the channel URI in this case. * * 3) a channel, but no window. this can occur when the consumer kicking * off the load doesn't provide one to the channel, and should be limited * to loads of certain types of resources. * * 4) a window equal to the top window of same type, with the channel its * document channel. this covers the case of a freshly kicked-off load * (e.g. the user typing something in the location bar, or clicking on a * bookmark), where the window's URI hasn't yet been set, and will be * bogus. we return the channel URI in this case. * * 5) Anything else. this covers most cases for an ordinary page load from * the location bar, and will catch nested frames within a page, image * loads, etc. we return the URI of the root window's document's principal * in this case. */ *aURI = nullptr; // case 1) if (!aChannel) return NS_ERROR_NULL_POINTER; // case 2) nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal = do_QueryInterface(aChannel); if (httpChannelInternal) { bool doForce = false; if (NS_SUCCEEDED(httpChannelInternal->GetForceAllowThirdPartyCookie(&doForce)) && doForce) { // return the channel's URI (we may not have a window) aChannel->GetURI(aURI); if (!*aURI) return NS_ERROR_NULL_POINTER; return NS_OK; } // TODO: Why don't we just use this here: // httpChannelInternal->GetDocumentURI(aURI); } // find the associated window and its top window nsCOMPtr<nsILoadContext> ctx; NS_QueryNotificationCallbacks(aChannel, ctx); nsCOMPtr<nsIDOMWindow> topWin, ourWin; if (ctx) { ctx->GetTopWindow(getter_AddRefs(topWin)); ctx->GetAssociatedWindow(getter_AddRefs(ourWin)); } // case 3) if (!topWin) return NS_ERROR_INVALID_ARG; // case 4) if (ourWin == topWin) { // Check whether this is the document channel for this window (representing // a load of a new page). This is a bit of a nasty hack, but we will // hopefully flag these channels better later. nsLoadFlags flags; aChannel->GetLoadFlags(&flags); if (flags & nsIChannel::LOAD_DOCUMENT_URI) { // get the channel URI - the window's will be bogus aChannel->GetURI(aURI); if (!*aURI) return NS_ERROR_NULL_POINTER; return NS_OK; } } // case 5) - get the originating URI from the top window's principal nsCOMPtr<nsIScriptObjectPrincipal> scriptObjPrin = do_QueryInterface(topWin); NS_ENSURE_TRUE(scriptObjPrin, NS_ERROR_UNEXPECTED); nsIPrincipal* prin = scriptObjPrin->GetPrincipal(); NS_ENSURE_TRUE(prin, NS_ERROR_UNEXPECTED); prin->GetURI(aURI); if (!*aURI) return NS_ERROR_NULL_POINTER; // all done! return NS_OK; } // Determine if aFirstURI is third party with respect to aSecondURI. See docs // for mozIThirdPartyUtil. NS_IMETHODIMP Loading Loading @@ -368,3 +490,185 @@ ThirdPartyUtil::GetBaseDomain(nsIURI* aHostURI, return NS_OK; } // Not scriptable due to the use of an nsIDocument parameter. NS_IMETHODIMP ThirdPartyUtil::GetFirstPartyURI(nsIChannel *aChannel, nsIDocument *aDoc, nsIURI **aOutput) { return GetFirstPartyURIInternal(aChannel, aDoc, true, aOutput); } nsresult ThirdPartyUtil::GetFirstPartyURIInternal(nsIChannel *aChannel, nsIDocument *aDoc, bool aLogErrors, nsIURI **aOutput) { nsresult rv = NS_ERROR_NULL_POINTER; nsCOMPtr<nsIURI> srcURI; if (!aOutput) return rv; *aOutput = nullptr; if (!aChannel && aDoc) { aChannel = aDoc->GetChannel(); } // If aChannel is specified or available, use the official route // for sure if (aChannel) { rv = GetOriginatingURI(aChannel, aOutput); aChannel->GetURI(getter_AddRefs(srcURI)); if (NS_SUCCEEDED(rv) && *aOutput) { // At this point, about: and chrome: URLs have been mapped to file: or // jar: URLs. Try to recover the original URL. nsAutoCString scheme; nsresult rv2 = (*aOutput)->GetScheme(scheme); NS_ENSURE_SUCCESS(rv2, rv2); if (scheme.Equals("file") || scheme.Equals("jar")) { nsCOMPtr<nsIURI> originalURI; rv2 = aChannel->GetOriginalURI(getter_AddRefs(originalURI)); if (NS_SUCCEEDED(rv2) && originalURI) { NS_RELEASE(*aOutput); NS_ADDREF(*aOutput = originalURI); } } } } // If the channel was missing, closed or broken, try the // window hierarchy directly. // // This might fail to work for first-party loads themselves, but // we don't need this codepath for that case. if (NS_FAILED(rv) && aDoc) { nsCOMPtr<nsIDOMWindow> top; nsCOMPtr<nsIDOMDocument> topDDoc; nsIURI *docURI = nullptr; srcURI = aDoc->GetDocumentURI(); if (aDoc->GetWindow()) { aDoc->GetWindow()->GetTop(getter_AddRefs(top)); top->GetDocument(getter_AddRefs(topDDoc)); nsCOMPtr<nsIDocument> topDoc(do_QueryInterface(topDDoc)); docURI = topDoc->GetOriginalURI(); if (docURI) { // Give us a mutable URI and also addref rv = NS_EnsureSafeToReturn(docURI, aOutput); } } else { // XXX: Chrome callers (such as NoScript) can end up here // through getImageData/canvas usage with no document state // (no Window and a document URI of about:blank). Propogate // rv fail (by doing nothing), and hope caller recovers. } if (*aOutput) rv = NS_OK; } if (*aOutput && !SchemeIsWhiteListed(*aOutput)) { // If URI scheme is not whitelisted and the URI lacks a hostname, force a // failure. nsAutoCString host; rv = (*aOutput)->GetHost(host); if (NS_SUCCEEDED(rv) && (host.Length() == 0)) { rv = NS_ERROR_FAILURE; } } // Log failure to error console. if (aLogErrors && NS_FAILED(rv)) { nsCOMPtr<nsIConsoleService> console (do_GetService(NS_CONSOLESERVICE_CONTRACTID)); if (console) { nsCString spec; nsCString srcSpec("unknown"); if (srcURI) srcURI->GetSpec(srcSpec); if (*aOutput) (*aOutput)->GetSpec(spec); if (spec.Length() > 0) { nsPrintfCString msg("getFirstPartyURI failed for %s: no host in first party URI %s", srcSpec.get(), spec.get()); // TODO: L10N console->LogStringMessage(NS_ConvertUTF8toUTF16(msg).get()); } else { nsPrintfCString msg("getFirstPartyURI failed for %s: 0x%x", srcSpec.get(), rv); console->LogStringMessage(NS_ConvertUTF8toUTF16(msg).get()); } } if (*aOutput) { // discard return object. (*aOutput)->Release(); *aOutput = nullptr; } } // TODO: We could provide a route through the loadgroup + notification // callbacks too, but either channel or document was always available // in the cases where this function was originally needed (the image cache). // The notification callbacks also appear to suffers from the same limitation // as the document path. See nsICookiePermissions.GetOriginatingURI() for // details. return rv; } NS_IMETHODIMP ThirdPartyUtil::GetFirstPartyURIFromChannel(nsIChannel *aChannel, bool aLogErrors, nsIURI **aOutput) { return GetFirstPartyURIInternal(aChannel, nullptr, aLogErrors, aOutput); } NS_IMETHODIMP ThirdPartyUtil::GetFirstPartyHostForIsolation(nsIURI *aFirstPartyURI, nsACString& aHost) { if (!aFirstPartyURI) return NS_ERROR_INVALID_ARG; if (!SchemeIsWhiteListed(aFirstPartyURI)) { nsresult rv = GetBaseDomain(aFirstPartyURI, aHost); return (aHost.Length() > 0) ? NS_OK : rv; } // This URI lacks a host, so construct and return a pseudo-host. aHost = "--NoFirstPartyHost-"; // Append the scheme. To ensure that the pseudo-hosts are consistent // when the hacky "moz-safe-about" scheme is used, map it back to "about". nsAutoCString scheme; nsresult rv = aFirstPartyURI->GetScheme(scheme); NS_ENSURE_SUCCESS(rv, rv); if (scheme.Equals("moz-safe-about")) aHost.Append("about"); else aHost.Append(scheme); // Append the URL's file name (e.g., -browser.xul) or its path (e.g., // -home for about:home) nsAutoCString s; nsCOMPtr<nsIURL> url = do_QueryInterface(aFirstPartyURI); if (url) url->GetFileName(s); else aFirstPartyURI->GetPath(s); if (s.Length() > 0) { aHost.Append("-"); aHost.Append(s); } aHost.Append("--"); return NS_OK; } dom/base/ThirdPartyUtil.h +6 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include "nsString.h" #include "mozIThirdPartyUtil.h" #include "nsIEffectiveTLDService.h" #include "nsICookiePermission.h" #include "mozilla/Attributes.h" class nsIURI; Loading @@ -28,8 +29,13 @@ private: nsresult IsThirdPartyInternal(const nsCString& aFirstDomain, nsIURI* aSecondURI, bool* aResult); bool SchemeIsWhiteListed(nsIURI *aURI); static nsresult GetOriginatingURI(nsIChannel *aChannel, nsIURI **aURI); nsresult GetFirstPartyURIInternal(nsIChannel *aChannel, nsIDocument *aDoc, bool aLogErrors, nsIURI **aOutput); nsCOMPtr<nsIEffectiveTLDService> mTLDService; nsCOMPtr<nsICookiePermission> mCookiePermissions; }; #endif Loading netwerk/base/mozIThirdPartyUtil.idl +63 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ interface nsIURI; interface nsIDOMWindow; interface nsIChannel; interface nsIDocument; /** * Utility functions for determining whether a given URI, channel, or window Loading Loading @@ -155,6 +156,68 @@ interface mozIThirdPartyUtil : nsISupports * Returns the top-level window associated with the given channel. */ nsIDOMWindow getTopWindowForChannel(in nsIChannel aChannel); /** * getFirstPartyURI * * Obtain the top-level url bar URI for either a channel or a document. * Either parameter may be null (but not both). * * @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 the first party url bar URI for the load. * * @throws if the URI cannot be obtained or the URI lacks a hostname and the * URI's scheme is not white listed. */ [noscript] nsIURI getFirstPartyURI(in nsIChannel aChannel, in nsIDocument aDoc); /** * getFirstPartyURIFromChannel * * Obtain the top-level url bar URI for a channel. * * @param aChannel * An arbitrary channel for some content element of a first party * load. * * @param aLogErrors * If true, log errors to the Error Console. * * @return the first party url bar URI for the load. * * @throws if the URI cannot be obtained or the URI lacks a hostname and the * URI's scheme is not white listed. */ nsIURI getFirstPartyURIFromChannel(in nsIChannel aChannel, in bool aLogErrors); /** * getFirstPartyHostForIsolation * * Obtain the host or pseudo-host for aFirstPartyURI. Some examples: * aFirstPartyURI Return Value * -------------- ------------ * https://news.google.com/nwshp?hl=en "news.google.com" * about:home "--NoFirstPartyHost-about-home--" * chrome://browser/content/browser.xul "--NoFirstPartyHost-chrome-browser.xul--" * * @param aFirstPartyURI * The first party URI. * * @return host or pseudo host. * * @throws if the URI lacks a host and the scheme is not a whitelisted one * for which we generate a pseudo host. */ AUTF8String getFirstPartyHostForIsolation(in nsIURI aFirstPartyURI); }; %{ C++ Loading Loading
dom/base/ThirdPartyUtil.cpp +304 −0 Original line number Diff line number Diff line Loading @@ -9,12 +9,18 @@ #include "nsIServiceManager.h" #include "nsIHttpChannelInternal.h" #include "nsIDOMWindow.h" #include "nsICookiePermission.h" #include "nsIDOMDocument.h" #include "nsIDocument.h" #include "nsILoadContext.h" #include "nsIPrincipal.h" #include "nsIScriptObjectPrincipal.h" #include "nsIURI.h" #include "nsThreadUtils.h" #include "prlog.h" #include "nsPrintfCString.h" #include "nsIConsoleService.h" #include "nsContentUtils.h" NS_IMPL_ISUPPORTS(ThirdPartyUtil, mozIThirdPartyUtil) Loading @@ -32,6 +38,7 @@ ThirdPartyUtil::Init() nsresult rv; mTLDService = do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv); mCookiePermissions = do_GetService(NS_COOKIEPERMISSION_CONTRACTID); if (!gThirdPartyLog) gThirdPartyLog = PR_NewLogModule("thirdPartyUtil"); Loading Loading @@ -60,6 +67,21 @@ ThirdPartyUtil::IsThirdPartyInternal(const nsCString& aFirstDomain, return NS_OK; } // Return true if aURI's scheme is white listed, in which case // getFirstPartyURI() will not require that the firstPartyURI contains a host. bool ThirdPartyUtil::SchemeIsWhiteListed(nsIURI *aURI) { if (!aURI) return false; nsAutoCString scheme; nsresult rv = aURI->GetScheme(scheme); NS_ENSURE_SUCCESS(rv, false); return (scheme.Equals("about") || scheme.Equals("moz-safe-about") || scheme.Equals("chrome")); } // Get the URI associated with a window. NS_IMETHODIMP ThirdPartyUtil::GetURIFromWindow(nsIDOMWindow* aWin, nsIURI** result) Loading @@ -84,6 +106,106 @@ ThirdPartyUtil::GetURIFromWindow(nsIDOMWindow* aWin, nsIURI** result) return rv; } nsresult ThirdPartyUtil::GetOriginatingURI(nsIChannel *aChannel, nsIURI **aURI) { /* to find the originating URI, we use the loadgroup of the channel to obtain * the window owning the load, and from there, we find the top same-type * window and its URI. there are several possible cases: * * 1) no channel. * * 2) a channel with the "force allow third party cookies" option set. * since we may not have a window, we return the channel URI in this case. * * 3) a channel, but no window. this can occur when the consumer kicking * off the load doesn't provide one to the channel, and should be limited * to loads of certain types of resources. * * 4) a window equal to the top window of same type, with the channel its * document channel. this covers the case of a freshly kicked-off load * (e.g. the user typing something in the location bar, or clicking on a * bookmark), where the window's URI hasn't yet been set, and will be * bogus. we return the channel URI in this case. * * 5) Anything else. this covers most cases for an ordinary page load from * the location bar, and will catch nested frames within a page, image * loads, etc. we return the URI of the root window's document's principal * in this case. */ *aURI = nullptr; // case 1) if (!aChannel) return NS_ERROR_NULL_POINTER; // case 2) nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal = do_QueryInterface(aChannel); if (httpChannelInternal) { bool doForce = false; if (NS_SUCCEEDED(httpChannelInternal->GetForceAllowThirdPartyCookie(&doForce)) && doForce) { // return the channel's URI (we may not have a window) aChannel->GetURI(aURI); if (!*aURI) return NS_ERROR_NULL_POINTER; return NS_OK; } // TODO: Why don't we just use this here: // httpChannelInternal->GetDocumentURI(aURI); } // find the associated window and its top window nsCOMPtr<nsILoadContext> ctx; NS_QueryNotificationCallbacks(aChannel, ctx); nsCOMPtr<nsIDOMWindow> topWin, ourWin; if (ctx) { ctx->GetTopWindow(getter_AddRefs(topWin)); ctx->GetAssociatedWindow(getter_AddRefs(ourWin)); } // case 3) if (!topWin) return NS_ERROR_INVALID_ARG; // case 4) if (ourWin == topWin) { // Check whether this is the document channel for this window (representing // a load of a new page). This is a bit of a nasty hack, but we will // hopefully flag these channels better later. nsLoadFlags flags; aChannel->GetLoadFlags(&flags); if (flags & nsIChannel::LOAD_DOCUMENT_URI) { // get the channel URI - the window's will be bogus aChannel->GetURI(aURI); if (!*aURI) return NS_ERROR_NULL_POINTER; return NS_OK; } } // case 5) - get the originating URI from the top window's principal nsCOMPtr<nsIScriptObjectPrincipal> scriptObjPrin = do_QueryInterface(topWin); NS_ENSURE_TRUE(scriptObjPrin, NS_ERROR_UNEXPECTED); nsIPrincipal* prin = scriptObjPrin->GetPrincipal(); NS_ENSURE_TRUE(prin, NS_ERROR_UNEXPECTED); prin->GetURI(aURI); if (!*aURI) return NS_ERROR_NULL_POINTER; // all done! return NS_OK; } // Determine if aFirstURI is third party with respect to aSecondURI. See docs // for mozIThirdPartyUtil. NS_IMETHODIMP Loading Loading @@ -368,3 +490,185 @@ ThirdPartyUtil::GetBaseDomain(nsIURI* aHostURI, return NS_OK; } // Not scriptable due to the use of an nsIDocument parameter. NS_IMETHODIMP ThirdPartyUtil::GetFirstPartyURI(nsIChannel *aChannel, nsIDocument *aDoc, nsIURI **aOutput) { return GetFirstPartyURIInternal(aChannel, aDoc, true, aOutput); } nsresult ThirdPartyUtil::GetFirstPartyURIInternal(nsIChannel *aChannel, nsIDocument *aDoc, bool aLogErrors, nsIURI **aOutput) { nsresult rv = NS_ERROR_NULL_POINTER; nsCOMPtr<nsIURI> srcURI; if (!aOutput) return rv; *aOutput = nullptr; if (!aChannel && aDoc) { aChannel = aDoc->GetChannel(); } // If aChannel is specified or available, use the official route // for sure if (aChannel) { rv = GetOriginatingURI(aChannel, aOutput); aChannel->GetURI(getter_AddRefs(srcURI)); if (NS_SUCCEEDED(rv) && *aOutput) { // At this point, about: and chrome: URLs have been mapped to file: or // jar: URLs. Try to recover the original URL. nsAutoCString scheme; nsresult rv2 = (*aOutput)->GetScheme(scheme); NS_ENSURE_SUCCESS(rv2, rv2); if (scheme.Equals("file") || scheme.Equals("jar")) { nsCOMPtr<nsIURI> originalURI; rv2 = aChannel->GetOriginalURI(getter_AddRefs(originalURI)); if (NS_SUCCEEDED(rv2) && originalURI) { NS_RELEASE(*aOutput); NS_ADDREF(*aOutput = originalURI); } } } } // If the channel was missing, closed or broken, try the // window hierarchy directly. // // This might fail to work for first-party loads themselves, but // we don't need this codepath for that case. if (NS_FAILED(rv) && aDoc) { nsCOMPtr<nsIDOMWindow> top; nsCOMPtr<nsIDOMDocument> topDDoc; nsIURI *docURI = nullptr; srcURI = aDoc->GetDocumentURI(); if (aDoc->GetWindow()) { aDoc->GetWindow()->GetTop(getter_AddRefs(top)); top->GetDocument(getter_AddRefs(topDDoc)); nsCOMPtr<nsIDocument> topDoc(do_QueryInterface(topDDoc)); docURI = topDoc->GetOriginalURI(); if (docURI) { // Give us a mutable URI and also addref rv = NS_EnsureSafeToReturn(docURI, aOutput); } } else { // XXX: Chrome callers (such as NoScript) can end up here // through getImageData/canvas usage with no document state // (no Window and a document URI of about:blank). Propogate // rv fail (by doing nothing), and hope caller recovers. } if (*aOutput) rv = NS_OK; } if (*aOutput && !SchemeIsWhiteListed(*aOutput)) { // If URI scheme is not whitelisted and the URI lacks a hostname, force a // failure. nsAutoCString host; rv = (*aOutput)->GetHost(host); if (NS_SUCCEEDED(rv) && (host.Length() == 0)) { rv = NS_ERROR_FAILURE; } } // Log failure to error console. if (aLogErrors && NS_FAILED(rv)) { nsCOMPtr<nsIConsoleService> console (do_GetService(NS_CONSOLESERVICE_CONTRACTID)); if (console) { nsCString spec; nsCString srcSpec("unknown"); if (srcURI) srcURI->GetSpec(srcSpec); if (*aOutput) (*aOutput)->GetSpec(spec); if (spec.Length() > 0) { nsPrintfCString msg("getFirstPartyURI failed for %s: no host in first party URI %s", srcSpec.get(), spec.get()); // TODO: L10N console->LogStringMessage(NS_ConvertUTF8toUTF16(msg).get()); } else { nsPrintfCString msg("getFirstPartyURI failed for %s: 0x%x", srcSpec.get(), rv); console->LogStringMessage(NS_ConvertUTF8toUTF16(msg).get()); } } if (*aOutput) { // discard return object. (*aOutput)->Release(); *aOutput = nullptr; } } // TODO: We could provide a route through the loadgroup + notification // callbacks too, but either channel or document was always available // in the cases where this function was originally needed (the image cache). // The notification callbacks also appear to suffers from the same limitation // as the document path. See nsICookiePermissions.GetOriginatingURI() for // details. return rv; } NS_IMETHODIMP ThirdPartyUtil::GetFirstPartyURIFromChannel(nsIChannel *aChannel, bool aLogErrors, nsIURI **aOutput) { return GetFirstPartyURIInternal(aChannel, nullptr, aLogErrors, aOutput); } NS_IMETHODIMP ThirdPartyUtil::GetFirstPartyHostForIsolation(nsIURI *aFirstPartyURI, nsACString& aHost) { if (!aFirstPartyURI) return NS_ERROR_INVALID_ARG; if (!SchemeIsWhiteListed(aFirstPartyURI)) { nsresult rv = GetBaseDomain(aFirstPartyURI, aHost); return (aHost.Length() > 0) ? NS_OK : rv; } // This URI lacks a host, so construct and return a pseudo-host. aHost = "--NoFirstPartyHost-"; // Append the scheme. To ensure that the pseudo-hosts are consistent // when the hacky "moz-safe-about" scheme is used, map it back to "about". nsAutoCString scheme; nsresult rv = aFirstPartyURI->GetScheme(scheme); NS_ENSURE_SUCCESS(rv, rv); if (scheme.Equals("moz-safe-about")) aHost.Append("about"); else aHost.Append(scheme); // Append the URL's file name (e.g., -browser.xul) or its path (e.g., // -home for about:home) nsAutoCString s; nsCOMPtr<nsIURL> url = do_QueryInterface(aFirstPartyURI); if (url) url->GetFileName(s); else aFirstPartyURI->GetPath(s); if (s.Length() > 0) { aHost.Append("-"); aHost.Append(s); } aHost.Append("--"); return NS_OK; }
dom/base/ThirdPartyUtil.h +6 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include "nsString.h" #include "mozIThirdPartyUtil.h" #include "nsIEffectiveTLDService.h" #include "nsICookiePermission.h" #include "mozilla/Attributes.h" class nsIURI; Loading @@ -28,8 +29,13 @@ private: nsresult IsThirdPartyInternal(const nsCString& aFirstDomain, nsIURI* aSecondURI, bool* aResult); bool SchemeIsWhiteListed(nsIURI *aURI); static nsresult GetOriginatingURI(nsIChannel *aChannel, nsIURI **aURI); nsresult GetFirstPartyURIInternal(nsIChannel *aChannel, nsIDocument *aDoc, bool aLogErrors, nsIURI **aOutput); nsCOMPtr<nsIEffectiveTLDService> mTLDService; nsCOMPtr<nsICookiePermission> mCookiePermissions; }; #endif Loading
netwerk/base/mozIThirdPartyUtil.idl +63 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ interface nsIURI; interface nsIDOMWindow; interface nsIChannel; interface nsIDocument; /** * Utility functions for determining whether a given URI, channel, or window Loading Loading @@ -155,6 +156,68 @@ interface mozIThirdPartyUtil : nsISupports * Returns the top-level window associated with the given channel. */ nsIDOMWindow getTopWindowForChannel(in nsIChannel aChannel); /** * getFirstPartyURI * * Obtain the top-level url bar URI for either a channel or a document. * Either parameter may be null (but not both). * * @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 the first party url bar URI for the load. * * @throws if the URI cannot be obtained or the URI lacks a hostname and the * URI's scheme is not white listed. */ [noscript] nsIURI getFirstPartyURI(in nsIChannel aChannel, in nsIDocument aDoc); /** * getFirstPartyURIFromChannel * * Obtain the top-level url bar URI for a channel. * * @param aChannel * An arbitrary channel for some content element of a first party * load. * * @param aLogErrors * If true, log errors to the Error Console. * * @return the first party url bar URI for the load. * * @throws if the URI cannot be obtained or the URI lacks a hostname and the * URI's scheme is not white listed. */ nsIURI getFirstPartyURIFromChannel(in nsIChannel aChannel, in bool aLogErrors); /** * getFirstPartyHostForIsolation * * Obtain the host or pseudo-host for aFirstPartyURI. Some examples: * aFirstPartyURI Return Value * -------------- ------------ * https://news.google.com/nwshp?hl=en "news.google.com" * about:home "--NoFirstPartyHost-about-home--" * chrome://browser/content/browser.xul "--NoFirstPartyHost-chrome-browser.xul--" * * @param aFirstPartyURI * The first party URI. * * @return host or pseudo host. * * @throws if the URI lacks a host and the scheme is not a whitelisted one * for which we generate a pseudo host. */ AUTF8String getFirstPartyHostForIsolation(in nsIURI aFirstPartyURI); }; %{ C++ Loading