test_origin.js (9097B)
1 var ssm = Services.scriptSecurityManager; 2 function makeURI(uri) { 3 return Services.io.newURI(uri); 4 } 5 6 function checkThrows(f) { 7 var threw = false; 8 try { 9 f(); 10 } catch (e) { 11 threw = true; 12 } 13 Assert.ok(threw); 14 } 15 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)); 23 } 24 25 function checkOriginAttributes(prin, attrs, suffix) { 26 attrs = attrs || {}; 27 Assert.equal(prin.originSuffix, suffix || ""); 28 Assert.equal(ChromeUtils.originAttributesToSuffix(attrs), suffix || ""); 29 Assert.ok( 30 ChromeUtils.originAttributesMatchPattern(prin.originAttributes, attrs) 31 ); 32 if (!prin.isNullPrincipal && !prin.origin.startsWith("[")) { 33 Assert.ok(ssm.createContentPrincipalFromOrigin(prin.origin).equals(prin)); 34 } else { 35 checkThrows(() => ssm.createContentPrincipalFromOrigin(prin.origin)); 36 } 37 } 38 39 function checkSandboxOriginAttributes(arr, attrs, options) { 40 options = options || {}; 41 var sandbox = Cu.Sandbox(arr, options); 42 checkOriginAttributes( 43 Cu.getObjectPrincipal(sandbox), 44 attrs, 45 ChromeUtils.originAttributesToSuffix(attrs) 46 ); 47 } 48 49 // utility function useful for debugging 50 // eslint-disable-next-line no-unused-vars 51 function printAttrs(name, attrs) { 52 info( 53 name + 54 " {\n" + 55 "\tuserContextId: " + 56 attrs.userContextId + 57 ",\n" + 58 "\tprivateBrowsingId: '" + 59 attrs.privateBrowsingId + 60 "',\n" + 61 "\tfirstPartyDomain: '" + 62 attrs.firstPartyDomain + 63 "'\n}" 64 ); 65 } 66 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 || ""); 74 } 75 76 function run_test() { 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"), 82 {} 83 ); 84 Assert.equal(exampleOrg.origin, "http://example.org"); 85 checkOriginAttributes(exampleOrg); 86 var exampleCom = ssm.createContentPrincipal( 87 makeURI("https://www.example.com:123"), 88 {} 89 ); 90 Assert.equal(exampleCom.origin, "https://www.example.com:123"); 91 checkOriginAttributes(exampleCom); 92 var nullPrin = Cu.getObjectPrincipal(new Cu.Sandbox(null)); 93 Assert.ok( 94 /^moz-nullprincipal:\{([0-9]|[a-z]|\-){36}\}$/.test(nullPrin.origin) 95 ); 96 checkOriginAttributes(nullPrin); 97 var ipv6Prin = ssm.createContentPrincipal( 98 makeURI("https://[2001:db8::ff00:42:8329]:123"), 99 {} 100 ); 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]"), 105 {} 106 ); 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]) 111 ); 112 checkOriginAttributes(ep); 113 checkCrossOrigin(exampleCom, exampleOrg); 114 checkCrossOrigin(exampleOrg, nullPrin); 115 116 // nsEP origins should be in lexical order. 117 Assert.equal( 118 ep.origin, 119 `[Expanded Principal [${exampleCom.origin}, ${nullPrin.origin}, ${exampleOrg.origin}]]` 120 ); 121 122 // Make sure createContentPrincipal does what the rest of gecko does. 123 Assert.ok( 124 exampleOrg.equals( 125 Cu.getObjectPrincipal(new Cu.Sandbox("http://example.org")) 126 ) 127 ); 128 129 // 130 // Test origin attributes. 131 // 132 133 // First party Uri 134 var exampleOrg_firstPartyDomain = ssm.createContentPrincipal( 135 makeURI("http://example.org"), 136 { firstPartyDomain: "example.org" } 137 ); 138 checkOriginAttributes( 139 exampleOrg_firstPartyDomain, 140 { firstPartyDomain: "example.org" }, 141 "^firstPartyDomain=example.org" 142 ); 143 Assert.equal( 144 exampleOrg_firstPartyDomain.origin, 145 "http://example.org^firstPartyDomain=example.org" 146 ); 147 148 // Just userContext. 149 var exampleOrg_userContext = ssm.createContentPrincipal( 150 makeURI("http://example.org"), 151 { userContextId: 42 } 152 ); 153 checkOriginAttributes( 154 exampleOrg_userContext, 155 { userContextId: 42 }, 156 "^userContextId=42" 157 ); 158 Assert.equal( 159 exampleOrg_userContext.origin, 160 "http://example.org^userContextId=42" 161 ); 162 163 checkSandboxOriginAttributes(null, {}); 164 checkSandboxOriginAttributes("http://example.org", {}); 165 checkSandboxOriginAttributes( 166 "http://example.org", 167 {}, 168 { originAttributes: {} } 169 ); 170 checkSandboxOriginAttributes(["http://example.org"], {}); 171 checkSandboxOriginAttributes( 172 ["http://example.org"], 173 {}, 174 { originAttributes: {} } 175 ); 176 177 // Check that all of the above are cross-origin. 178 checkCrossOrigin(exampleOrg_firstPartyDomain, exampleOrg); 179 checkCrossOrigin(exampleOrg_userContext, exampleOrg); 180 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"); 187 } 188 checkKind(ssm.createNullPrincipal({}), "nullPrincipal"); 189 checkKind( 190 ssm.createContentPrincipal(makeURI("http://www.example.com"), {}), 191 "contentPrincipal" 192 ); 193 checkKind( 194 Cu.getObjectPrincipal( 195 Cu.Sandbox([ 196 ssm.createContentPrincipal(makeURI("http://www.example.com"), {}), 197 ]) 198 ), 199 "expandedPrincipal" 200 ); 201 checkKind(ssm.getSystemPrincipal(), "systemPrincipal"); 202 203 // 204 // Test Origin Attribute Manipulation 205 // 206 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); 211 212 var uri = "http://example.org"; 213 var tests = [ 214 ["", {}], 215 ["^userContextId=3", { userContextId: 3 }], 216 ["^firstPartyDomain=example.org", { firstPartyDomain: "example.org" }], 217 ]; 218 219 // check that we can create an origin attributes from an origin properly 220 tests.forEach(t => { 221 let attrs = ChromeUtils.createOriginAttributesFromOrigin(uri + t[0]); 222 checkValues(attrs, t[1]); 223 Assert.equal(ChromeUtils.originAttributesToSuffix(attrs), t[0]); 224 }); 225 226 // check that we can create an origin attributes from a dict properly 227 tests.forEach(t => { 228 let attrs = ChromeUtils.fillNonDefaultOriginAttributes(t[1]); 229 checkValues(attrs, t[1]); 230 Assert.equal(ChromeUtils.originAttributesToSuffix(attrs), t[0]); 231 }); 232 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] 238 var dflt_tests = [ 239 ["", {}, {}, ""], 240 ["^userContextId=3", { userContextId: 3 }, {}, ""], 241 ]; 242 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]); 247 let mod = orig; 248 mod.userContextId = 0; 249 checkValues(mod, t[2]); 250 Assert.equal(ChromeUtils.originAttributesToSuffix(mod), t[3]); 251 }); 252 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] 258 var dflt2_tests = [ 259 ["", {}, {}, ""], 260 ["^firstPartyDomain=foo.com", { firstPartyDomain: "foo.com" }, {}, ""], 261 ]; 262 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]); 267 let mod = orig; 268 mod.firstPartyDomain = ""; 269 checkValues(mod, t[2]); 270 Assert.equal(ChromeUtils.originAttributesToSuffix(mod), t[3]); 271 }); 272 273 var fileURI = makeURI("file:///foo/bar").QueryInterface(Ci.nsIFileURL); 274 var fileTests = [ 275 [true, fileURI.spec], 276 [false, "file://UNIVERSAL_FILE_URI_ORIGIN"], 277 ]; 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]); 282 }); 283 Services.prefs.clearUserPref("security.fileuri.strict_origin_policy"); 284 285 var aboutBlankURI = makeURI("about:blank"); 286 var aboutBlankPrin = ssm.createContentPrincipal(aboutBlankURI, {}); 287 Assert.ok( 288 /^moz-nullprincipal:\{([0-9]|[a-z]|\-){36}\}$/.test(aboutBlankPrin.origin) 289 ); 290 }