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) {
27 Assert.equal(prin.originSuffix, suffix || "");
28 Assert.equal(ChromeUtils.originAttributesToSuffix(attrs), suffix || "");
30 ChromeUtils.originAttributesMatchPattern(prin.originAttributes, attrs)
32 if (!prin.isNullPrincipal && !prin.origin.startsWith("[")) {
33 Assert.ok(ssm.createContentPrincipalFromOrigin(prin.origin).equals(prin));
35 checkThrows(() => ssm.createContentPrincipalFromOrigin(prin.origin));
39 function checkSandboxOriginAttributes(arr, attrs, options) {
40 options = options || {};
41 var sandbox = Cu.Sandbox(arr, options);
42 checkOriginAttributes(
43 Cu.getObjectPrincipal(sandbox),
45 ChromeUtils.originAttributesToSuffix(attrs)
49 // utility function useful for debugging
50 // eslint-disable-next-line no-unused-vars
51 function printAttrs(name, attrs) {
58 "\tprivateBrowsingId: '" +
59 attrs.privateBrowsingId +
61 "\tfirstPartyDomain: '" +
62 attrs.firstPartyDomain +
67 function checkValues(attrs, values) {
68 values = values || {};
69 // printAttrs("attrs", attrs);
70 // printAttrs("values", values);
71 Assert.equal(attrs.userContextId, values.userContextId || 0);
72 Assert.equal(attrs.privateBrowsingId, values.privateBrowsingId || "");
73 Assert.equal(attrs.firstPartyDomain, values.firstPartyDomain || "");
77 // Attributeless origins.
78 Assert.equal(ssm.getSystemPrincipal().origin, "[System Principal]");
79 checkOriginAttributes(ssm.getSystemPrincipal());
80 var exampleOrg = ssm.createContentPrincipal(
81 makeURI("http://example.org"),
84 Assert.equal(exampleOrg.origin, "http://example.org");
85 checkOriginAttributes(exampleOrg);
86 var exampleCom = ssm.createContentPrincipal(
87 makeURI("https://www.example.com:123"),
90 Assert.equal(exampleCom.origin, "https://www.example.com:123");
91 checkOriginAttributes(exampleCom);
92 var nullPrin = Cu.getObjectPrincipal(new Cu.Sandbox(null));
94 /^moz-nullprincipal:\{([0-9]|[a-z]|\-){36}\}$/.test(nullPrin.origin)
96 checkOriginAttributes(nullPrin);
97 var ipv6Prin = ssm.createContentPrincipal(
98 makeURI("https://[2001:db8::ff00:42:8329]:123"),
101 Assert.equal(ipv6Prin.origin, "https://[2001:db8::ff00:42:8329]:123");
102 checkOriginAttributes(ipv6Prin);
103 var ipv6NPPrin = ssm.createContentPrincipal(
104 makeURI("https://[2001:db8::ff00:42:8329]"),
107 Assert.equal(ipv6NPPrin.origin, "https://[2001:db8::ff00:42:8329]");
108 checkOriginAttributes(ipv6NPPrin);
109 var ep = Cu.getObjectPrincipal(
110 Cu.Sandbox([exampleCom, nullPrin, exampleOrg])
112 checkOriginAttributes(ep);
113 checkCrossOrigin(exampleCom, exampleOrg);
114 checkCrossOrigin(exampleOrg, nullPrin);
116 // nsEP origins should be in lexical order.
119 `[Expanded Principal [${exampleCom.origin}, ${nullPrin.origin}, ${exampleOrg.origin}]]`
122 // Make sure createContentPrincipal does what the rest of gecko does.
125 Cu.getObjectPrincipal(new Cu.Sandbox("http://example.org"))
130 // Test origin attributes.
134 var exampleOrg_firstPartyDomain = ssm.createContentPrincipal(
135 makeURI("http://example.org"),
136 { firstPartyDomain: "example.org" }
138 checkOriginAttributes(
139 exampleOrg_firstPartyDomain,
140 { firstPartyDomain: "example.org" },
141 "^firstPartyDomain=example.org"
144 exampleOrg_firstPartyDomain.origin,
145 "http://example.org^firstPartyDomain=example.org"
149 var exampleOrg_userContext = ssm.createContentPrincipal(
150 makeURI("http://example.org"),
151 { userContextId: 42 }
153 checkOriginAttributes(
154 exampleOrg_userContext,
155 { userContextId: 42 },
159 exampleOrg_userContext.origin,
160 "http://example.org^userContextId=42"
163 checkSandboxOriginAttributes(null, {});
164 checkSandboxOriginAttributes("http://example.org", {});
165 checkSandboxOriginAttributes(
166 "http://example.org",
168 { originAttributes: {} }
170 checkSandboxOriginAttributes(["http://example.org"], {});
171 checkSandboxOriginAttributes(
172 ["http://example.org"],
174 { originAttributes: {} }
177 // Check that all of the above are cross-origin.
178 checkCrossOrigin(exampleOrg_firstPartyDomain, exampleOrg);
179 checkCrossOrigin(exampleOrg_userContext, exampleOrg);
181 // Check Principal kinds.
182 function checkKind(prin, kind) {
183 Assert.equal(prin.isNullPrincipal, kind == "nullPrincipal");
184 Assert.equal(prin.isContentPrincipal, kind == "contentPrincipal");
185 Assert.equal(prin.isExpandedPrincipal, kind == "expandedPrincipal");
186 Assert.equal(prin.isSystemPrincipal, kind == "systemPrincipal");
188 checkKind(ssm.createNullPrincipal({}), "nullPrincipal");
190 ssm.createContentPrincipal(makeURI("http://www.example.com"), {}),
194 Cu.getObjectPrincipal(
196 ssm.createContentPrincipal(makeURI("http://www.example.com"), {}),
201 checkKind(ssm.getSystemPrincipal(), "systemPrincipal");
204 // Test Origin Attribute Manipulation
207 // check that we can create an empty origin attributes dict with default
208 // members and values.
209 var emptyAttrs = ChromeUtils.fillNonDefaultOriginAttributes({});
210 checkValues(emptyAttrs);
212 var uri = "http://example.org";
215 ["^userContextId=3", { userContextId: 3 }],
216 ["^firstPartyDomain=example.org", { firstPartyDomain: "example.org" }],
219 // check that we can create an origin attributes from an origin properly
221 let attrs = ChromeUtils.createOriginAttributesFromOrigin(uri + t[0]);
222 checkValues(attrs, t[1]);
223 Assert.equal(ChromeUtils.originAttributesToSuffix(attrs), t[0]);
226 // check that we can create an origin attributes from a dict properly
228 let attrs = ChromeUtils.fillNonDefaultOriginAttributes(t[1]);
229 checkValues(attrs, t[1]);
230 Assert.equal(ChromeUtils.originAttributesToSuffix(attrs), t[0]);
233 // each row in the dflt_tests array has these values:
234 // [0] - the suffix used to create an origin attribute from
235 // [1] - the expected result of creating an origin attributes from [0]
236 // [2] - the expected result after setting userContextId to the default
237 // [3] - the expected result of creating a suffix from [2]
240 ["^userContextId=3", { userContextId: 3 }, {}, ""],
243 // check that we can set the userContextId to default properly
244 dflt_tests.forEach(t => {
245 let orig = ChromeUtils.createOriginAttributesFromOrigin(uri + t[0]);
246 checkValues(orig, t[1]);
248 mod.userContextId = 0;
249 checkValues(mod, t[2]);
250 Assert.equal(ChromeUtils.originAttributesToSuffix(mod), t[3]);
253 // each row in the dflt2_tests array has these values:
254 // [0] - the suffix used to create an origin attribute from
255 // [1] - the expected result of creating an origin attributes from [0]
256 // [2] - the expected result after setting firstPartyUri to the default
257 // [3] - the expected result of creating a suffix from [2]
260 ["^firstPartyDomain=foo.com", { firstPartyDomain: "foo.com" }, {}, ""],
263 // check that we can set the userContextId to default properly
264 dflt2_tests.forEach(t => {
265 let orig = ChromeUtils.createOriginAttributesFromOrigin(uri + t[0]);
266 checkValues(orig, t[1]);
268 mod.firstPartyDomain = "";
269 checkValues(mod, t[2]);
270 Assert.equal(ChromeUtils.originAttributesToSuffix(mod), t[3]);
273 var fileURI = makeURI("file:///foo/bar").QueryInterface(Ci.nsIFileURL);
275 [true, fileURI.spec],
276 [false, "file://UNIVERSAL_FILE_URI_ORIGIN"],
278 fileTests.forEach(t => {
279 Services.prefs.setBoolPref("security.fileuri.strict_origin_policy", t[0]);
280 var filePrin = ssm.createContentPrincipal(fileURI, {});
281 Assert.equal(filePrin.origin, t[1]);
283 Services.prefs.clearUserPref("security.fileuri.strict_origin_policy");
285 var aboutBlankURI = makeURI("about:blank");
286 var aboutBlankPrin = ssm.createContentPrincipal(aboutBlankURI, {});
288 /^moz-nullprincipal:\{([0-9]|[a-z]|\-){36}\}$/.test(aboutBlankPrin.origin)