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

[FIX] Testing Cloudflare Requests: Ensuring Stability and Compatibility Across Platforms #274

Open
alpgul opened this issue May 12, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@alpgul
Copy link

alpgul commented May 12, 2024

Test.js:
/**
* Cloudflare Check Tools:
   * https://nopecha.com/demo/cloudflare
   * https://nowsecure.nl/
   * https://2captcha.com/demo/cloudflare-turnstile
* Browser Check Tools:
   * https://infosimples.github.io/detect-headless/
   * https://arh.antoinevastel.com/bots/areyouheadless
   * https://bot.sannysoft.com/
   * https://hmaker.github.io/selenium-detector/
   * https://kaliiiiiiiiii.github.io/brotector/
   */
const puppeteer = require("puppeteer-core");
const fs = require('fs');
const chromium = require("@sparticuz/chromium-min");
const remoteExecutablePath =
    "https://github.com/Sparticuz/chromium/releases/download/v123.0.1/chromium-v123.0.1-pack.tar";
async function main() {
    let userAgent = "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Mobile Safari/537.36";

    const browser = await puppeteer.launch({
        ignoreDefaultArgs: ["--enable-automation"],
        args: [...chromium.args, "--disable-blink-features=AutomationControlled"],
        defaultViewport: chromium.defaultViewport,
        executablePath: await chromium.executablePath(remoteExecutablePath),
        headless: "new"
    });
    console.log("Browser is created.");
    browser.on("targetcreated", async (target) => {
        const page = await target.page();
        try {
            await page.setUserAgent(userAgent);
            await page.setViewport({
                width: 1920,
                height: 1080,
            });
            const preloadFile = fs.readFileSync('./preload.js', 'utf8');
            await page.evaluateOnNewDocument(preloadFile);
        } catch (err) {
            // console.log(err.message);
        }
    });

    let page = (await browser.pages())[0];
    await page.setUserAgent(userAgent);
    await page.setViewport({
        width: 1920,
        height: 1080,
    });
    const preloadFile = fs.readFileSync('./preload.js', 'utf8');
    await page.evaluateOnNewDocument(preloadFile);
    await page.goto("https://nopecha.com/demo/cloudflare", {
        waitUntil: "networkidle2",
    });
    console.log("CF is loaded.");
    await page.waitForSelector('.link_row', {
        timeout: 60000
    })
    console.log("Page is loaded.");
    await page.screenshot({ path: "example2.png" });
    console.log("Screenshot is created.");
    await browser.close();


}
main();
Preload.js:
(() => {
  const windowsPatch = (w) => {
    w.chrome = {
      "app": { "isInstalled": false, "InstallState": { "DISABLED": "disabled", "INSTALLED": "installed", "NOT_INSTALLED": "not_installed" }, "RunningState": { "CANNOT_RUN": "cannot_run", "READY_TO_RUN": "ready_to_run", "RUNNING": "running" } },
      loadTimes: () => { },
      csi: () => { }
    }
    w.console.debug = () => { };
    w.console.log = () => { }
    w.console.context = () => { };
    w.navigator.permissions.query = new Proxy(navigator.permissions.query, {
      apply: async function (target, thisArg, args) {
        try {
          const result = await Reflect.apply(target, thisArg, args);
          if (result?.state === "prompt") {
            Object.defineProperty(result, 'state', { value: "denied" });
          }
          return Promise.resolve(result);
        } catch (error) {
          return Promise.reject(error);
        }
      }
    });
    Element.prototype._addEventListener = Element.prototype.addEventListener;
    Element.prototype.addEventListener = function () {
      let args = [...arguments]
      let temp = args[1];
      args[1] = function () {
        let args2 = [...arguments];
        args2[0] = Object.assign({}, args2[0])
        args2[0].isTrusted = true;
        return temp(...args2);
      }
      return this._addEventListener(...args);
    }
  }
  const cloudflareClicker = (w) => {
    if (w?.document && w.location.host === "challenges.cloudflare.com") {
      const targetSelector = 'input[type=checkbox]';
      const observer = new MutationObserver((mutationsList) => {
        for (const mutation of mutationsList) {
          if (mutation.type === 'childList') {
            const addedNodes = Array.from(mutation.addedNodes);
            for (const addedNode of addedNodes) {
              if (addedNode.nodeType === addedNode.ELEMENT_NODE) {
                const node = addedNode?.querySelector(targetSelector);
                if (node) {
                  setTimeout(() => {
                    node.parentElement.click();
                  }, 1000);
                }
              }
            }
          }
        }
      });


      const observerOptions = {
        childList: true,
        subtree: true
      };
      observer.observe(w.document, observerOptions);
    }
  }
  windowsPatch(window);
  cloudflareClicker(window);
})();

I have written the test and preload codes above for Cloudflare to successfully perform its requests, and they are working fine. However, I'm unsure if the code is stable or not. That's why I opened this topic, as it needs to be tested on different websites, different versions of Chromium, and platforms.

When testing, attention should be paid to the user-agent because plugins are checked in user-agents that do not include the Android expression. That's why I used Android because it doesn't have any plugins.
If stability is achieved, the usage of the @sparticuz/chromium-min package will increase.

@alpgul alpgul added the bug Something isn't working label May 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant