CSP Issue attempting to access an iframe from a different origin: "Blocked a frame with origin from accessing a cross-origin frame"

Hi,
I spotted this other thread explaining how to set bypassCSP: true to be able to work with iframes from a different origin

However, am I correct in assuming that this code no longer works since k6 v0.46?

const context = browser.newContext({
  bypassCSP: true
});

From:

" * Browser options can now only be set using environment variables."

I searched for a relevant env variable but couldn’t fine one in the docs

Currently I get the following error

Blocked a frame with origin "https://mydomain.com" from accessing a cross-origin frame.

The code I’m attempting to execute is identical to the previous thread:

  console.log(page.evaluate(() => {
    return document.querySelector('iframe').contentWindow.document.getElementsByTagName('span')[0].innerText
  }));

Hello @colm3,

The code you provided remains functional in k6 v0.46. The bypassCSP setting belongs to the browserContext options, as outlined in the browserContext documentation, rather than being a browser module option. You can continue configuring it as you have before without necessitating the use of environment variables.

Kindly produce a test script that reproduces the issue, letting us offer assistance.

Thanks.

The “Blocked a frame with origin from accessing a cross-origin frame” error is triggered by the Same-Origin Policy in web browsers, which prevents scripts in one frame from directly accessing content in a frame from a different origin due to security concerns. To address this issue, you should employ cross-origin communication techniques such as postMessage() for controlled messaging between frames, configure Cross-Origin Resource Sharing (CORS) headers when controlling both source and destination servers, or use JSONP for data retrieval. Verify proper URL configuration, consider server-side solutions, and adhere to browser extension policies. These measures ensure secure and legitimate interactions between frames without violating the security constraints imposed by the Same-Origin Policy.

Hi @inancgumus

Here’s an example to reproduce the problem:
I’ve setup a tmp instance of a Braintree credit card form here:
https://k6csp.guruslabs.com/btree/

Here’s the sample k6 browser test I created

I tried executing this with:

K6_BROWSER_HEADLESS=false k6 run k6b-iframe.js

In desperation I also tried it with:
K6_BROWSER_HEADLESS=false K6_BROWSER_ARGS='disable-web-security,user-data-dir=datadir' k6 run k6b-iframe-sample.js

In all scenarios I get the following error:

ERRO[0005] Uncaught (in promise) GoError: evaluating JS: DOMException: Blocked a frame with origin "https://k6csp.guruslabs.com" from accessing a cross-origin frame.
    at __xk6_browser_evaluation_script__:3:89
	at github.com/grafana/xk6-browser/api.Page.Evaluate-fm (native)
	at file:///<<snip>>/k6b-iframe-sample.js:42:24(39)  executor=shared-iterations scenario=browser

Let me know if you need anything else

1 Like

Hi @colm3,

Thanks for the example :bowing_man:

Can you try the following script:

export default async function () {
  const context = browser.newContext({
    bypassCSP: true,
    colorScheme: 'dark',
  });

  const page = context.newPage();

  try {
    await page.goto(
      'https://k6csp.guruslabs.com/btree/index.php',
      { waitUntil: 'networkidle' },
    )  
    
    // complete test payment.
    await page.locator('div.braintree-option__card').click();

    const iframeHandle = page.$('iframe[name=braintree-hosted-field-number]');
    const frame = iframeHandle.contentFrame();
    frame.waitForSelector('input[name="credit-card-number"]');
    await frame.click('input[name="credit-card-number"]');
    await frame.type('input[name="credit-card-number"]', '4111111111111111');

    await page.locator('button').click();
  } finally {
    page.close();
  }
}

Please make sure also enable CORS on this server. Something like the following:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://your-domain.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true

Let me know how it goes.

Thanks.

Hi @inancgumus

unfortunately that didn’t work :confused:

At the moment the script is just running indefinitely - I’m guessing it’s stuck at:

frame.waitForSelector('input[name="credit-card-number"]');

Re: CORS settings - those aren’t relevant here I think? Any CORS issues would pertain to Braintrees server settings, and the form in my demo is coming directly from Braintree and I can see their scripts/assets all load with the correct CORS headers in their responses:
e.g.

It seems like a local problem because it works on my localhost. Could you try running it from another machine/network to diagnose the problem? Another reason could be the element from the selector might not be appearing at the exact time.