¿Puede un sitio web detectar cuando está utilizando selenio con chromedriver?


He estado probando el Selenio con Chromedriver y me di cuenta de que algunas páginas pueden detectar que está utilizando Selenio a pesar de que no hay automatización en absoluto. Incluso cuando estoy navegando manualmente usando Chrome a través de Selenium y Xephyr A menudo recibo una página que dice que se detectó actividad sospechosa. He comprobado mi agente de usuario, y la huella digital de mi navegador, y todos son exactamente idénticos al navegador Chrome normal.

Cuando navego a estos sitios en chrome normal todo funciona bien, pero en el momento en que uso Selenio me detectan.

En teoría, chromedriver y chrome deberían verse literalmente exactamente igual a cualquier servidor web, pero de alguna manera pueden detectarlo.

Si quieres algún testcode prueba esto:

from pyvirtualdisplay import Display
from selenium import webdriver

display = Display(visible=1, size=(1600, 902))
display.start()
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--disable-extensions')
chrome_options.add_argument('--profile-directory=Default')
chrome_options.add_argument("--incognito")
chrome_options.add_argument("--disable-plugins-discovery");
chrome_options.add_argument("--start-maximized")
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.delete_all_cookies()
driver.set_window_size(800,800)
driver.set_window_position(0,0)
print 'arguments done'
driver.get('http://stubhub.com')

Si navegas por stubhub, serás redirigido y 'bloqueado' dentro de una o dos solicitudes. He estado investigando esto y no puedo averiguar cómo pueden decir que un usuario está usando Selenio.

, ¿Cómo lo hacen ¿eso?

EDITAR ACTUALIZACIÓN:

Instalé el complemento Selenium IDE en Firefox y me prohibieron cuando fui a stubhub.com en el navegador firefox normal con solo el plugin adicional.

EDITAR:

Cuando uso Fiddler para ver las solicitudes HTTP que se envían de ida y vuelta Me he dado cuenta de que el 'navegador falso's' solicitudes a menudo tienen 'no-cache' en el encabezado de respuesta.

EDITAR:

Resultados como este ¿Hay una manera de detectar que estoy en un Selenium Webdriver page from Javascript sugiere que no debería haber manera de detectar cuando está utilizando un webdriver. Pero esta evidencia sugiere lo contrario.

EDITAR:

El sitio sube una huella digital a sus servidores, pero he comprobado y la huella digital de selenium es idéntica a la huella digital cuando se utiliza chrome.

EDITAR:

Esta es una de las cargas útiles de huellas dactilares que envían a sus servidores

{"appName":"Netscape","platform":"Linuxx86_64","cookies":1,"syslang":"en-US","userlang":"en-US","cpu":"","productSub":"20030107","setTimeout":1,"setInterval":1,"plugins":{"0":"ChromePDFViewer","1":"ShockwaveFlash","2":"WidevineContentDecryptionModule","3":"NativeClient","4":"ChromePDFViewer"},"mimeTypes":{"0":"application/pdf","1":"ShockwaveFlashapplication/x-shockwave-flash","2":"FutureSplashPlayerapplication/futuresplash","3":"WidevineContentDecryptionModuleapplication/x-ppapi-widevine-cdm","4":"NativeClientExecutableapplication/x-nacl","5":"PortableNativeClientExecutableapplication/x-pnacl","6":"PortableDocumentFormatapplication/x-google-chrome-pdf"},"screen":{"width":1600,"height":900,"colorDepth":24},"fonts":{"0":"monospace","1":"DejaVuSerif","2":"Georgia","3":"DejaVuSans","4":"TrebuchetMS","5":"Verdana","6":"AndaleMono","7":"DejaVuSansMono","8":"LiberationMono","9":"NimbusMonoL","10":"CourierNew","11":"Courier"}}

Es idéntico en selenio y en chrome

EDITAR:

Las VPN funcionan para un solo uso, pero se detectan después de cargar la primera página. Claramente se está ejecutando algo de javascript para detectar Selenium.

Author: Community, 2015-10-20

12 answers

Para Usuarios de Mac

Sustitución de la variable cdc_ mediante Vim o Perl

Puedes usar vim, o como @Vic Seedoubleyew ha señalado en la respuesta de @Erti-Chris Eelmaa, perl, para reemplazar la variable cdc_ ( Ver post de @Erti-Chris Eelmaa para aprender más sobre esa variable). Usar vim o perl evita tener que recompilar código fuente o usar un editor hexadecimal. Asegúrese de hacer una copia del original chromedriver antes de intentar para editarlo.


Usando Vim

vim /path/to/chromedriver

Después de ejecutar la línea anterior, probablemente verá un montón de galimatías. Haga lo siguiente:

  1. Busca cdc_ escribiendo /cdc_ y presionando return.
  2. Habilita la edición pulsando a.
  3. Suprímase cualquier cantidad de $cdc_lasutopfhvcZLmcfl y sustitúyase lo que se suprimió por una cantidad igual de caracteres. Si no lo haces, chromedriver fallará.
  4. Después de que haya terminado de editar, presione esc.
  5. Para salvar la cambia y sale, escribe :wq! y presiona return.
  6. Si no desea guardar los cambios, pero desea salir, escriba :q! y presione return.
  7. Has terminado.

Vaya a la alterada chromedriver y haga doble clic en ella. Debería abrirse una ventana terminal. Si no ve killed en la salida, alteró correctamente el controlador.


Usando Perl

La línea siguiente reemplaza cdc_ por dog_:

perl -pi -e 's/cdc_/dog_/g' /path/to/chromedriver

Asegúrese de que el la cadena de reemplazo tiene el mismo número de caracteres que la cadena de búsqueda, de lo contrario el chromedriver fallará.

Explicación de Perl

s///g indica que desea buscar una cadena y reemplazarla globalmente con otra cadena (reemplaza todas las ocurrencias).

E. g., s/string/replacment/g

Así que,

s/// denota buscar y reemplazar una cadena.

cdc_ es la cadena de búsqueda.

dog_ es la cadena de reemplazo.

g es la clave global, que reemplaza cada ocurrencia de la cadena.

Cómo verificar si el reemplazo de Perl funcionó

La siguiente línea imprimirá cada aparición de la cadena de búsqueda cdc_:

perl -ne 'while(/cdc_/g){print "$&\n";}' /path/to/chromedriver

Si esto no devuelve nada, entonces cdc_ ha sido reemplazado.

Por el contrario, puedes usar esto:

perl -ne 'while(/dog_/g){print "$&\n";}' /path/to/chromedriver

Para ver si su la cadena de reemplazo, dog_, ahora está en el binario chromedriver. Si lo es, la cadena de reemplazo se imprimirá en la consola.

Vaya a la alterada chromedriver y haga doble clic en ella. Debería abrirse una ventana terminal. Si no ve killed en la salida, alteró correctamente el controlador.


Terminando

Después de alterar el binario chromedriver, asegúrese de que el nombre del binario chromedriver alterado es chromedriver, y que el binario original se mueve desde su ubicación original o renombrado.


Mi Experiencia Con Este Método

Anteriormente estaba siendo detectado en un sitio web mientras intentaba iniciar sesión, pero después de reemplazar cdc_ con una cadena del mismo tamaño, pude iniciar sesión. Como otros han dicho, sin embargo, si ya ha sido detectado, es posible que se bloquee por una gran cantidad de otras razones, incluso después de usar este método. Por lo tanto, es posible que tenga que intentar acceder al sitio que lo detectaba utilizando una VPN, red diferente, o lo que sea.

 3
Author: colossatr0n,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-01 01:48:36

Básicamente la forma en que funciona la detección de selenium, es que prueban las variables javascript predefinidas que aparecen cuando se ejecutan con selenium. Los scripts de detección de bot usualmente buscan cualquier cosa que contenga la palabra "selenium" / "webdriver" en cualquiera de las variables (en el objeto window), y también variables de documento llamadas $cdc_ y $wdc_. Por supuesto, todo esto depende del navegador en el que se encuentre. Todos los diferentes navegadores exponen diferentes cosas.

Para mí, usé chrome, así que, todos lo que tuve que hacer fue asegurarme de que $cdc_ ya no existía como variable de documento, y listo (descargar el código fuente de chromedriver, modificar chromedriver y volver a compilar $cdc_ bajo un nombre diferente.)

Esta es la función que modifiqué en chromedriver:

Función de llamada.js:

function getPageCache(opt_doc) {
  var doc = opt_doc || document;
  //var key = '$cdc_asdjflasutopfhvcZLmcfl_';
  var key = 'randomblabla_';
  if (!(key in doc))
    doc[key] = new Cache();
  return doc[key];
}

(nota: el comentario, todo lo que hice me volví $cdc_ a randomblabla_.

Aquí hay un pseudo-código que demuestra algunas de las técnicas que las redes de bots podrían utilizar:

runBotDetection = function () {
    var documentDetectionKeys = [
        "__webdriver_evaluate",
        "__selenium_evaluate",
        "__webdriver_script_function",
        "__webdriver_script_func",
        "__webdriver_script_fn",
        "__fxdriver_evaluate",
        "__driver_unwrapped",
        "__webdriver_unwrapped",
        "__driver_evaluate",
        "__selenium_unwrapped",
        "__fxdriver_unwrapped",
    ];

    var windowDetectionKeys = [
        "_phantom",
        "__nightmare",
        "_selenium",
        "callPhantom",
        "callSelenium",
        "_Selenium_IDE_Recorder",
    ];

    for (const windowDetectionKey in windowDetectionKeys) {
        const windowDetectionKeyValue = windowDetectionKeys[windowDetectionKey];
        if (window[windowDetectionKeyValue]) {
            return true;
        }
    };
    for (const documentDetectionKey in documentDetectionKeys) {
        const documentDetectionKeyValue = documentDetectionKeys[documentDetectionKey];
        if (window['document'][documentDetectionKeyValue]) {
            return true;
        }
    };

    for (const documentKey in window['document']) {
        if (documentKey.match(/\$[a-z]dc_/) && window['document'][documentKey]['cache_']) {
            return true;
        }
    }

    if (window['external'] && window['external'].toString() && (window['external'].toString()['indexOf']('Sequentum') != -1)) return true;

    if (window['document']['documentElement']['getAttribute']('selenium')) return true;
    if (window['document']['documentElement']['getAttribute']('webdriver')) return true;
    if (window['document']['documentElement']['getAttribute']('driver')) return true;

    return false;
};

Según usuario @ szx, también es posible simplemente abrir chromedriver.exe en el editor hexadecimal, y simplemente haga el reemplazo manualmente, sin hacer realmente ninguna compilación.

 94
Author: Erti-Chris Eelmaa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-11 17:22:36

Como ya hemos averiguado en la pregunta y las respuestas publicadas, hay un anti-Web-scraping y un servicio de detección de Bot llamado "Distil Networks" en juego aquí. Y, según la entrevista del CEO de la compañía :

A pesar de que pueden crear nuevos bots, encontramos una manera de identificar Selenio la herramienta a que están utilizando, por lo que estamos bloqueando el Selenio no importa cuántas veces iteran en ese bot. Estamos haciendo eso ahora con Python y un muchas tecnologías diferentes. Una vez que vemos un patrón emerge de un tipo de bot, luego trabajamos para realizar ingeniería inversa la tecnología que utilizan y la identifican como maliciosa.

Tomará tiempo y desafíos adicionales entender cómo exactamente están detectando Selenio, pero qué podemos decir con seguridad en este momento:

  • no está relacionado con las acciones que realiza con selenium: una vez que navega al sitio, se detecta y se prohíbe de inmediato. He tratado de añadir retrasos aleatorios artificiales entre acciones, haga una pausa después de que se cargue la página - nada ayudó
  • tampoco se trata de huellas dactilares del navegador - lo probé en múltiples navegadores con perfiles limpios y no, modos de incógnito - nada ayudó
  • dado que, de acuerdo con la sugerencia en la entrevista, esto fue "ingeniería inversa", sospecho que esto se hace con algún código JS que se ejecuta en el navegador revelando que este es un navegador automatizado a través de selenium webdriver

Decidido para publicarlo como una respuesta, ya que claramente:

¿Puede un sitio web detectar cuándo está utilizando selenio con chromedriver?

Sí.


También, lo que no he experimentado con es más antiguo selenium y versiones de navegador más antiguas - en teoría, podría haber algo implementado/añadido a selenium en un cierto punto que Distil Networks bot detector actualmente se basa en. Entonces, si este es el caso, podríamos detectar (sí, vamos a detectar el detector) en qué punto / versión a se realizó un cambio relevante, busque en el registro de cambios y conjuntos de cambios y, puede ser, esto podría darnos más información sobre dónde buscar y qué es lo que utilizan para detectar un navegador alimentado por webdriver. Es sólo una teoría que necesita ser probada.

 63
Author: alecxe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-29 00:33:53

Ejemplo de cómo se implementa en wellsfargo.com:

try {
 if (window.document.documentElement.getAttribute("webdriver")) return !+[]
} catch (IDLMrxxel) {}
try {
 if ("_Selenium_IDE_Recorder" in window) return !+""
} catch (KknKsUayS) {}
try {
 if ("__webdriver_script_fn" in document) return !+""
 17
Author: aianitro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-11 10:18:20

partial interface Navigator { readonly attribute boolean webdriver; };

El atributo IDL de webdriver de la interfaz del Navegador debe devolver el valor del indicador webdriver-active, que inicialmente es false.

Esta propiedad permite a los sitios web determinar que el agente de usuario está bajo el control de WebDriver, y se puede usar para ayudar a mitigar los ataques de denegación de servicio.

Tomado directamente del Borrador del Editor del W3C de 2017 de WebDriver . Esto implica en gran medida que, por lo menos, futuras iteraciones de los controladores de selenio serán identificables para evitar el mal uso. En última instancia, es difícil decir sin el código fuente, lo que hace exactamente controlador de chrome en específico para ser detectable.

 7
Author: bryce,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-27 23:05:14

Intenta usar selenium con un perfil de usuario específico de chrome, de esa manera puedes usarlo como usuario específico y definir cualquier cosa que quieras, Al hacerlo se ejecutará como un usuario 'real', mira el proceso de chrome con algún explorador de procesos y verás la diferencia con las etiquetas.

Por ejemplo:

username = os.getenv("USERNAME")
userProfile = "C:\\Users\\" + username + "\\AppData\\Local\\Google\\Chrome\\User Data\\Default"
options = webdriver.ChromeOptions()
options.add_argument("user-data-dir={}".format(userProfile))
# add here any tag you want.
options.add_experimental_option("excludeSwitches", ["ignore-certificate-errors", "safebrowsing-disable-download-protection", "safebrowsing-disable-auto-update", "disable-client-side-phishing-detection"])
chromedriver = "C:\Python27\chromedriver\chromedriver.exe"
os.environ["webdriver.chrome.driver"] = chromedriver
browser = webdriver.Chrome(executable_path=chromedriver, chrome_options=options)

Lista de etiquetas de Chrome aquí

 6
Author: Kobi K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-28 16:39:35

Incluso si está enviando todos los datos correctos (por ejemplo, Selenium no aparece como una extensión, tiene una resolución/profundidad de bits razonable, &c), hay una serie de servicios y herramientas que perfilan el comportamiento del visitante para determinar si el actor es un usuario o un sistema automatizado.

Por ejemplo, visitar un sitio y luego ir inmediatamente a realizar alguna acción moviendo el ratón directamente al botón relevante, en menos de un segundo, es algo que ningún usuario realmente haría hacer.

También podría ser útil como herramienta de depuración para usar un sitio como https://panopticlick.eff.org / para comprobar lo único que es su navegador; también le ayudará a verificar si hay algún parámetro específico que indique que se está ejecutando en Selenium.

 5
Author: lfaraone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-25 22:01:14

Parece que están detrás de un firewall de aplicaciones web. Echa un vistazo a modsecurity y owasp para ver cómo funcionan. En realidad, lo que está preguntando es cómo hacer la evasión de detección de bots. Para eso no es selenium web driver. Es para probar su aplicación web no golpear otras aplicaciones web. Es posible, pero básicamente, tendría que mirar lo que un WAF busca en su conjunto de reglas y específicamente evitarlo con selenio si puede. Incluso entonces, podría no funcionar porque no sabes qué WAF están usando. Hiciste el primer paso correcto, que es fingir el agente de usuario. Si eso no funcionó, entonces un WAF está en su lugar y es probable que tenga que ser más difícil.

Editar: Tomado de otra respuesta. Asegúrese de que su agente de usuario se está configurando correctamente primero. Tal vez tener que golpear un servidor web local o olfatear el tráfico que sale.

 4
Author: Bassel Samman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-23 23:53:12

Se dice que Firefox establece window.navigator.webdriver === true si trabaja con un webdriver. Eso fue de acuerdo con una de las especificaciones más antiguas (por ejemplo: archive.org ) pero no pude encontrarlo en el nuevo excepto por algunas palabras muy vagas en los apéndices.

Una prueba para ello está en el código selenium en el archivo fingerprint_test.js donde el comentario al final dice "Actualmente solo implementado en firefox", pero no pude identificar ningún código en esa dirección con un simple greping, ni en el actual (41.0.2) Firefox release-tree ni en el Chromium-tree.

También encontré un comentario para una confirmación anterior con respecto a las huellas dactilares en el controlador de firefox b82512999938 de enero de 2015. Ese código todavía está en el Selenium GIT-master descargado ayer en javascript/firefox-driver/extension/content/server.js con un comentario que enlaza con el apéndice ligeramente diferente en la especificación actual de w3c webdriver.

 3
Author: deamentiaemundi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-27 23:44:32

La detección de bot que he visto parece más sofisticada o al menos diferente de lo que he leído en las respuestas a continuación.

EXPERIMENTO 1:

  1. Abro un navegador y una página web con Selenium desde una consola Python.
  2. El ratón ya está en una ubicación específica donde sé que aparecerá un enlace una vez que se cargue la página. Nunca muevo el ratón.
  3. Presiono el botón izquierdo del ratón una vez (esto es necesario para enfocar desde la consola donde Python se está ejecutando en el navegador).
  4. Presiono el botón izquierdo del ratón de nuevo (recuerde, el cursor está encima de un enlace dado).
  5. El enlace se abre normalmente, como debería.

EXPERIMENTO 2:

  1. Como antes, abro un navegador y la página web con Selenium desde una consola Python.

  2. Esta vez, en lugar de hacer clic con el ratón, utilizo Selenium (en la consola de Python) para hacer clic en el mismo elemento con un desplazamiento aleatorio.

  3. El enlace no se abre, pero me llevan a una página de registro.

IMPLICACIONES:

  • abrir un navegador web a través de Selenium no me impide aparecer humano
  • mover el ratón como un humano no es necesario para ser clasificado como humano
  • al hacer clic en algo a través de Selenio con un desplazamiento todavía se dispara la alarma

Parece misterioso, pero supongo que solo pueden determinar si una acción se origina a partir de Selenio o no, mientras que no les importa si el navegador se abrió a través de Selenium o no. ¿O pueden determinar si la ventana tiene foco? Sería interesante saber si alguien tiene alguna idea.

 3
Author: M3RS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-20 11:24:30

Escriba una página html con el siguiente código. Verá que en el DOM selenium aplica un atributo webdriver en el outerHTML

<html>
<head>
  <script type="text/javascript">
  <!--
    function showWindow(){
      javascript:(alert(document.documentElement.outerHTML));
    }
  //-->
  </script>
</head>
<body>
  <form>
    <input type="button" value="Show outerHTML" onclick="showWindow()">
  </form>
</body>
</html>
 1
Author: PC3TJ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-28 04:10:54

Algunos sitios están detectando esto:

function d() {
try {
    if (window.document.$cdc_asdjflasutopfhvcZLmcfl_.cache_)
        return !0
} catch (e) {}

try {
    //if (window.document.documentElement.getAttribute(decodeURIComponent("%77%65%62%64%72%69%76%65%72")))
    if (window.document.documentElement.getAttribute("webdriver"))
        return !0
} catch (e) {}

try {
    //if (decodeURIComponent("%5F%53%65%6C%65%6E%69%75%6D%5F%49%44%45%5F%52%65%63%6F%72%64%65%72") in window)
    if ("_Selenium_IDE_Recorder" in window)
        return !0
} catch (e) {}

try {
    //if (decodeURIComponent("%5F%5F%77%65%62%64%72%69%76%65%72%5F%73%63%72%69%70%74%5F%66%6E") in document)
    if ("__webdriver_script_fn" in document)
        return !0
} catch (e) {}
 1
Author: Néstor Lim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-22 09:52:33