如何使用puppeteer的API页面绕过CSP(Content-Security-Policy).addScriptTag?

时间:2017-10-19 15:51:06

标签: google-chrome headless puppeteer

情形:

我在无头模式下使用puppeteer启动的chrome,并使用跨域javascript文件调用page.addScriptTag。现在,如果开放网站有csp设置并且仅限制相同的原始javascript标记,我该如何使用puppeteer API绕过它?

2 个答案:

答案 0 :(得分:3)

使用:

await page.setBypassCSP(true)

Documentation

答案 1 :(得分:0)

这是我的第一个stackoverflow贡献,所以请怜悯我。我发现这项工作允许您通过CSP,Here

基本思想是拦截页面请求并使用类似node-fetch的库来发出请求,并在将其传递回chrome时禁用CSP标头。

这里是最初来自github问题跟踪器的片段。

替换" example.com"与需要禁用CSP的网站。

const fetch = require('node-fetch')

const requestInterceptor = async (request) => {
  try {
    const url = request.url()
    const requestHeaders = request.headers()
    const acceptHeader = requestHeaders.accept || ''
    if (url.includes("example.com") && (acceptHeader.includes('text/html'))) {
      const cookiesList = await page.cookies(url)
      const cookies = cookiesList.map(cookie => `${cookie.name}=${cookie.value}`).join('; ')
      delete requestHeaders['x-devtools-emulate-network-conditions-client-id']
      if (requestHeaders.Cookie) {
        requestHeaders.cookie = requestHeaders.Cookie
        delete requestHeaders.Cookie
      }
      const theseHeaders = Object.assign({'cookie': cookies}, requestHeaders, {'accept-language': 'en-US,en'})

      const init = {
        body: request.postData(),
        headers: theseHeaders,
        method: request.method(),
        follow: 20,
      }
      const result = await fetch(
        url,
        init,
      )
      const resultHeaders = {}
      result.headers.forEach((value, name) => {
        if (name.toLowerCase() !== 'content-security-policy') {
          resultHeaders[name] = value
        } else {
          console.log('CSP', `omitting CSP`, {originalCSP: value})
        }
      })
      const buffer = await result.buffer()
      await request.respond({
        body: buffer,
        resultHeaders,
        status: result.status,
      })
    } else {
      request.continue();
    }
  } catch (e) {
    console.log("Error while disabling CSP", e);
    request.abort();
  }
}

await page.setRequestInterception(true)
page.on('request', requestInterceptor)