Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

evaluateOnNewDocument not working in Iframes with sandbox attribute set to allow-same-origin #1106

Closed
Ndragomirov opened this issue Oct 20, 2017 · 8 comments
Labels
bug chromium Issues with Puppeteer-Chromium confirmed upstream

Comments

@Ndragomirov
Copy link

Ndragomirov commented Oct 20, 2017

Steps to reproduce

Tell us about your environment:

What steps will reproduce the problem?

Please include code that reproduces the issue.

var pup = require('puppeteer');

function test(){
  window.test = 1;
}

(async() =>{
  var b = await pup.launch({
    headless: true,
    args: [
      '--no-sandbox',
      '--disable-web-security'
    ]
  });
  var p = await b.newPage();
  await p.evaluateOnNewDocument(test);
  await p.goto('http://scooterlabs.com/echo');

  var foo = await p.evaluate(()=>{
    var el = document.createElement('iframe');
    el.setAttribute('sandbox', 'allow-same-origin');
    document.body.appendChild(el);
    return el.contentWindow.test;
  })

  var bar = await p.evaluate(()=>{
    var el = document.createElement('iframe');
    document.body.appendChild(el);
    return el.contentWindow.test;
  })

  console.log('foo', foo);
  console.log('bar ', bar );
  await b.close();
})();

What is the expected result?
foo should be 1 instead of undefined

What happens instead?
foo should be 1 instead of undefined

@paulirish
Copy link
Collaborator

I ran into something similar so i've expanded upon the original test case:

Findings:

  1. any sandbox iframes need both allow-same-origin and allow-scripts in the sandbox attribute.
    • the allow-scripts isn't required for a typical page to read/write to the window or document of such an iframe. DevTools protocol usually bypasses CSP when it wants to evaluate, so this feels like a bug.
  2. if [srcdoc] is set, page.evaluateOnNewDocument fails.
    • I don't see any reason in the spec that presence of srcdoc means a sandbox attribute is applied (though they are usually used together), so this may be a bug in Chromium's impl of srcdoc?

repro

var pup = require('puppeteer');

(async () => {
  var b = await pup.launch();
  var p = await b.newPage();
  await p.evaluateOnNewDocument(() => {
    window.foobar = Math.random() * 1000;
  });
  await p.goto('about:blank');

  var basiciframe = await p.evaluate(() => {
    var el = document.createElement('iframe');
    document.body.appendChild(el);
    return el.contentWindow.foobar;
  });

  var sandboxSOiframe = await p.evaluate(() => {
    var el = document.createElement('iframe');
    el.setAttribute('sandbox', 'allow-same-origin');
    document.body.appendChild(el);
    return el.contentWindow.foobar;
  });

  var sandboxSOASiframe = await p.evaluate(() => {
    var el = document.createElement('iframe');
    el.setAttribute('sandbox', 'allow-same-origin allow-scripts');
    document.body.appendChild(el);
    return el.contentWindow.foobar;
  });

  var srcdociframe = await p.evaluate(() => {
    var el = document.createElement('iframe');
    el.srcdoc = 'blank page, boys.';
    document.body.appendChild(el);
    return el.contentWindow.foobar;
  });

  console.log('basic iframe', basiciframe);
  console.log('sandbox same-origin iframe', sandboxSOiframe);
  console.log('sandbox same-origin&scripts iframe', sandboxSOASiframe);
  console.log('srcdoc iframe', srcdociframe);
  await b.close();
})();

returns:

basic iframe 932.347139390046
sandbox same-origin iframe undefined
sandbox same-origin&scripts iframe 590.9983933328277
srcdoc iframe undefined

@Ndragomirov
Copy link
Author

Ndragomirov commented Jun 10, 2018

Also there is no option to bypass CSP using evaluateOnNewDocument. By default, evaluateOnNewDocument is not working in frames loaded from different domains.

*EDIT Seems to be fixed in 1.5.0

@stale
Copy link

stale bot commented Jun 27, 2022

We're marking this issue as unconfirmed because it has not had recent activity and we weren't able to confirm it yet. It will be closed if no further activity occurs within the next 30 days.

@stale stale bot added the unconfirmed label Jun 27, 2022
@stale
Copy link

stale bot commented Jul 27, 2022

We are closing this issue. If the issue still persists in the latest version of Puppeteer, please reopen the issue and update the description. We will try our best to accomodate it!

@NightTsarina
Copy link
Contributor

I can confirm that this issue is still present with Puppeteer 19.9.1, but only affecting srcdoc iframes:

basic iframe: 1
sandbox same-origin iframe: 1
sandbox same-origin&scripts iframe: 1
srcdoc iframe: undefined

@OrKoN OrKoN reopened this Oct 10, 2023
@OrKoN
Copy link
Collaborator

OrKoN commented Oct 10, 2023

@NightTsarina do you have a reproducible example?

@NightTsarina
Copy link
Contributor

@NightTsarina do you have a reproducible example?

Sure, it is just an improvement over previous snippets:

import puppeteer from 'puppeteer';

async function main() {
    const browserArgs = [
        '--disable-dev-shm-usage',
        '--ignore-certificate-errors',
        '--no-sandbox',
    ];
    const launchOptions = {
        headless: 'new',
        args: browserArgs,
    };
    const browser = await puppeteer.launch(launchOptions);
    const page = await browser.newPage();    

    await page.evaluateOnNewDocument(() => {
        window.foobar = 'PASSED';
    });
    await page.goto('about:blank');

    const tests = {
        'basic <iframe>': {},
        'sandbox + same-origin <iframe>': {
            attributes: ['sandbox', 'allow-same-origin'],
        },
        'sandbox + same-origin & allow-scripts <iframe>': {
            attributes: ['sandbox', 'allow-same-origin allow-scripts'],
        },
        'srcdoc <iframe>': {
            srcdoc: 'Test content',
        },
    };

    for (const [testName, config] of Object.entries(tests)) {
        const result = await page.evaluate(({ attributes, srcdoc }) => {
            const el = document.createElement('iframe');
            if (attributes) {
                el.setAttribute(...attributes);
            }
            if (srcdoc) {
                el.srcdoc = srcdoc;
            }
            document.body.appendChild(el);
            return el.contentWindow.foobar ?? 'FAILED';
        }, config);
        console.log(`Test ${testName}: ${result}`);
    }
    await browser.close();
}

await main();
process.exit();
$ node ./index.mjs
Test basic <iframe>: PASSED
Test sandbox + same-origin <iframe>: PASSED
Test sandbox + same-origin & allow-scripts <iframe>: PASSED
Test srcdoc <iframe>: FAILED

Although, I have just tested upgrading the version of chrome, and it seems this was fixed recently. I tested:

  • Chrome/111.0.5555.0: FAILED
  • Chrome/112.0.5614.0: FAILED
  • Chrome/117.0.5938.149: PASSED

@OrKoN
Copy link
Collaborator

OrKoN commented Oct 11, 2023

Thanks! I am unable to reproduce on the latest version as well. I assume the issue has been fixed upstream.

@OrKoN OrKoN closed this as completed Oct 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug chromium Issues with Puppeteer-Chromium confirmed upstream
Projects
None yet
Development

No branches or pull requests

5 participants