some headless evasions
This commit is contained in:
parent
843173827a
commit
8084b3f9c4
|
@ -22,6 +22,7 @@ by UltrafunkAmsterdam (https://github.com/ultrafunkamsterdam)
|
||||||
__version__ = "3.1.5r4"
|
__version__ = "3.1.5r4"
|
||||||
|
|
||||||
|
|
||||||
|
import inspect
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
@ -29,9 +30,8 @@ import re
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import time
|
|
||||||
import inspect
|
|
||||||
import threading
|
import threading
|
||||||
|
import time
|
||||||
|
|
||||||
import selenium.webdriver.chrome.service
|
import selenium.webdriver.chrome.service
|
||||||
import selenium.webdriver.chrome.webdriver
|
import selenium.webdriver.chrome.webdriver
|
||||||
|
@ -39,11 +39,10 @@ import selenium.webdriver.common.service
|
||||||
import selenium.webdriver.remote.webdriver
|
import selenium.webdriver.remote.webdriver
|
||||||
|
|
||||||
from .cdp import CDP
|
from .cdp import CDP
|
||||||
from .options import ChromeOptions
|
|
||||||
from .patcher import IS_POSIX
|
|
||||||
from .patcher import Patcher
|
|
||||||
from .reactor import Reactor
|
|
||||||
from .dprocess import start_detached
|
from .dprocess import start_detached
|
||||||
|
from .options import ChromeOptions
|
||||||
|
from .patcher import IS_POSIX, Patcher
|
||||||
|
from .reactor import Reactor
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
"Chrome",
|
"Chrome",
|
||||||
|
@ -119,7 +118,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
|
||||||
suppress_welcome=True,
|
suppress_welcome=True,
|
||||||
use_subprocess=False,
|
use_subprocess=False,
|
||||||
debug=False,
|
debug=False,
|
||||||
**kw
|
**kw,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Creates a new instance of the chrome driver.
|
Creates a new instance of the chrome driver.
|
||||||
|
@ -235,7 +234,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
|
||||||
if not options:
|
if not options:
|
||||||
options = ChromeOptions()
|
options = ChromeOptions()
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if hasattr(options, "_session") and options._session is not None:
|
if hasattr(options, "_session") and options._session is not None:
|
||||||
# prevent reuse of options,
|
# prevent reuse of options,
|
||||||
|
@ -262,7 +260,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
|
||||||
options.add_argument("--remote-debugging-port=%s" % debug_port)
|
options.add_argument("--remote-debugging-port=%s" % debug_port)
|
||||||
|
|
||||||
if user_data_dir:
|
if user_data_dir:
|
||||||
options.add_argument('--user-data-dir=%s' % user_data_dir)
|
options.add_argument("--user-data-dir=%s" % user_data_dir)
|
||||||
|
|
||||||
language, keep_user_data_dir = None, bool(user_data_dir)
|
language, keep_user_data_dir = None, bool(user_data_dir)
|
||||||
|
|
||||||
|
@ -359,7 +357,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
|
||||||
or divmod(logging.getLogger().getEffectiveLevel(), 10)[0]
|
or divmod(logging.getLogger().getEffectiveLevel(), 10)[0]
|
||||||
)
|
)
|
||||||
|
|
||||||
if hasattr(options, 'handle_prefs'):
|
if hasattr(options, "handle_prefs"):
|
||||||
options.handle_prefs(user_data_dir)
|
options.handle_prefs(user_data_dir)
|
||||||
|
|
||||||
# fix exit_type flag to prevent tab-restore nag
|
# fix exit_type flag to prevent tab-restore nag
|
||||||
|
@ -375,7 +373,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
|
||||||
config["profile"]["exit_type"] = None
|
config["profile"]["exit_type"] = None
|
||||||
fs.seek(0, 0)
|
fs.seek(0, 0)
|
||||||
json.dump(config, fs)
|
json.dump(config, fs)
|
||||||
fs.truncate() # the file might be shorter
|
# fs.truncate() # the file might be shorter
|
||||||
logger.debug("fixed exit_type flag")
|
logger.debug("fixed exit_type flag")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.debug("did not find a bad exit_type flag ")
|
logger.debug("did not find a bad exit_type flag ")
|
||||||
|
@ -490,9 +488,101 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
|
||||||
"Page.addScriptToEvaluateOnNewDocument",
|
"Page.addScriptToEvaluateOnNewDocument",
|
||||||
{
|
{
|
||||||
"source": """
|
"source": """
|
||||||
Object.defineProperty(navigator, 'maxTouchPoints', {
|
Object.defineProperty(navigator, 'maxTouchPoints', {get: () => 1});
|
||||||
get: () => 1
|
Object.defineProperty(navigator.connection, 'rtt', {get: () => 100});
|
||||||
})"""
|
|
||||||
|
// https://github.com/microlinkhq/browserless/blob/master/packages/goto/src/evasions/chrome-runtime.js
|
||||||
|
window.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'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
runtime: {
|
||||||
|
OnInstalledReason: {
|
||||||
|
CHROME_UPDATE: 'chrome_update',
|
||||||
|
INSTALL: 'install',
|
||||||
|
SHARED_MODULE_UPDATE: 'shared_module_update',
|
||||||
|
UPDATE: 'update'
|
||||||
|
},
|
||||||
|
OnRestartRequiredReason: {
|
||||||
|
APP_UPDATE: 'app_update',
|
||||||
|
OS_UPDATE: 'os_update',
|
||||||
|
PERIODIC: 'periodic'
|
||||||
|
},
|
||||||
|
PlatformArch: {
|
||||||
|
ARM: 'arm',
|
||||||
|
ARM64: 'arm64',
|
||||||
|
MIPS: 'mips',
|
||||||
|
MIPS64: 'mips64',
|
||||||
|
X86_32: 'x86-32',
|
||||||
|
X86_64: 'x86-64'
|
||||||
|
},
|
||||||
|
PlatformNaclArch: {
|
||||||
|
ARM: 'arm',
|
||||||
|
MIPS: 'mips',
|
||||||
|
MIPS64: 'mips64',
|
||||||
|
X86_32: 'x86-32',
|
||||||
|
X86_64: 'x86-64'
|
||||||
|
},
|
||||||
|
PlatformOs: {
|
||||||
|
ANDROID: 'android',
|
||||||
|
CROS: 'cros',
|
||||||
|
LINUX: 'linux',
|
||||||
|
MAC: 'mac',
|
||||||
|
OPENBSD: 'openbsd',
|
||||||
|
WIN: 'win'
|
||||||
|
},
|
||||||
|
RequestUpdateCheckStatus: {
|
||||||
|
NO_UPDATE: 'no_update',
|
||||||
|
THROTTLED: 'throttled',
|
||||||
|
UPDATE_AVAILABLE: 'update_available'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/microlinkhq/browserless/blob/master/packages/goto/src/evasions/navigator-permissions.js
|
||||||
|
if (!window.Notification) {
|
||||||
|
window.Notification = {
|
||||||
|
permission: 'denied'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const originalQuery = window.navigator.permissions.query
|
||||||
|
window.navigator.permissions.__proto__.query = parameters =>
|
||||||
|
parameters.name === 'notifications'
|
||||||
|
? Promise.resolve({ state: window.Notification.permission })
|
||||||
|
: originalQuery(parameters)
|
||||||
|
|
||||||
|
const oldCall = Function.prototype.call
|
||||||
|
function call() {
|
||||||
|
return oldCall.apply(this, arguments)
|
||||||
|
}
|
||||||
|
Function.prototype.call = call
|
||||||
|
|
||||||
|
const nativeToStringFunctionString = Error.toString().replace(/Error/g, 'toString')
|
||||||
|
const oldToString = Function.prototype.toString
|
||||||
|
|
||||||
|
function functionToString() {
|
||||||
|
if (this === window.navigator.permissions.query) {
|
||||||
|
return 'function query() { [native code] }'
|
||||||
|
}
|
||||||
|
if (this === functionToString) {
|
||||||
|
return nativeToStringFunctionString
|
||||||
|
}
|
||||||
|
return oldCall.call(oldToString, this)
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line
|
||||||
|
Function.prototype.toString = functionToString
|
||||||
|
"""
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
return orig_get(*args, **kwargs)
|
return orig_get(*args, **kwargs)
|
||||||
|
|
Loading…
Reference in New Issue