commit 6d41ba055896b2fad9132b6d08b29a57bd22afa6 Author: Mike Perry mikeperry-git@torproject.org Date: Wed Oct 2 19:20:03 2013 -0700
fixup! Add mozIThirdPartyUtil.getFirstPartyURI API
Make getFirstPartyURI log+handle errors internally to simplify caller usage of the API. --- content/base/src/ThirdPartyUtil.cpp | 110 ++++++++++++++++++++++++++++ content/base/src/ThirdPartyUtil.h | 1 + netwerk/base/public/mozIThirdPartyUtil.idl | 22 ++++++ 3 files changed, 133 insertions(+)
diff --git a/content/base/src/ThirdPartyUtil.cpp b/content/base/src/ThirdPartyUtil.cpp index ad1b0fa..36c2d25 100644 --- a/content/base/src/ThirdPartyUtil.cpp +++ b/content/base/src/ThirdPartyUtil.cpp @@ -14,6 +14,9 @@ #include "nsIPrincipal.h" #include "nsIScriptObjectPrincipal.h" #include "nsThreadUtils.h" +#include "nsPrintfCString.h" +#include "nsIConsoleService.h" +#include "nsContentUtils.h"
NS_IMPL_ISUPPORTS1(ThirdPartyUtil, mozIThirdPartyUtil)
@@ -49,6 +52,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; + + nsCAutoString 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. already_AddRefed<nsIURI> ThirdPartyUtil::GetURIFromWindow(nsIDOMWindow* aWin) @@ -307,6 +325,21 @@ ThirdPartyUtil::GetFirstPartyURI(nsIChannel *aChannel, // for sure if (aChannel) { rv = mCookiePermissions->GetOriginatingURI(aChannel, aOutput); + 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. + nsCAutoString 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 @@ -340,6 +373,41 @@ ThirdPartyUtil::GetFirstPartyURI(nsIChannel *aChannel, rv = NS_OK; }
+ if (*aOutput && !SchemeIsWhiteListed(*aOutput)) { + // If URI scheme is not whitelisted and the URI lacks a hostname, force a + // failure. + nsCAutoString host; + rv = (*aOutput)->GetHost(host); + if (NS_SUCCEEDED(rv) && (host.Length() == 0)) { + rv = NS_ERROR_FAILURE; + } + } + + // Log failure to error console. + if (NS_FAILED(rv)) { + nsCOMPtr<nsIConsoleService> console + (do_GetService(NS_CONSOLESERVICE_CONTRACTID)); + if (console) { + nsCString spec; + if (*aOutput) + (*aOutput)->GetSpec(spec); + if (spec.Length() > 0) { + nsPrintfCString msg("getFirstPartyURI: no host in first party URI %s", + spec.get()); // TODO: L10N + console->LogStringMessage(NS_ConvertUTF8toUTF16(msg).get()); + } else { + nsPrintfCString msg("getFirstPartyURI failed: 0x%x", 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). @@ -350,3 +418,45 @@ ThirdPartyUtil::GetFirstPartyURI(nsIChannel *aChannel, return rv; }
+NS_IMETHODIMP +ThirdPartyUtil::GetFirstPartyHostForIsolation(nsIURI *aFirstPartyURI, + nsACString& aHost) +{ + if (!aFirstPartyURI) + return NS_ERROR_INVALID_ARG; + + if (!SchemeIsWhiteListed(aFirstPartyURI)) { + nsresult rv = aFirstPartyURI->GetHost(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". + nsCAutoString 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) + nsCAutoString 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; +} diff --git a/content/base/src/ThirdPartyUtil.h b/content/base/src/ThirdPartyUtil.h index fe7b214..3cf442e 100644 --- a/content/base/src/ThirdPartyUtil.h +++ b/content/base/src/ThirdPartyUtil.h @@ -27,6 +27,7 @@ public: private: nsresult IsThirdPartyInternal(const nsCString& aFirstDomain, nsIURI* aSecondURI, bool* aResult); + bool SchemeIsWhiteListed(nsIURI *aURI); static already_AddRefed<nsIURI> GetURIFromWindow(nsIDOMWindow* aWin);
nsCOMPtr<nsIEffectiveTLDService> mTLDService; diff --git a/netwerk/base/public/mozIThirdPartyUtil.idl b/netwerk/base/public/mozIThirdPartyUtil.idl index 963385c..b602ac3 100644 --- a/netwerk/base/public/mozIThirdPartyUtil.idl +++ b/netwerk/base/public/mozIThirdPartyUtil.idl @@ -157,10 +157,32 @@ interface mozIThirdPartyUtil : nsISupports * 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. */ nsIURI getFirstPartyURI(in nsIChannel aChannel, in nsIDocument aDoc);
+ /** + * 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++
tor-commits@lists.torproject.org