commit 0d67ab406bdd3cf095802cb25c081641aa1f0bcc Author: Arthur Edelstein arthuredelstein@gmail.com Date: Sun Apr 12 13:47:55 2015 -0700
Bug #15502. Isolate blob URLs to first party; no blobURLs in Web Workers --- content/base/src/ThirdPartyUtil.cpp | 9 +++++++++ content/base/src/nsHostObjectProtocolHandler.cpp | 23 ++++++++++++++++++++-- dom/workers/URL.cpp | 7 +++++++ netwerk/base/public/mozIThirdPartyUtil.idl | 15 ++++++++++++++ 4 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/content/base/src/ThirdPartyUtil.cpp b/content/base/src/ThirdPartyUtil.cpp index 695392f..0e037d1 100644 --- a/content/base/src/ThirdPartyUtil.cpp +++ b/content/base/src/ThirdPartyUtil.cpp @@ -635,3 +635,12 @@ ThirdPartyUtil::GetFirstPartyHostForIsolation(nsIURI *aFirstPartyURI, aHost.Append("--"); return NS_OK; } + +NS_IMETHODIMP +ThirdPartyUtil::GetFirstPartyHostFromCaller(nsACString& aHost) { + nsCOMPtr<nsIURI> uri; + nsresult rv = GetFirstPartyIsolationURI(nullptr, + nsContentUtils::GetDocumentFromCaller(), getter_AddRefs(uri)); + NS_ENSURE_SUCCESS(rv, rv); + return GetFirstPartyHostForIsolation(uri, aHost); +} diff --git a/content/base/src/nsHostObjectProtocolHandler.cpp b/content/base/src/nsHostObjectProtocolHandler.cpp index 10ec44c..e578804 100644 --- a/content/base/src/nsHostObjectProtocolHandler.cpp +++ b/content/base/src/nsHostObjectProtocolHandler.cpp @@ -15,6 +15,7 @@ #include "mozilla/dom/MediaSource.h" #include "nsIMemoryReporter.h" #include "mozilla/Preferences.h" +#include "mozIThirdPartyUtil.h"
// ----------------------------------------------------------------------- // Hash table @@ -24,9 +25,20 @@ struct DataInfo nsCOMPtr<nsISupports> mObject; nsCOMPtr<nsIPrincipal> mPrincipal; nsCString mStack; + nsCString mFirstPartyHost; };
static nsClassHashtable<nsCStringHashKey, DataInfo>* gDataTable; +static nsCOMPtr<mozIThirdPartyUtil> gThirdPartyUtilService; + +static nsCString GetFirstPartyHostFromCaller() { + if (!gThirdPartyUtilService) { + gThirdPartyUtilService = do_GetService(THIRDPARTYUTIL_CONTRACTID); + } + nsCString host; + gThirdPartyUtilService->GetFirstPartyHostFromCaller(host); + return host; +}
// Memory reporting for the hash table. namespace mozilla { @@ -290,6 +302,8 @@ nsHostObjectProtocolHandler::AddDataEntry(const nsACString& aScheme,
info->mObject = aObject; info->mPrincipal = aPrincipal; + // Record the first party host that originated this object. + info->mFirstPartyHost = GetFirstPartyHostFromCaller(); mozilla::BlobURLsReporter::GetJSStackForBlob(info);
gDataTable->Put(aUri, info); @@ -401,7 +415,10 @@ GetDataObject(nsIURI* aURI) aURI->GetSpec(spec);
DataInfo* info = GetDataInfo(spec); - return info ? info->mObject : nullptr; + // Deny access to this object if the current first-party host + // doesn't match the originating first-party host. + return (info && info->mFirstPartyHost == GetFirstPartyHostFromCaller()) + ? info->mObject : nullptr; }
// ----------------------------------------------------------------------- @@ -457,7 +474,9 @@ nsHostObjectProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
DataInfo* info = GetDataInfo(spec);
- if (!info) { + // Deny access to this URI if the current first party host + // doesn't match the first party host when it was created. + if (!info || (info->mFirstPartyHost != GetFirstPartyHostFromCaller())) { return NS_ERROR_DOM_BAD_URI; } nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(info->mObject); diff --git a/dom/workers/URL.cpp b/dom/workers/URL.cpp index f80594e..d52e4c6 100644 --- a/dom/workers/URL.cpp +++ b/dom/workers/URL.cpp @@ -894,6 +894,13 @@ URL::CreateObjectURL(const GlobalObject& aGlobal, JSObject* aBlob, JSContext* cx = aGlobal.GetContext(); WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
+ if (!workerPrivate->IsChromeWorker()) { + workerPrivate->ReportError(cx, "Worker attempted to use createObjectURL; denied.", nullptr); + NS_NAMED_LITERAL_STRING(argStr, "URL.createObjectURL"); + aRv.ThrowTypeError(MSG_METHOD_THIS_UNWRAPPING_DENIED, &argStr); + return; + } + nsCOMPtr<nsIDOMBlob> blob = file::GetDOMBlobFromJSObject(aBlob); if (!blob) { SetDOMStringToNull(aResult); diff --git a/netwerk/base/public/mozIThirdPartyUtil.idl b/netwerk/base/public/mozIThirdPartyUtil.idl index 0bb632b..0b0f410 100644 --- a/netwerk/base/public/mozIThirdPartyUtil.idl +++ b/netwerk/base/public/mozIThirdPartyUtil.idl @@ -246,6 +246,21 @@ interface mozIThirdPartyUtil : nsISupports * for which we generate a pseudo host. */ AUTF8String getFirstPartyHostForIsolation(in nsIURI aFirstPartyURI); + + /** + * getFirstPartyHostFromCaller + * + * Obtain the host or pseudo-host for the first party URI belonging + * to the calling document. See getFirstPartyHostForIsolation(...) for + * examples. + * + * @return host or pseudo host. + * + * @throws if the calling document's first party URI lacks a host + * and the scheme is not a whitelisted one for which we + * generate a pseudo host. + */ + AUTF8String getFirstPartyHostFromCaller(); };
%{ C++