Bug 1344170: set firstPartyDomai on blob: URI. r=smaug

A web page could generate an URL by URl.createObjectURL(new Blob(...));
then navigate to this generated URL.

In this case the (top-level) document URI will be blob:{origin}:{uuid}.
And we try to add firstPartyDomain on this top-level document with blob URI, so
the following request from this document could have correct origin
attributes.
This commit is contained in:
Yoshi Huang 2017-04-12 14:47:48 +08:00
Родитель 31140c21b1
Коммит 332addc285
4 изменённых файлов: 100 добавлений и 8 удалений

Просмотреть файл

@ -65,6 +65,7 @@ support-files =
[browser_favicon_userContextId.js]
[browser_firstPartyIsolation.js]
[browser_firstPartyIsolation_aboutPages.js]
[browser_firstPartyIsolation_blobURI.js]
[browser_firstPartyIsolation_js_uri.js]
[browser_localStorageIsolation.js]
[browser_blobURLIsolation.js]

Просмотреть файл

@ -5,6 +5,7 @@ add_task(function* setup() {
Services.prefs.setBoolPref("privacy.firstparty.isolate", true);
registerCleanupFunction(function() {
Services.prefs.clearUserPref("privacy.firstparty.isolate");
Services.cookies.removeAll();
});
});

Просмотреть файл

@ -0,0 +1,76 @@
add_task(function* setup() {
Services.prefs.setBoolPref("privacy.firstparty.isolate", true);
registerCleanupFunction(function() {
Services.prefs.clearUserPref("privacy.firstparty.isolate");
Services.cookies.removeAll();
});
});
/**
* First we generate a Blob URI by using URL.createObjectURL(new Blob(..));
* then we navigate to this Blob URI, hence to make the top-level document URI
* is Blob URI.
* Later we create an iframe on this Blob: document, and we test that the iframe
* has correct firstPartyDomain.
*/
add_task(function* test_blob_uri_inherit_oa_from_content() {
const BASE_URI = "http://mochi.test:8888/browser/browser/components/" +
"originattributes/test/browser/dummy.html";
const BASE_DOMAIN = "mochi.test";
// First we load a normal web page.
let win = yield BrowserTestUtils.openNewBrowserWindow({ remote: true });
let browser = win.gBrowser.selectedBrowser;
browser.loadURI(BASE_URI);
yield BrowserTestUtils.browserLoaded(browser);
// Then navigate to the blob: URI.
yield ContentTask.spawn(browser, { firstPartyDomain: BASE_DOMAIN }, function* (attrs) {
info("origin " + content.document.nodePrincipal.origin);
Assert.equal(content.document.nodePrincipal.originAttributes.firstPartyDomain,
attrs.firstPartyDomain, "The document should have firstPartyDomain");
// Now we use createObjectURL to generate a blob URI and navigate to it.
let url = content.window.URL.createObjectURL(new content.window.Blob([
`<script src="http://mochi.test:8888/browser/browser/components/originattributes/test/browser/test.js"></script>`],
{"type": "text/html"}));
content.document.location = url;
});
// Wait for the Blob: URI to be loaded.
yield BrowserTestUtils.browserLoaded(browser, false, function(url) {
info("BrowserTestUtils.browserLoaded url=" + url);
return url.startsWith("blob:http://mochi.test:8888/");
});
// We verify the blob document has correct origin attributes.
// Then we inject an iframe to it.
yield ContentTask.spawn(browser, { firstPartyDomain: BASE_DOMAIN }, function* (attrs) {
Assert.ok(content.document.documentURI.startsWith("blob:http://mochi.test:8888/"),
"the document URI should be a blob URI.");
info("origin " + content.document.nodePrincipal.origin);
Assert.equal(content.document.nodePrincipal.originAttributes.firstPartyDomain,
attrs.firstPartyDomain, "The document should have firstPartyDomain");
let iframe = content.document.createElement("iframe");
iframe.src = "http://example.com";
iframe.id = "iframe1";
content.document.body.appendChild(iframe);
});
// Wait for the iframe to be loaded.
// yield BrowserTestUtils.browserLoaded(browser, true, function(url) {
// info("BrowserTestUtils.browserLoaded iframe url=" + url);
// return url == "http://example.com/";
// });
// Finally we verify the iframe has correct origin attributes.
yield ContentTask.spawn(browser, { firstPartyDomain: BASE_DOMAIN }, function* (attrs) {
let iframe = content.document.getElementById("iframe1");
Assert.equal(iframe.contentDocument.nodePrincipal.originAttributes.firstPartyDomain,
attrs.firstPartyDomain, "iframe should inherit firstPartyDomain from blob: URI");
});
win.close();
});

Просмотреть файл

@ -10,6 +10,7 @@
#include "mozilla/dom/quota/QuotaManager.h"
#include "nsIEffectiveTLDService.h"
#include "nsIURI.h"
#include "nsIURIWithPrincipal.h"
namespace mozilla {
@ -52,16 +53,29 @@ OriginAttributes::SetFirstPartyDomain(const bool aIsTopLevelDocument,
nsAutoCString baseDomain;
nsresult rv = tldService->GetBaseDomain(aURI, 0, baseDomain);
if (NS_FAILED(rv)) {
nsAutoCString scheme;
rv = aURI->GetScheme(scheme);
NS_ENSURE_SUCCESS_VOID(rv);
if (scheme.EqualsLiteral("about")) {
baseDomain.AssignLiteral(ABOUT_URI_FIRST_PARTY_DOMAIN);
}
if (NS_SUCCEEDED(rv)) {
mFirstPartyDomain = NS_ConvertUTF8toUTF16(baseDomain);
return;
}
mFirstPartyDomain = NS_ConvertUTF8toUTF16(baseDomain);
nsAutoCString scheme;
rv = aURI->GetScheme(scheme);
NS_ENSURE_SUCCESS_VOID(rv);
if (scheme.EqualsLiteral("about")) {
mFirstPartyDomain.AssignLiteral(ABOUT_URI_FIRST_PARTY_DOMAIN);
} else if (scheme.EqualsLiteral("blob")) {
nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
if (uriPrinc) {
nsCOMPtr<nsIPrincipal> principal;
rv = uriPrinc->GetPrincipal(getter_AddRefs(principal));
NS_ENSURE_SUCCESS_VOID(rv);
MOZ_ASSERT(principal, "blob URI but no principal.");
if (principal) {
mFirstPartyDomain = principal->OriginAttributesRef().mFirstPartyDomain;
}
}
}
}
void