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

Browser Automation Detected on Linux Machines #13

Open
0x6a69616e opened this issue Mar 6, 2024 · 7 comments
Open

Browser Automation Detected on Linux Machines #13

0x6a69616e opened this issue Mar 6, 2024 · 7 comments

Comments

@0x6a69616e
Copy link
Owner

I've been notified about a persistent problem affecting several users, and I'd like to address it myself since there haven't been any related issues submitted to this repository. Correct me if I'm mistaken, but it appears that kpsdk-solver is easily being detected for browser automation on Linux-based systems.

At the moment, the easiest workaround is to run the solver on a Windows-based machine. However, despite this, I still plan on putting efforts into patching this issue in an attempt to maintain some cross-platform functionality.

@0x6a69616e
Copy link
Owner Author

0x6a69616e commented Mar 12, 2024

I have a Linux machine where Kasada appears to function smoothly. Transferring certain window.navigator entries and the user agent from it to a solver on a Windows system seems to work fine.

const context = await browser.newContext({
  userAgent: 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0'
});

await context.addInitScript(() => {
  Object.entries({
    appCodeName: 'Mozilla',
    appName: 'Netscape',
    appVersion: '5.0 (X11)',
    buildID: '20181001000000',
    doNotTrack: "1",
    oscpu: 'Linux x86_64',
    platform: 'Linux x86_64',
    product: 'Gecko',
    productSub: '20100101'
  }).map(([key, value]) => Object.defineProperty(navigator, key, {
    get: () => value
  }));
});

Removing the oscpu and platform fields results in no presence of reinterrogationTimeoutDuration in the obtained SDK message, which indicates detection of an automated browser.

This is not a foolproof solution.

@niriter
Copy link

niriter commented Apr 10, 2024

Hi, is there a Docker image that will work stably on Linux?

@0x6a69616e
Copy link
Owner Author

No, not exactly. 😅

@pydlv
Copy link

pydlv commented May 6, 2024

I have a Linux machine where Kasada appears to function smoothly. Transferring certain window.navigator entries and the user agent from it to a solver on a Windows system seems to work fine.

const context = await browser.newContext({
  userAgent: 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0'
});

await context.addInitScript(() => {
  Object.entries({
    appCodeName: 'Mozilla',
    appName: 'Netscape',
    appVersion: '5.0 (X11)',
    buildID: '20181001000000',
    doNotTrack: "1",
    oscpu: 'Linux x86_64',
    platform: 'Linux x86_64',
    product: 'Gecko',
    productSub: '20100101'
  }).map(([key, value]) => Object.defineProperty(navigator, key, {
    get: () => value
  }));
});

Removing the oscpu and platform fields results in no presence of reinterrogationTimeoutDuration in the obtained SDK message, which indicates detection of an automated browser.

This is not a foolproof solution.

Just FYI these values are working for me inside docker with TTV, despite the image being based on Ubuntu:

const context = await browser.newContext({
            userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0'
        });

        try {
            await context.addInitScript(() => {
                Object.entries({
                    appCodeName: 'Mozilla',
                    appName: 'Netscape',
                    appVersion: "5.0 (Windows)",
                    buildID: '20181001000000',
                    doNotTrack: "1",
                    oscpu: "Windows NT 10.0; Win64; x64",
                    platform: 'Win32',
                    product: 'Gecko',
                    productSub: '20100101'
                }).map(([key, value]) => Object.defineProperty(navigator, key, {
                    get: () => value
                }));
            });

@0x6a69616e 0x6a69616e pinned this issue May 6, 2024
@winterfell2021
Copy link

hi, I requested the api through the headers I got and got a 500 error response, is this because of linux?

@0x6a69616e
Copy link
Owner Author

hi, I requested the api through the headers I got and got a 500 error response, is this because of linux?

It's not entirely clear whether Linux plays a major role in causing the 500 error response. Could you specify which service you're using kpsdk-solver against?

@winterfell2021
Copy link

hi, I requested the api through the headers I got and got a 500 error response, is this because of linux?

It's not entirely clear whether Linux plays a major role in causing the 500 error response. Could you specify which service you're using kpsdk-solver against?

I try to against vercel on debian12, code:

const playwright = require('playwright');
const Solver = require('kpsdk-solver');
const request_api = require('request');
let config = {
    kasada: [{
        domain: 'xxx',
        method: 'POST',
        path: '/api/xxx',
        protocol: 'https:'
    }],
    'sdk-script': {
        url: 'https://xxx/149e9513-01fa-4fb0-aad4-566afd725d1b/2d206a39-8ed7-437e-a3be-862e0f06eea3/p.js'
    },
    url: 'https://xxx'
}
const solver = new Solver(config);

(async () => {
    const browser = await playwright.firefox.launch({ headless: true });
    const context = await browser.newContext({
        userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0'
    });

    await context.addInitScript(() => {
        Object.entries({
            appCodeName: 'Mozilla',
            appName: 'Netscape',
            appVersion: "5.0 (Windows)",
            buildID: '20181001000000',
            doNotTrack: "1",
            oscpu: "Windows NT 10.0; Win64; x64",
            platform: 'Win32',
            product: 'Gecko',
            productSub: '20100101'
        }).map(([key, value]) => Object.defineProperty(navigator, key, {
            get: () => value
        }));
    });

    const page = await solver.create(context, page => {
        // optional, page callback; access the page instance before the solver uses it
        console.log(page.url()); // should return about:blank or smthn
    });

    // retrieve the SDK messages
    console.log(page.solver.messages); // KPSDK:DONE:...

    // make a modifiable fetch request
    var options = {
        'method': 'POST',
        'url': 'https://xxxx',
        body: JSON.stringify({
            // actual body from network
        })

    };
    const { route, request } = await page.solver.fetch('xxxx',
        options
    );
    let headers = request.headers();
    options.headers = headers;
    request_api(options, function (error, response) {
        if (error) throw new Error(error);
        console.log(response.body);
    });
    await route.abort(); // abort unless same-page client token regeneration should be used

    await page.close();
    await context.close();
    await browser.close();
})();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants