cross-origin.https.window.js (21972B)
1 // META: script=/resources/testdriver.js 2 // META: script=/resources/testdriver-vendor.js 3 // META: script=/common/utils.js 4 // META: script=/common/subset-tests.js 5 // META: script=resources/fledge-util.sub.js 6 // META: timeout=long 7 // META: variant=?1-4 8 // META: variant=?5-8 9 // META: variant=?9-12 10 // META: variant=?13-last 11 12 "use strict"; 13 14 //////////////////////////////////////////////////////////////////////////////// 15 // Join interest group in iframe tests. 16 //////////////////////////////////////////////////////////////////////////////// 17 18 subsetTest(promise_test, async test => { 19 const uuid = generateUuid(test); 20 let iframe = await createIframe(test, document.location.origin); 21 22 // Join a same-origin InterestGroup in a iframe navigated to its origin. 23 await runInFrame(test, iframe, `await joinInterestGroup(test_instance, "${uuid}");`); 24 25 // Run an auction using window.location.origin as a bidder. The IG should 26 // make a bid and win an auction. 27 await runBasicFledgeTestExpectingWinner(test, uuid); 28 }, 'Join interest group in same-origin iframe, default permissions.'); 29 30 subsetTest(promise_test, async test => { 31 const uuid = generateUuid(test); 32 let iframe = await createIframe(test, OTHER_ORIGIN1); 33 34 // Join a cross-origin InterestGroup in a iframe navigated to its origin. 35 await runInFrame(test, iframe, `await joinInterestGroup(test_instance, "${uuid}");`); 36 37 // Run an auction in this frame using the other origin as a bidder. The IG should 38 // make a bid and win an auction. 39 // 40 // TODO: Once the permission defaults to not being able to join InterestGroups in 41 // cross-origin iframes, this auction should have no winner. 42 await runBasicFledgeTestExpectingWinner( 43 test, uuid, 44 { interestGroupBuyers: [OTHER_ORIGIN1], 45 scoreAd: `if (browserSignals.interestGroupOwner !== "${OTHER_ORIGIN1}") 46 throw "Wrong owner: " + browserSignals.interestGroupOwner` 47 }); 48 }, 'Join interest group in cross-origin iframe, default permissions.'); 49 50 subsetTest(promise_test, async test => { 51 const uuid = generateUuid(test); 52 let iframe = await createIframe(test, OTHER_ORIGIN1, 'join-ad-interest-group'); 53 54 // Join a cross-origin InterestGroup in a iframe navigated to its origin. 55 await runInFrame(test, iframe, `await joinInterestGroup(test_instance, "${uuid}");`); 56 57 // Run an auction in this frame using the other origin as a bidder. The IG should 58 // make a bid and win an auction. 59 await runBasicFledgeTestExpectingWinner( 60 test, uuid, 61 { interestGroupBuyers: [OTHER_ORIGIN1], 62 scoreAd: `if (browserSignals.interestGroupOwner !== "${OTHER_ORIGIN1}") 63 throw "Wrong owner: " + browserSignals.interestGroupOwner` 64 }); 65 }, 'Join interest group in cross-origin iframe with join-ad-interest-group permission.'); 66 67 subsetTest(promise_test, async test => { 68 const uuid = generateUuid(test); 69 let iframe = await createIframe(test, OTHER_ORIGIN1, "join-ad-interest-group 'none'"); 70 71 // Try to join an InterestGroup in a cross-origin iframe whose permissions policy 72 // blocks joining interest groups. An exception should be thrown, and the interest 73 // group should not be joined. 74 await runInFrame(test, iframe, 75 `try { 76 await joinInterestGroup(test_instance, "${uuid}"); 77 } catch (e) { 78 assert_true(e instanceof DOMException, "DOMException thrown"); 79 assert_equals(e.name, "NotAllowedError", "NotAllowedError DOMException thrown"); 80 return {result: "success"}; 81 } 82 return "exception unexpectedly not thrown";`); 83 84 // Run an auction in this frame using the other origin as a bidder. Since the join 85 // should have failed, the auction should have no winner. 86 await runBasicFledgeTestExpectingNoWinner( 87 test, uuid, 88 { interestGroupBuyers: [OTHER_ORIGIN1] }); 89 }, 'Join interest group in cross-origin iframe with join-ad-interest-group permission denied.'); 90 91 subsetTest(promise_test, async test => { 92 const uuid = generateUuid(test); 93 let iframe = await createIframe(test, OTHER_ORIGIN1, 'join-ad-interest-group'); 94 95 // Try to join an IG with the parent's origin as an owner in a cross-origin iframe. 96 // This should require a .well-known fetch to the parents origin, which will not 97 // grant permission. The case where permission is granted is not yet testable. 98 let interestGroup = JSON.stringify(createInterestGroupForOrigin(uuid, window.location.origin)); 99 await runInFrame(test, iframe, 100 `try { 101 await joinInterestGroup(test_instance, "${uuid}", ${interestGroup}); 102 } catch (e) { 103 assert_true(e instanceof DOMException, "DOMException thrown"); 104 assert_equals(e.name, "NotAllowedError", "NotAllowedError DOMException thrown"); 105 return {result: "success"}; 106 } 107 return "exception unexpectedly not thrown";`); 108 109 // Run an auction with this page's origin as a bidder. Since the join 110 // should have failed, the auction should have no winner. 111 await runBasicFledgeTestExpectingNoWinner(test, uuid); 112 }, "Join interest group owned by parent's origin in cross-origin iframe."); 113 114 //////////////////////////////////////////////////////////////////////////////// 115 // Run auction in iframe tests. 116 //////////////////////////////////////////////////////////////////////////////// 117 118 subsetTest(promise_test, async test => { 119 const uuid = generateUuid(test); 120 await joinInterestGroup(test, uuid); 121 122 let iframe = await createIframe(test, document.location.origin); 123 124 // Join a same-origin InterestGroup in a iframe navigated to its origin. 125 await runInFrame(test, iframe, `await joinInterestGroup(test_instance, "${uuid}");`); 126 127 // Run auction in same-origin iframe. This should succeed, by default. 128 await runInFrame( 129 test, iframe, 130 `await runBasicFledgeTestExpectingWinner(test_instance, "${uuid}");`); 131 }, 'Run auction in same-origin iframe, default permissions.'); 132 133 subsetTest(promise_test, async test => { 134 const uuid = generateUuid(test); 135 // Join an interest group owned by the main frame's origin. 136 await joinInterestGroup(test, uuid); 137 138 let iframe = await createIframe(test, OTHER_ORIGIN1); 139 140 // Run auction in cross-origin iframe. Currently, this is allowed by default. 141 await runInFrame( 142 test, iframe, 143 `await runBasicFledgeTestExpectingWinner( 144 test_instance, "${uuid}", 145 {interestGroupBuyers: ["${window.location.origin}"]});`); 146 }, 'Run auction in cross-origin iframe, default permissions.'); 147 148 subsetTest(promise_test, async test => { 149 const uuid = generateUuid(test); 150 // Join an interest group owned by the main frame's origin. 151 await joinInterestGroup(test, uuid); 152 153 let iframe = await createIframe(test, OTHER_ORIGIN1, "run-ad-auction"); 154 155 // Run auction in cross-origin iframe that should allow the auction to occur. 156 await runInFrame( 157 test, iframe, 158 `await runBasicFledgeTestExpectingWinner( 159 test_instance, "${uuid}", 160 {interestGroupBuyers: ["${window.location.origin}"]});`); 161 }, 'Run auction in cross-origin iframe with run-ad-auction permission.'); 162 163 subsetTest(promise_test, async test => { 164 const uuid = generateUuid(test); 165 // No need to join any interest groups in this case - running an auction 166 // should only throw an exception based on permissions policy, regardless 167 // of whether there are any interest groups can participate. 168 169 let iframe = await createIframe(test, OTHER_ORIGIN1, "run-ad-auction 'none'"); 170 171 // Run auction in cross-origin iframe that should not allow the auction to occur. 172 await runInFrame( 173 test, iframe, 174 `try { 175 await runBasicFledgeAuction(test_instance, "${uuid}"); 176 } catch (e) { 177 assert_true(e instanceof DOMException, "DOMException thrown"); 178 assert_equals(e.name, "NotAllowedError", "NotAllowedError DOMException thrown"); 179 return {result: "success"}; 180 } 181 throw "Attempting to run auction unexpectedly did not throw"`); 182 }, 'Run auction in cross-origin iframe with run-ad-auction permission denied.'); 183 184 subsetTest(promise_test, async test => { 185 const uuid = generateUuid(test); 186 // Join an interest group owned by the main frame's origin. 187 await joinInterestGroup(test, uuid); 188 189 let iframe = await createIframe(test, OTHER_ORIGIN1, `run-ad-auction ${OTHER_ORIGIN1}`); 190 191 await runInFrame( 192 test, iframe, 193 `await runBasicFledgeTestExpectingWinner( 194 test_instance, "${uuid}", 195 { interestGroupBuyers: ["${window.location.origin}"], 196 seller: "${OTHER_ORIGIN2}", 197 decisionLogicURL: createDecisionScriptURL("${uuid}", {origin: "${OTHER_ORIGIN2}"}) 198 });`); 199 }, 'Run auction in cross-origin iframe with run-ad-auction for iframe origin, which is different from seller origin.'); 200 201 //////////////////////////////////////////////////////////////////////////////// 202 // Navigate fenced frame iframe tests. 203 //////////////////////////////////////////////////////////////////////////////// 204 205 subsetTest(promise_test, async test => { 206 const uuid = generateUuid(test); 207 208 // Join an interest group and run an auction with a winner. 209 await joinInterestGroup(test, uuid); 210 let config = await runBasicFledgeTestExpectingWinner(test, uuid); 211 212 // Try to navigate a fenced frame to the winning ad in a cross-origin iframe 213 // with no fledge-related permissions. 214 let iframe = await createIframe( 215 test, OTHER_ORIGIN1, "join-ad-interest-group 'none'; run-ad-auction 'none'"); 216 await runInFrame( 217 test, iframe, 218 `await createAndNavigateFencedFrame(test_instance, param);`, 219 /*param=*/config); 220 await waitForObservedRequests( 221 uuid, [createBidderReportURL(uuid), createSellerReportURL(uuid)]); 222 }, 'Run auction main frame, open winning ad in cross-origin iframe.'); 223 224 subsetTest(promise_test, async test => { 225 const uuid = generateUuid(test); 226 227 let iframe = await createIframe( 228 test, OTHER_ORIGIN1, "join-ad-interest-group; run-ad-auction"); 229 await runInFrame( 230 test, iframe, 231 `await joinInterestGroup(test_instance, "${uuid}"); 232 await runBasicFledgeAuctionAndNavigate(test_instance, "${uuid}"); 233 await waitForObservedRequests( 234 "${uuid}", [createBidderReportURL("${uuid}"), createSellerReportURL("${uuid}")])`); 235 }, 'Run auction in cross-origin iframe and open winning ad in nested fenced frame.'); 236 237 subsetTest(promise_test, async test => { 238 const uuid = generateUuid(test); 239 240 // Run an auction in an cross-origin iframe, and get the resulting FencedFrameConfig. 241 let iframe = await createIframe( 242 test, OTHER_ORIGIN1, "join-ad-interest-group; run-ad-auction"); 243 let config = await runInFrame( 244 test, iframe, 245 `await joinInterestGroup(test_instance, "${uuid}"); 246 let config = await runBasicFledgeTestExpectingWinner(test_instance, "${uuid}"); 247 return {result: "success", returnValue: config};`); 248 assert_true(config != null, "Value not returned from auction in iframe"); 249 assert_true(config instanceof FencedFrameConfig, 250 `Wrong value type returned from auction: ${config.constructor.type}`); 251 252 // Loading the winning ad in a fenced frame that's a child of the main frame should 253 // succeed. 254 await createAndNavigateFencedFrame(test, config); 255 await waitForObservedRequests( 256 uuid, 257 [ createBidderReportURL(uuid, '1', OTHER_ORIGIN1), 258 createSellerReportURL(uuid, '1', OTHER_ORIGIN1)]); 259 }, 'Run auction in cross-origin iframe and open winning ad in a fenced frame child of the main frame.'); 260 261 subsetTest(promise_test, async test => { 262 const uuid = generateUuid(test); 263 264 // Run an auction in an cross-origin iframe, and get the resulting FencedFrameConfig. 265 let iframe = await createIframe( 266 test, OTHER_ORIGIN1, "join-ad-interest-group; run-ad-auction"); 267 let config = await runInFrame( 268 test, iframe, 269 `await joinInterestGroup(test_instance, "${uuid}"); 270 let config = await runBasicFledgeTestExpectingWinner(test_instance, "${uuid}"); 271 return {result: "success", returnValue: config};`); 272 assert_true(config != null, "Value not returned from auction in iframe"); 273 assert_true(config instanceof FencedFrameConfig, 274 `Wrong value type returned from auction: ${config.constructor.type}`); 275 276 // Try to navigate a fenced frame to the winning ad in a cross-origin iframe 277 // with no fledge-related permissions. The iframe is a different origin from the 278 // first cross-origin iframe. 279 let iframe2 = await createIframe( 280 test, OTHER_ORIGIN2, "join-ad-interest-group 'none'; run-ad-auction 'none'"); 281 await runInFrame( 282 test, iframe2, 283 `await createAndNavigateFencedFrame(test_instance, param);`, 284 /*param=*/config); 285 await waitForObservedRequests( 286 uuid, 287 [ createBidderReportURL(uuid, '1', OTHER_ORIGIN1), 288 createSellerReportURL(uuid, '1', OTHER_ORIGIN1)]); 289 }, 'Run auction in cross-origin iframe and open winning ad in a fenced frame child of another cross-origin iframe.'); 290 291 //////////////////////////////////////////////////////////////////////////////// 292 // Other tests. 293 //////////////////////////////////////////////////////////////////////////////// 294 295 subsetTest(promise_test, async test => { 296 const uuid = generateUuid(test); 297 298 let iframe = await createIframe(test, OTHER_ORIGIN1, "run-ad-auction"); 299 300 // Do everything in a cross-origin iframe, and make sure correct top-frame origin is used. 301 await runInFrame( 302 test, iframe, 303 `const uuid = "${uuid}"; 304 const renderURL = createRenderURL(uuid, /*script=*/null, /*signalsParam=*/'hostname'); 305 306 await joinInterestGroup( 307 test_instance, uuid, 308 { trustedBiddingSignalsKeys: ['hostname'], 309 trustedBiddingSignalsURL: TRUSTED_BIDDING_SIGNALS_URL, 310 ads: [{ renderURL: renderURL }], 311 biddingLogicURL: createBiddingScriptURL({ 312 generateBid: 313 \`if (browserSignals.topWindowHostname !== "${document.location.hostname}") 314 throw "Wrong topWindowHostname: " + browserSignals.topWindowHostname; 315 if (trustedBiddingSignals.hostname !== '${window.location.hostname}') 316 throw 'Wrong hostname: ' + trustedBiddingSignals.hostname;\`})}); 317 318 await runBasicFledgeTestExpectingWinner( 319 test_instance, uuid, 320 { trustedScoringSignalsURL: TRUSTED_SCORING_SIGNALS_URL, 321 decisionLogicURL: 322 createDecisionScriptURL( 323 uuid, 324 { scoreAd: 325 \`if (browserSignals.topWindowHostname !== "${document.location.hostname}") 326 throw "Wrong topWindowHostname: " + browserSignals.topWindowHostname; 327 if (trustedScoringSignals.renderURL["\${renderURL}"] !== '${window.location.hostname}') 328 throw 'Wrong hostname: ' + trustedScoringSignals.renderURL["\${renderURL}"];\` })});`); 329 }, 'Different top-frame origin.'); 330 331 subsetTest(promise_test, async test => { 332 const uuid = generateUuid(test); 333 334 let bidderOrigin = OTHER_ORIGIN1; 335 let sellerOrigin = OTHER_ORIGIN2; 336 let bidderSendReportToURL = createBidderReportURL(uuid, '1', OTHER_ORIGIN3); 337 let sellerSendReportToURL = createSellerReportURL(uuid, '2', OTHER_ORIGIN4); 338 let bidderBeaconURL = createBidderBeaconURL(uuid, '3', OTHER_ORIGIN5); 339 let sellerBeaconURL = createSellerBeaconURL(uuid, '4', OTHER_ORIGIN6); 340 let renderURL = createRenderURL( 341 uuid, 342 `window.fence.reportEvent({ 343 eventType: "beacon", 344 eventData: window.location.href, 345 destination: ["buyer", "seller"] 346 })`, 347 /*signalsParams=*/null, OTHER_ORIGIN7); 348 349 let iframe = await createIframe(test, bidderOrigin, "join-ad-interest-group"); 350 let interestGroup = createInterestGroupForOrigin( 351 uuid, bidderOrigin, 352 {biddingLogicURL: createBiddingScriptURL( 353 { origin: bidderOrigin, 354 generateBid: `if (browserSignals.topWindowHostname !== "${document.location.hostname}") 355 throw "Wrong topWindowHostname: " + browserSignals.topWindowHostname; 356 if (interestGroup.owner !== "${bidderOrigin}") 357 throw "Wrong origin: " + interestGroup.owner; 358 if (!interestGroup.biddingLogicURL.startsWith("${bidderOrigin}")) 359 throw "Wrong origin: " + interestGroup.biddingLogicURL; 360 if (interestGroup.ads[0].renderURL !== "${renderURL}") 361 throw "Wrong renderURL: " + interestGroup.ads[0].renderURL; 362 if (browserSignals.seller !== "${sellerOrigin}") 363 throw "Wrong origin: " + browserSignals.seller;`, 364 reportWin: `if (browserSignals.topWindowHostname !== "${document.location.hostname}") 365 throw "Wrong topWindowHostname: " + browserSignals.topWindowHostname; 366 if (browserSignals.seller !== "${sellerOrigin}") 367 throw "Wrong seller: " + browserSignals.seller; 368 if (browserSignals.interestGroupOwner !== "${bidderOrigin}") 369 throw "Wrong interestGroupOwner: " + browserSignals.interestGroupOwner; 370 if (browserSignals.renderURL !== "${renderURL}") 371 throw "Wrong renderURL: " + browserSignals.renderURL; 372 if (browserSignals.seller !== "${sellerOrigin}") 373 throw "Wrong seller: " + browserSignals.seller; 374 sendReportTo("${bidderSendReportToURL}"); 375 registerAdBeacon({beacon: "${bidderBeaconURL}"});` }), 376 ads: [{ renderURL: renderURL }]}); 377 await runInFrame( 378 test, iframe, 379 `await joinInterestGroup(test_instance, "${uuid}", ${JSON.stringify(interestGroup)});`); 380 381 await runBasicFledgeAuctionAndNavigate(test, uuid, 382 { seller: sellerOrigin, 383 interestGroupBuyers: [bidderOrigin], 384 decisionLogicURL: createDecisionScriptURL( 385 uuid, 386 { origin: sellerOrigin, 387 scoreAd: `if (browserSignals.topWindowHostname !== "${document.location.hostname}") 388 throw "Wrong topWindowHostname: " + browserSignals.topWindowHostname; 389 if (auctionConfig.seller !== "${sellerOrigin}") 390 throw "Wrong seller: " + auctionConfig.seller; 391 if (auctionConfig.interestGroupBuyers[0] !== "${bidderOrigin}") 392 throw "Wrong interestGroupBuyers: " + auctionConfig.interestGroupBuyers; 393 if (browserSignals.interestGroupOwner !== "${bidderOrigin}") 394 throw "Wrong interestGroupOwner: " + browserSignals.interestGroupOwner; 395 if (browserSignals.renderURL !== "${renderURL}") 396 throw "Wrong renderURL: " + browserSignals.renderURL;`, 397 reportResult: `if (browserSignals.topWindowHostname !== "${document.location.hostname}") 398 throw "Wrong topWindowHostname: " + browserSignals.topWindowHostname; 399 if (browserSignals.interestGroupOwner !== "${bidderOrigin}") 400 throw "Wrong interestGroupOwner: " + browserSignals.interestGroupOwner; 401 if (browserSignals.renderURL !== "${renderURL}") 402 throw "Wrong renderURL: " + browserSignals.renderURL; 403 sendReportTo("${sellerSendReportToURL}"); 404 registerAdBeacon({beacon: "${sellerBeaconURL}"});`}) 405 }); 406 407 await waitForObservedRequests( 408 uuid, 409 [ bidderSendReportToURL, 410 sellerSendReportToURL, 411 `${bidderBeaconURL}, body: ${renderURL}`, 412 `${sellerBeaconURL}, body: ${renderURL}` 413 ]); 414 }, 'Single seller auction with as many distinct origins as possible (except no component ads).'); 415 416 subsetTest(promise_test, async test => { 417 const uuid = generateUuid(test); 418 419 // Join an interest group and run an auction with a winner. Use a tracking 420 // URL for the ad, so that if it's incorrectly loaded in this test, the 421 // waitForObservedRequests() at the end of the test will see it, and the 422 // test will fail. 423 await joinInterestGroup( 424 test, uuid, 425 {ads: [{renderURL: createTrackerURL(window.location.origin, uuid, 'track_get', 'renderURL')}]}); 426 let config = await runBasicFledgeTestExpectingWinner(test, uuid); 427 428 // Try to navigate a fenced frame to the winning ad in a new same-origin 429 // window. This should fail. Unfortunately, there's no assertion that 430 // can be checked for, and can't communicate with the contents of the 431 // fenced frame to make sure the load fails. 432 // 433 // So instead, join an interest group with a different sendReportTo-url, 434 // overwriting the previously joined one, and run another auction, loading 435 // the winner in another fenced frame. 436 // 437 // Then wait to see that only the reporting URLs from that second auction 438 // are requested. They should almost always be requested after the URLs 439 // from the first auction. 440 let child_window = 441 await createFrame(test, document.location.origin, /*is_iframe=*/false); 442 await runInFrame( 443 test, child_window, 444 `await createAndNavigateFencedFrame(test_instance, param); 445 await joinInterestGroup( 446 test_instance, "${uuid}", 447 {biddingLogicURL: createBiddingScriptURL( 448 {reportWin: "sendReportTo('${createBidderReportURL(uuid, "2")}');" })}); 449 await runBasicFledgeAuctionAndNavigate(test_instance, "${uuid}");`, 450 /*param=*/config); 451 await waitForObservedRequests( 452 uuid, [createBidderReportURL(uuid, "2"), createSellerReportURL(uuid)]); 453 }, 'Run auction in main frame, try to open winning ad in different same-origin main frame.');