1 var ssm = Services.scriptSecurityManager;
2 function makeURI(uri) {
3 return Services.io.newURI(uri);
6 function checkThrows(f) {
16 function checkCrossOrigin(a, b) {
17 Assert.ok(!a.equals(b));
18 Assert.ok(!a.equalsConsideringDomain(b));
19 Assert.ok(!a.subsumes(b));
20 Assert.ok(!a.subsumesConsideringDomain(b));
21 Assert.ok(!b.subsumes(a));
22 Assert.ok(!b.subsumesConsideringDomain(a));
25 function checkOriginAttributes(prin, attrs, suffix) {
28 prin.originAttributes.inIsolatedMozBrowser,
29 attrs.inIsolatedMozBrowser || false
31 Assert.equal(prin.originSuffix, suffix || "");
32 Assert.equal(ChromeUtils.originAttributesToSuffix(attrs), suffix || "");
34 ChromeUtils.originAttributesMatchPattern(prin.originAttributes, attrs)
36 if (!prin.isNullPrincipal && !prin.origin.startsWith("[")) {
37 Assert.ok(ssm.createContentPrincipalFromOrigin(prin.origin).equals(prin));
39 checkThrows(() => ssm.createContentPrincipalFromOrigin(prin.origin));
43 function checkSandboxOriginAttributes(arr, attrs, options) {
44 options = options || {};
45 var sandbox = Cu.Sandbox(arr, options);
46 checkOriginAttributes(
47 Cu.getObjectPrincipal(sandbox),
49 ChromeUtils.originAttributesToSuffix(attrs)
53 // utility function useful for debugging
54 // eslint-disable-next-line no-unused-vars
55 function printAttrs(name, attrs) {
62 "\tinIsolatedMozBrowser: " +
63 attrs.inIsolatedMozBrowser +
65 "\tprivateBrowsingId: '" +
66 attrs.privateBrowsingId +
68 "\tfirstPartyDomain: '" +
69 attrs.firstPartyDomain +
74 function checkValues(attrs, values) {
75 values = values || {};
76 // printAttrs("attrs", attrs);
77 // printAttrs("values", values);
78 Assert.equal(attrs.userContextId, values.userContextId || 0);
80 attrs.inIsolatedMozBrowser,
81 values.inIsolatedMozBrowser || false
83 Assert.equal(attrs.privateBrowsingId, values.privateBrowsingId || "");
84 Assert.equal(attrs.firstPartyDomain, values.firstPartyDomain || "");
88 // Attributeless origins.
89 Assert.equal(ssm.getSystemPrincipal().origin, "[System Principal]");
90 checkOriginAttributes(ssm.getSystemPrincipal());
91 var exampleOrg = ssm.createContentPrincipal(
92 makeURI("http://example.org"),
95 Assert.equal(exampleOrg.origin, "http://example.org");
96 checkOriginAttributes(exampleOrg);
97 var exampleCom = ssm.createContentPrincipal(
98 makeURI("https://www.example.com:123"),
101 Assert.equal(exampleCom.origin, "https://www.example.com:123");
102 checkOriginAttributes(exampleCom);
103 var nullPrin = Cu.getObjectPrincipal(new Cu.Sandbox(null));
105 /^moz-nullprincipal:\{([0-9]|[a-z]|\-){36}\}$/.test(nullPrin.origin)
107 checkOriginAttributes(nullPrin);
108 var ipv6Prin = ssm.createContentPrincipal(
109 makeURI("https://[2001:db8::ff00:42:8329]:123"),
112 Assert.equal(ipv6Prin.origin, "https://[2001:db8::ff00:42:8329]:123");
113 checkOriginAttributes(ipv6Prin);
114 var ipv6NPPrin = ssm.createContentPrincipal(
115 makeURI("https://[2001:db8::ff00:42:8329]"),
118 Assert.equal(ipv6NPPrin.origin, "https://[2001:db8::ff00:42:8329]");
119 checkOriginAttributes(ipv6NPPrin);
120 var ep = Cu.getObjectPrincipal(
121 Cu.Sandbox([exampleCom, nullPrin, exampleOrg])
123 checkOriginAttributes(ep);
124 checkCrossOrigin(exampleCom, exampleOrg);
125 checkCrossOrigin(exampleOrg, nullPrin);
127 // nsEP origins should be in lexical order.
130 `[Expanded Principal [${exampleCom.origin}, ${nullPrin.origin}, ${exampleOrg.origin}]]`
133 // Make sure createContentPrincipal does what the rest of gecko does.
136 Cu.getObjectPrincipal(new Cu.Sandbox("http://example.org"))
141 // Test origin attributes.
145 var exampleOrg_browser = ssm.createContentPrincipal(
146 makeURI("http://example.org"),
147 { inIsolatedMozBrowser: true }
149 var nullPrin_browser = ssm.createNullPrincipal({
150 inIsolatedMozBrowser: true,
152 checkOriginAttributes(
154 { inIsolatedMozBrowser: true },
157 checkOriginAttributes(
159 { inIsolatedMozBrowser: true },
162 Assert.equal(exampleOrg_browser.origin, "http://example.org^inBrowser=1");
165 var exampleOrg_firstPartyDomain = ssm.createContentPrincipal(
166 makeURI("http://example.org"),
167 { firstPartyDomain: "example.org" }
169 checkOriginAttributes(
170 exampleOrg_firstPartyDomain,
171 { firstPartyDomain: "example.org" },
172 "^firstPartyDomain=example.org"
175 exampleOrg_firstPartyDomain.origin,
176 "http://example.org^firstPartyDomain=example.org"
180 var exampleOrg_userContext = ssm.createContentPrincipal(
181 makeURI("http://example.org"),
182 { userContextId: 42 }
184 checkOriginAttributes(
185 exampleOrg_userContext,
186 { userContextId: 42 },
190 exampleOrg_userContext.origin,
191 "http://example.org^userContextId=42"
194 checkSandboxOriginAttributes(null, {});
195 checkSandboxOriginAttributes("http://example.org", {});
196 checkSandboxOriginAttributes(
197 "http://example.org",
199 { originAttributes: {} }
201 checkSandboxOriginAttributes(["http://example.org"], {});
202 checkSandboxOriginAttributes(
203 ["http://example.org"],
205 { originAttributes: {} }
208 // Check that all of the above are cross-origin.
209 checkCrossOrigin(exampleOrg_browser, nullPrin_browser);
210 checkCrossOrigin(exampleOrg_firstPartyDomain, exampleOrg);
211 checkCrossOrigin(exampleOrg_userContext, exampleOrg);
213 // Check Principal kinds.
214 function checkKind(prin, kind) {
215 Assert.equal(prin.isNullPrincipal, kind == "nullPrincipal");
216 Assert.equal(prin.isContentPrincipal, kind == "contentPrincipal");
217 Assert.equal(prin.isExpandedPrincipal, kind == "expandedPrincipal");
218 Assert.equal(prin.isSystemPrincipal, kind == "systemPrincipal");
220 checkKind(ssm.createNullPrincipal({}), "nullPrincipal");
222 ssm.createContentPrincipal(makeURI("http://www.example.com"), {}),
226 Cu.getObjectPrincipal(
228 ssm.createContentPrincipal(makeURI("http://www.example.com"), {}),
233 checkKind(ssm.getSystemPrincipal(), "systemPrincipal");
236 // Test Origin Attribute Manipulation
239 // check that we can create an empty origin attributes dict with default
240 // members and values.
241 var emptyAttrs = ChromeUtils.fillNonDefaultOriginAttributes({});
242 checkValues(emptyAttrs);
244 var uri = "http://example.org";
247 ["^userContextId=3", { userContextId: 3 }],
248 ["^inBrowser=1", { inIsolatedMozBrowser: true }],
249 ["^firstPartyDomain=example.org", { firstPartyDomain: "example.org" }],
252 // check that we can create an origin attributes from an origin properly
254 let attrs = ChromeUtils.createOriginAttributesFromOrigin(uri + t[0]);
255 checkValues(attrs, t[1]);
256 Assert.equal(ChromeUtils.originAttributesToSuffix(attrs), t[0]);
259 // check that we can create an origin attributes from a dict properly
261 let attrs = ChromeUtils.fillNonDefaultOriginAttributes(t[1]);
262 checkValues(attrs, t[1]);
263 Assert.equal(ChromeUtils.originAttributesToSuffix(attrs), t[0]);
266 // each row in the dflt_tests array has these values:
267 // [0] - the suffix used to create an origin attribute from
268 // [1] - the expected result of creating an origin attributes from [0]
269 // [2] - the expected result after setting userContextId to the default
270 // [3] - the expected result of creating a suffix from [2]
273 ["^userContextId=3", { userContextId: 3 }, {}, ""],
276 // check that we can set the userContextId to default properly
277 dflt_tests.forEach(t => {
278 let orig = ChromeUtils.createOriginAttributesFromOrigin(uri + t[0]);
279 checkValues(orig, t[1]);
281 mod.userContextId = 0;
282 checkValues(mod, t[2]);
283 Assert.equal(ChromeUtils.originAttributesToSuffix(mod), t[3]);
286 // each row in the dflt2_tests array has these values:
287 // [0] - the suffix used to create an origin attribute from
288 // [1] - the expected result of creating an origin attributes from [0]
289 // [2] - the expected result after setting firstPartyUri to the default
290 // [3] - the expected result of creating a suffix from [2]
293 ["^firstPartyDomain=foo.com", { firstPartyDomain: "foo.com" }, {}, ""],
296 // check that we can set the userContextId to default properly
297 dflt2_tests.forEach(t => {
298 let orig = ChromeUtils.createOriginAttributesFromOrigin(uri + t[0]);
299 checkValues(orig, t[1]);
301 mod.firstPartyDomain = "";
302 checkValues(mod, t[2]);
303 Assert.equal(ChromeUtils.originAttributesToSuffix(mod), t[3]);
306 var fileURI = makeURI("file:///foo/bar").QueryInterface(Ci.nsIFileURL);
308 [true, fileURI.spec],
309 [false, "file://UNIVERSAL_FILE_URI_ORIGIN"],
311 fileTests.forEach(t => {
312 Services.prefs.setBoolPref("security.fileuri.strict_origin_policy", t[0]);
313 var filePrin = ssm.createContentPrincipal(fileURI, {});
314 Assert.equal(filePrin.origin, t[1]);
316 Services.prefs.clearUserPref("security.fileuri.strict_origin_policy");
318 var aboutBlankURI = makeURI("about:blank");
319 var aboutBlankPrin = ssm.createContentPrincipal(aboutBlankURI, {});
321 /^moz-nullprincipal:\{([0-9]|[a-z]|\-){36}\}$/.test(aboutBlankPrin.origin)