commit 0d67ab406bdd3cf095802cb25c081641aa1f0bcc
Author: Arthur Edelstein <arthuredelstein(a)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++