Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

var ssm = Services.scriptSecurityManager;
function makeURI(uri) {
return Services.io.newURI(uri);
}
function checkThrows(f) {
var threw = false;
try {
f();
} catch (e) {
threw = true;
}
Assert.ok(threw);
}
function checkCrossOrigin(a, b) {
Assert.ok(!a.equals(b));
Assert.ok(!a.equalsConsideringDomain(b));
Assert.ok(!a.subsumes(b));
Assert.ok(!a.subsumesConsideringDomain(b));
Assert.ok(!b.subsumes(a));
Assert.ok(!b.subsumesConsideringDomain(a));
}
function checkOriginAttributes(prin, attrs, suffix) {
attrs = attrs || {};
Assert.equal(prin.originSuffix, suffix || "");
Assert.equal(ChromeUtils.originAttributesToSuffix(attrs), suffix || "");
Assert.ok(
ChromeUtils.originAttributesMatchPattern(prin.originAttributes, attrs)
);
if (!prin.isNullPrincipal && !prin.origin.startsWith("[")) {
Assert.ok(ssm.createContentPrincipalFromOrigin(prin.origin).equals(prin));
} else {
checkThrows(() => ssm.createContentPrincipalFromOrigin(prin.origin));
}
}
function checkSandboxOriginAttributes(arr, attrs, options) {
options = options || {};
var sandbox = Cu.Sandbox(arr, options);
checkOriginAttributes(
Cu.getObjectPrincipal(sandbox),
attrs,
ChromeUtils.originAttributesToSuffix(attrs)
);
}
// utility function useful for debugging
// eslint-disable-next-line no-unused-vars
function printAttrs(name, attrs) {
info(
name +
" {\n" +
"\tuserContextId: " +
attrs.userContextId +
",\n" +
"\tprivateBrowsingId: '" +
attrs.privateBrowsingId +
"',\n" +
"\tfirstPartyDomain: '" +
attrs.firstPartyDomain +
"'\n}"
);
}
function checkValues(attrs, values) {
values = values || {};
// printAttrs("attrs", attrs);
// printAttrs("values", values);
Assert.equal(attrs.userContextId, values.userContextId || 0);
Assert.equal(attrs.privateBrowsingId, values.privateBrowsingId || "");
Assert.equal(attrs.firstPartyDomain, values.firstPartyDomain || "");
}
function run_test() {
// Attributeless origins.
Assert.equal(ssm.getSystemPrincipal().origin, "[System Principal]");
checkOriginAttributes(ssm.getSystemPrincipal());
var exampleOrg = ssm.createContentPrincipal(
makeURI("http://example.org"),
{}
);
Assert.equal(exampleOrg.origin, "http://example.org");
checkOriginAttributes(exampleOrg);
var exampleCom = ssm.createContentPrincipal(
{}
);
Assert.equal(exampleCom.origin, "https://www.example.com:123");
checkOriginAttributes(exampleCom);
var nullPrin = Cu.getObjectPrincipal(new Cu.Sandbox(null));
Assert.ok(
/^moz-nullprincipal:\{([0-9]|[a-z]|\-){36}\}$/.test(nullPrin.origin)
);
checkOriginAttributes(nullPrin);
var ipv6Prin = ssm.createContentPrincipal(
{}
);
Assert.equal(ipv6Prin.origin, "https://[2001:db8::ff00:42:8329]:123");
checkOriginAttributes(ipv6Prin);
var ipv6NPPrin = ssm.createContentPrincipal(
{}
);
Assert.equal(ipv6NPPrin.origin, "https://[2001:db8::ff00:42:8329]");
checkOriginAttributes(ipv6NPPrin);
var ep = Cu.getObjectPrincipal(
Cu.Sandbox([exampleCom, nullPrin, exampleOrg])
);
checkOriginAttributes(ep);
checkCrossOrigin(exampleCom, exampleOrg);
checkCrossOrigin(exampleOrg, nullPrin);
// nsEP origins should be in lexical order.
Assert.equal(
ep.origin,
`[Expanded Principal [${exampleCom.origin}, ${nullPrin.origin}, ${exampleOrg.origin}]]`
);
// Make sure createContentPrincipal does what the rest of gecko does.
Assert.ok(
exampleOrg.equals(
Cu.getObjectPrincipal(new Cu.Sandbox("http://example.org"))
)
);
//
// Test origin attributes.
//
// First party Uri
var exampleOrg_firstPartyDomain = ssm.createContentPrincipal(
makeURI("http://example.org"),
{ firstPartyDomain: "example.org" }
);
checkOriginAttributes(
exampleOrg_firstPartyDomain,
{ firstPartyDomain: "example.org" },
"^firstPartyDomain=example.org"
);
Assert.equal(
exampleOrg_firstPartyDomain.origin,
);
// Just userContext.
var exampleOrg_userContext = ssm.createContentPrincipal(
makeURI("http://example.org"),
{ userContextId: 42 }
);
checkOriginAttributes(
exampleOrg_userContext,
{ userContextId: 42 },
"^userContextId=42"
);
Assert.equal(
exampleOrg_userContext.origin,
);
checkSandboxOriginAttributes(null, {});
checkSandboxOriginAttributes("http://example.org", {});
checkSandboxOriginAttributes(
{},
{ originAttributes: {} }
);
checkSandboxOriginAttributes(["http://example.org"], {});
checkSandboxOriginAttributes(
{},
{ originAttributes: {} }
);
// Check that all of the above are cross-origin.
checkCrossOrigin(exampleOrg_firstPartyDomain, exampleOrg);
checkCrossOrigin(exampleOrg_userContext, exampleOrg);
// Check Principal kinds.
function checkKind(prin, kind) {
Assert.equal(prin.isNullPrincipal, kind == "nullPrincipal");
Assert.equal(prin.isContentPrincipal, kind == "contentPrincipal");
Assert.equal(prin.isExpandedPrincipal, kind == "expandedPrincipal");
Assert.equal(prin.isSystemPrincipal, kind == "systemPrincipal");
}
checkKind(ssm.createNullPrincipal({}), "nullPrincipal");
checkKind(
ssm.createContentPrincipal(makeURI("http://www.example.com"), {}),
"contentPrincipal"
);
checkKind(
Cu.getObjectPrincipal(
Cu.Sandbox([
ssm.createContentPrincipal(makeURI("http://www.example.com"), {}),
])
),
"expandedPrincipal"
);
checkKind(ssm.getSystemPrincipal(), "systemPrincipal");
//
// Test Origin Attribute Manipulation
//
// check that we can create an empty origin attributes dict with default
// members and values.
var emptyAttrs = ChromeUtils.fillNonDefaultOriginAttributes({});
checkValues(emptyAttrs);
var uri = "http://example.org";
var tests = [
["", {}],
["^userContextId=3", { userContextId: 3 }],
["^firstPartyDomain=example.org", { firstPartyDomain: "example.org" }],
];
// check that we can create an origin attributes from an origin properly
tests.forEach(t => {
let attrs = ChromeUtils.createOriginAttributesFromOrigin(uri + t[0]);
checkValues(attrs, t[1]);
Assert.equal(ChromeUtils.originAttributesToSuffix(attrs), t[0]);
});
// check that we can create an origin attributes from a dict properly
tests.forEach(t => {
let attrs = ChromeUtils.fillNonDefaultOriginAttributes(t[1]);
checkValues(attrs, t[1]);
Assert.equal(ChromeUtils.originAttributesToSuffix(attrs), t[0]);
});
// each row in the dflt_tests array has these values:
// [0] - the suffix used to create an origin attribute from
// [1] - the expected result of creating an origin attributes from [0]
// [2] - the expected result after setting userContextId to the default
// [3] - the expected result of creating a suffix from [2]
var dflt_tests = [
["", {}, {}, ""],
["^userContextId=3", { userContextId: 3 }, {}, ""],
];
// check that we can set the userContextId to default properly
dflt_tests.forEach(t => {
let orig = ChromeUtils.createOriginAttributesFromOrigin(uri + t[0]);
checkValues(orig, t[1]);
let mod = orig;
mod.userContextId = 0;
checkValues(mod, t[2]);
Assert.equal(ChromeUtils.originAttributesToSuffix(mod), t[3]);
});
// each row in the dflt2_tests array has these values:
// [0] - the suffix used to create an origin attribute from
// [1] - the expected result of creating an origin attributes from [0]
// [2] - the expected result after setting firstPartyUri to the default
// [3] - the expected result of creating a suffix from [2]
var dflt2_tests = [
["", {}, {}, ""],
["^firstPartyDomain=foo.com", { firstPartyDomain: "foo.com" }, {}, ""],
];
// check that we can set the userContextId to default properly
dflt2_tests.forEach(t => {
let orig = ChromeUtils.createOriginAttributesFromOrigin(uri + t[0]);
checkValues(orig, t[1]);
let mod = orig;
mod.firstPartyDomain = "";
checkValues(mod, t[2]);
Assert.equal(ChromeUtils.originAttributesToSuffix(mod), t[3]);
});
var fileURI = makeURI("file:///foo/bar").QueryInterface(Ci.nsIFileURL);
var fileTests = [
[true, fileURI.spec],
];
fileTests.forEach(t => {
Services.prefs.setBoolPref("security.fileuri.strict_origin_policy", t[0]);
var filePrin = ssm.createContentPrincipal(fileURI, {});
Assert.equal(filePrin.origin, t[1]);
});
Services.prefs.clearUserPref("security.fileuri.strict_origin_policy");
var aboutBlankURI = makeURI("about:blank");
var aboutBlankPrin = ssm.createContentPrincipal(aboutBlankURI, {});
Assert.ok(
/^moz-nullprincipal:\{([0-9]|[a-z]|\-){36}\}$/.test(aboutBlankPrin.origin)
);
}