Skip to content

Commit

Permalink
Bug 1297687 - Use the OriginAttributes associated with a window princ…
Browse files Browse the repository at this point in the history
…ipal when creating a Sandbox with an expanded principal; r=baku
  • Loading branch information
ehsan committed Sep 1, 2016
1 parent 29df86a commit 7d8261a
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 4 deletions.
8 changes: 8 additions & 0 deletions caps/nsIScriptSecurityManager.idl
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,14 @@ interface nsIScriptSecurityManager : nsISupports
*/
nsIPrincipal getChannelURIPrincipal(in nsIChannel aChannel);

/**
* Get the principal for a sandbox object.
*
* This function is currently only used in tests.
*/
[implicit_jscontext]
nsIPrincipal getSandboxPrincipal(in jsval aSandbox);

/**
* Check whether a given principal is a system principal. This allows us
* to avoid handing back the system principal to script while allowing
Expand Down
9 changes: 8 additions & 1 deletion caps/nsPrincipal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,14 @@ struct OriginComparator
}
};

nsExpandedPrincipal::nsExpandedPrincipal(nsTArray<nsCOMPtr <nsIPrincipal> > &aWhiteList)
nsExpandedPrincipal::nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
const PrincipalOriginAttributes& aOriginAttributes)
: nsExpandedPrincipal(aWhiteList)
{
mOriginAttributes = aOriginAttributes;
}

nsExpandedPrincipal::nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList)
{
// We force the principals to be sorted by origin so that nsExpandedPrincipal
// origins can have a canonical form.
Expand Down
4 changes: 3 additions & 1 deletion caps/nsPrincipal.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ class nsPrincipal final : public mozilla::BasePrincipal
class nsExpandedPrincipal : public nsIExpandedPrincipal, public mozilla::BasePrincipal
{
public:
explicit nsExpandedPrincipal(nsTArray< nsCOMPtr<nsIPrincipal> > &aWhiteList);
nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
const mozilla::PrincipalOriginAttributes& aOriginAttributes);
explicit nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList);

NS_DECL_NSIEXPANDEDPRINCIPAL
NS_DECL_NSISERIALIZABLE
Expand Down
13 changes: 13 additions & 0 deletions caps/nsScriptSecurityManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
#include "nsJSUtils.h"
#include "nsILoadInfo.h"
#include "nsXPCOMStrings.h"
#include "xpcprivate.h"

// This should be probably defined on some other place... but I couldn't find it
#define WEBAPPS_PERM_NAME "webapps-manage"
Expand Down Expand Up @@ -472,6 +473,18 @@ nsScriptSecurityManager::GetChannelURIPrincipal(nsIChannel* aChannel,
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
}

NS_IMETHODIMP
nsScriptSecurityManager::GetSandboxPrincipal(JS::HandleValue aSandboxArg,
JSContext* aCx,
nsIPrincipal** aPrincipal)
{
if (!aSandboxArg.isObject()) {
return NS_ERROR_INVALID_ARG;
}
JS::RootedObject sandbox(aCx, &aSandboxArg.toObject());
return xpc::GetSandboxPrincipal(aCx, sandbox, aPrincipal);
}

NS_IMETHODIMP
nsScriptSecurityManager::IsSystemPrincipal(nsIPrincipal* aPrincipal,
bool* aIsSystem)
Expand Down
35 changes: 33 additions & 2 deletions js/xpconnect/src/Sandbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1326,6 +1326,8 @@ GetExpandedPrincipal(JSContext* cx, HandleObject arrayObj, nsIExpandedPrincipal*
nsTArray< nsCOMPtr<nsIPrincipal> > allowedDomains(length);
allowedDomains.SetLength(length);

nsCOMPtr<nsIPrincipal> windowPrincipal;

for (uint32_t i = 0; i < length; ++i) {
RootedValue allowed(cx);
if (!JS_GetElement(cx, arrayObj, i, &allowed))
Expand All @@ -1337,7 +1339,7 @@ GetExpandedPrincipal(JSContext* cx, HandleObject arrayObj, nsIExpandedPrincipal*
// In case of string let's try to fetch a codebase principal from it.
RootedString str(cx, allowed.toString());

// We use a default originAttributes here because we don't support
// We use a default context ID here because we don't support
// passing a userContextId with an array.
PrincipalOriginAttributes attrs;
if (!ParsePrincipal(cx, str, attrs, getter_AddRefs(principal)))
Expand All @@ -1354,6 +1356,11 @@ GetExpandedPrincipal(JSContext* cx, HandleObject arrayObj, nsIExpandedPrincipal*
principal = do_QueryInterface(prinOrSop);
if (sop)
principal = sop->GetPrincipal();

// If a Window object has been passed, the expanded principal will inherit
// its OriginAttributes. If more than one Window object has been passed, use
// the last one.
windowPrincipal = principal;
}
NS_ENSURE_TRUE(principal, false);

Expand All @@ -1368,7 +1375,11 @@ GetExpandedPrincipal(JSContext* cx, HandleObject arrayObj, nsIExpandedPrincipal*
allowedDomains[i] = principal;
}

nsCOMPtr<nsIExpandedPrincipal> result = new nsExpandedPrincipal(allowedDomains);
PrincipalOriginAttributes attrs;
if (windowPrincipal) {
attrs = BasePrincipal::Cast(windowPrincipal)->OriginAttributesRef();
}
RefPtr<nsExpandedPrincipal> result = new nsExpandedPrincipal(allowedDomains, attrs);
result.forget(out);
return true;
}
Expand Down Expand Up @@ -1738,6 +1749,26 @@ nsXPCComponents_utils_Sandbox::CallOrConstruct(nsIXPConnectWrappedNative* wrappe
return NS_OK;
}

nsresult
xpc::GetSandboxPrincipal(JSContext* aCx, HandleObject aSandboxArg,
nsIPrincipal** aPrincipal)
{
JS_AbortIfWrongThread(aCx);

RootedObject sandbox(aCx, js::CheckedUnwrap(aSandboxArg));
if (!sandbox || !IsSandbox(sandbox)) {
return NS_ERROR_INVALID_ARG;
}

nsIScriptObjectPrincipal* sop =
static_cast<nsIScriptObjectPrincipal*>(xpc_GetJSPrivate(sandbox));
MOZ_ASSERT(sop, "Invalid sandbox passed");
nsCOMPtr<nsIPrincipal> prin = sop->GetPrincipal();
prin.forget(aPrincipal);

return NS_OK;
}

nsresult
xpc::EvalInSandbox(JSContext* cx, HandleObject sandboxArg, const nsAString& source,
const nsACString& filename, int32_t lineNo,
Expand Down
4 changes: 4 additions & 0 deletions js/xpconnect/src/xpcprivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -3295,6 +3295,10 @@ nsresult
SetSandboxMetadata(JSContext* cx, JS::HandleObject sandboxArg,
JS::HandleValue metadata);

nsresult
GetSandboxPrincipal(JSContext* aCx, JS::HandleObject aSandboxArg,
nsIPrincipal** aPrincipal);

bool
CreateObjectIn(JSContext* cx, JS::HandleValue vobj, CreateObjectInOptions& options,
JS::MutableHandleValue rval);
Expand Down
1 change: 1 addition & 0 deletions js/xpconnect/tests/browser/browser.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
support-files =
browser_deadObjectOnUnload.html
[browser_dead_object.js]
[browser_expandedPrincipal_originAttributes.js]
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

add_task(function* test() {
let privateWin = yield BrowserTestUtils.openNewBrowserWindow({private: true});

yield ContentTask.spawn(privateWin.gBrowser.selectedBrowser, {}, function*() {
let tests = [
[["https://mozilla.org", content], 1],
[["https://mozilla.org", "https://example.com"], 0],
];
tests.forEach(item => {
let sandbox = Components.utils.Sandbox(item[0]);
let principal = Services.scriptSecurityManager
.getSandboxPrincipal(sandbox);
is(principal.privateBrowsingId, item[1],
"Sandbox principal should have the correct OriginAttributes");
});
});

privateWin.close();

yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function*() {
let tests = [
[["https://mozilla.org", content], 0],
[["https://mozilla.org", "https://example.com"], 0],
];
tests.forEach(item => {
let sandbox = Components.utils.Sandbox(item[0]);
let principal = Services.scriptSecurityManager
.getSandboxPrincipal(sandbox);
is(principal.privateBrowsingId, item[1],
"Sandbox principal should have the correct OriginAttributes");
});
});
});

0 comments on commit 7d8261a

Please sign in to comment.