Un site web peut-il détecter lorsque vous utilisez le sélénium avec chromedriver?

j'ai testé le sélénium avec Chromedriver et j'ai remarqué que certaines pages peuvent détecter que vous utilisez du sélénium même s'il n'y a pas d'automatisation du tout. Même quand je ne fais que naviguer manuellement en utilisant chrome à travers Selenium et Xephyr, je reçois souvent une page disant que l'activité suspecte a été détectée. J'ai vérifié mon agent utilisateur, et l'empreinte de mon navigateur, et ils sont tous exactement identiques au navigateur chrome normal.

quand je navigue vers ces sites dans le chrome normal, tout fonctionne bien, mais dès que j'utilise du sélénium, je suis détecté.

en théorie, le chromedriver et le chrome devraient être identiques pour tous les serveurs Web, mais ils peuvent le détecter d'une manière ou d'une autre.

si vous voulez un testcode essayer ceci:

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 vous parcourez stubhub, vous serez redirigé et "bloqué" dans une ou deux requêtes. J'ai étudié cela et je ne peux pas comprendre comment ils peut dire qu'un utilisateur utilise du sélénium.

Comment font-ils?

MODIFIER LA MISE À JOUR:

j'ai installé le plugin IDE Selenium dans Firefox et j'ai été banni quand je suis allé à stubhub.com dans le navigateur normal de firefox avec seulement le plugin supplémentaire.

EDIT:

quand J'utilise Fiddler pour voir les requêtes HTTP envoyées de part et d'autre, j'ai remarqué que les requêtes " faux browser's'ont souvent "no-cache" dans l'en-tête de réponse.

EDIT:

résultats comme celui-ci est-il un moyen de détecter que je suis dans une page Selenium Webdriver à partir de Javascript suggérer qu'il ne devrait pas y avoir de moyen de détecter lorsque vous utilisez un webdriver. Mais cette évidence suggère le contraire.

EDIT:

le site télécharge une empreinte digitale sur leurs serveurs, mais j'ai vérifié et l'empreinte digitale du sélénium est identique à l'empreinte digitale lors de l'utilisation de chrome.

EDIT:

c'est l'une des charges qu'ils envoient à leurs serveurs

{"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"}}

son identique en sélénium et en chrome

EDIT:

VPNs fonctionnent pour une seule utilisation mais sont détectés après que j'ai chargé la première page. De toute évidence, javascript est utilisé pour détecter le sélénium.

179
demandé sur Community 2015-10-20 03:08:57

12 réponses

Pour Les Utilisateurs Mac

remplaçant cdc_ variable utilisant Vim ou Perl

vous pouvez utiliser vim , ou comme @Vic Seedoubleyew l'a souligné dans la réponse de @Erti-Chris Eelmaa, perl , pour remplacer la variable cdc_ ( voir le post de @Erti-Chris Eelmaa pour en savoir plus sur cette variable ). En utilisant vim ou perl vous évite d'avoir à recompiler le code source ou utiliser un éditeur hexadécimal. Assurez-vous de faire une copie de l'original chromedriver avant de tenter de le modifier.


En Utilisant Vim

vim /path/to/chromedriver

après avoir parcouru la ligne ci-dessus, vous verrez probablement un tas de charabia. Faire ce qui suit:

  1. Rechercher cdc_ en tapant /cdc_ et en appuyant sur return .
  2. permet l'édition en appuyant sur a .
  3. supprimer tout montant de $cdc_lasutopfhvcZLmcfl et remplacer ce qui a été supprimé par un nombre égal de caractères. Si vous ne le faites pas, chromedriver échouera.
  4. après avoir édité, appuyez sur esc .
  5. Pour enregistrer les modifications et quitter, tapez :wq! et appuyez sur return .
  6. Si vous ne voulez pas enregistrer les changements, mais vous voulez arrêter, tapez :q! et appuyez sur return .
  7. C'est fini.

allez à la version modifiée chromedriver et double-cliquez dessus. Une fenêtre terminal devrait s'ouvrir. Si vous ne voyez pas killed dans la sortie, vous avez réussi à modifier le pilote.


En Utilisant Perl

La ligne ci-dessous remplace cdc_ avec dog_ :

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

assurez-vous que la chaîne de remplacement a le même nombre de caractères que la chaîne de recherche, sinon le chromedriver échouent.

Perl Explication

s///g indique que vous voulez rechercher une chaîne et la remplacer globalement par une autre chaîne (remplace toutes les occurrences).

p.ex., s/string/replacment/g

,

s/// indique la recherche et le remplacement d'une chaîne.

cdc_ est la chaîne de recherche.

dog_ est la chaîne de remplacement.

g est la clé globale, qui remplace chaque occurrence de la chaîne.

Comment vérifier si le remplacement Perl a fonctionné

la ligne suivante affichera chaque occurrence de la chaîne de recherche cdc_ :

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

si cela ne retourne rien, alors cdc_ a été remplacé.

inversement, vous pouvez utiliser le Ceci:

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

pour voir si votre chaîne de remplacement, dog_ , est maintenant dans le chromedriver binaire. Si c'est le cas, la chaîne de remplacement sera imprimée sur la console.

allez à la version modifiée chromedriver et double-cliquez dessus. Une fenêtre terminal devrait s'ouvrir. Si vous ne voyez pas killed dans la sortie, vous avez réussi à modifier le pilote.


Récapitulation

après avoir modifié le binaire chromedriver , assurez-vous que le nom du binaire modifié chromedriver est chromedriver , et que le binaire original est soit déplacé de son emplacement original ou renommé.


Mon Expérience Avec Cette Méthode

j'ai déjà été détecté sur un site Web en essayant de me connecter, mais après avoir remplacé cdc_ avec une corde de taille égale, j'ai pu me connecter. Comme d'autres l'ont dit, si vous avez déjà été détecté, vous pourriez être bloqué pour une pléthore d'autres raisons, même après avoir utilisé cette méthode. Donc, vous pourriez avoir à essayer d'accéder au site qui vous détectait en utilisant un VPN, un réseau différent, ou ce que vous avez.

3
répondu colossatr0n 2018-09-01 01:48:36

essentiellement la façon dont la détection de sélénium fonctionne, est qu'ils testent pour les variables javascript prédéfinies qui apparaissent lors de l'exécution avec le sélénium. Les scripts de détection bot regardent habituellement tout ce qui contient le mot "sélénium" / " webdriver "dans n'importe laquelle des variables (sur l'objet de fenêtre), et documentent aussi les variables appelées $cdc_ et $wdc_ . Bien sûr, tout cela dépend du navigateur que vous utilisez. Tous les différents navigateurs exposent des choses différentes.

Pour moi, j'ai utilisé chrome, donc, tout ce que j'ai eu à faire était de s'assurer que $cdc_ n'existe plus en tant que variable de document, et voila (télécharger le code source chromedriver, modifier chromedriver et re-compiler $cdc_ sous un nom différent.)

c'est la fonction que j'ai modifiée dans chromedriver:

call_function.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];
}

(notez le commentaire, Tout ce que j'ai fait je suis passé $cdc_ à randomblabla_ .

voici un pseudo-code qui démontre certaines des techniques que les réseaux bot pourraient utiliser:

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;
};

selon l'utilisateur @szx, il est également possible d'ouvrir simplement chromedriver.exe dans l'éditeur hexadécimal, et il suffit de faire le remplacement manuellement, sans réellement faire des compilation.

94
répondu Erti-Chris Eelmaa 2018-05-11 17:22:36

comme nous l'avons déjà compris dans la question et les réponses postées, il y a un service anti-raclage Web et un service de détection Bot appelé " Distil Networks " en jeu ici. Et, selon le PDG de la société interview :

même s'ils peuvent créer de nouveaux bots, nous avons trouvé un moyen d'identifier Le sélénium est un outil qu'ils utilisent, donc nous bloquons le sélénium Non importe combien de fois ils itèrent sur ce bot . Nous faisons maintenant avec Python et beaucoup de technologies différentes. Une fois que nous voyons un modèle sortir d'un type de bot, puis nous travaillons à la rétro-ingénierie technologie qu'ils utilisent et l'identifient comme étant malveillante.

il faudra du temps et des défis supplémentaires pour comprendre comment exactement ils détectent le sélénium, mais que pouvons-nous dire de sûr pour le moment:

  • il n'est pas lié à les actions que vous prenez avec le sélénium - une fois que vous naviguez vers le site, vous êtes immédiatement détecté et banni. J'ai essayé d'ajouter des délais aléatoires artificiels entre les actions, faire une pause après que la page est chargée - rien aidé
  • il ne s'agit pas non plus d'empreinte de navigateur - essayé dans plusieurs navigateurs avec des profils propres et pas, modes incognito - rien aidé
  • puisque, selon l'allusion dans l'interview, il s'agissait de "reverse engineering", Je suspect ceci est fait avec un certain code JS exécuté dans le navigateur révélant qu'il s'agit d'un navigateur automatisé via Selenium webdriver

a décidé de le poster comme une réponse, depuis clairement:

un site web peut-il détecter lorsque vous utilisez le sélénium avec chromedriver?

Oui.


aussi, ce que je n'ai pas expérimenté avec est plus vieux sélénium et versions de navigateur plus anciennes - en théorie, il pourrait y avoir quelque chose mis en œuvre/ajouté au sélénium à un certain point que Distil réseaux bot détecteur dépend actuellement. Ensuite, si c'est le cas, nous pourrions détecter (Ouais, nous allons détecter le détecteur) à quel point/version un changement pertinent a été fait, regarder dans changelog et changesets et, peut-être, cela pourrait nous donner plus d'informations sur où regarder et ce qu'ils utilisent pour détecter un navigateur WebDriver alimenté. C'est juste une théorie qui doit être testé.

63
répondu alecxe 2015-10-29 00:33:53

exemple de la façon dont il est mis en œuvre sur 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
répondu aianitro 2017-10-11 10:18:20

partial interface Navigator { readonly attribute boolean webdriver; };

l'attribut IDL de Webdriver de l'interface de navigateur doit retourner la valeur du drapeau webdriver-active, qui est initialement false.

cette propriété permet à des sites Web de déterminer que l'agent utilisateur est sous le contrôle de WebDriver, et peut être utilisé pour aider à atténuer les attaques de déni de service.

tiré directement du 2017 W3C Editor's Draft of WebDriver . Cela implique fortement qu'à tout le moins, les itérations futures des moteurs du sélénium seront identifiables afin d'éviter une mauvaise utilisation. En fin de compte, il est difficile de dire sans le code source, ce qui provoque exactement le pilote chrome en particulier pour être détectable.

7
répondu bryce 2017-01-27 23:05:14

essayez d'utiliser selenium avec un profil d'utilisateur spécifique de chrome, de cette façon vous pouvez l'utiliser en tant qu'utilisateur spécifique et définir tout ce que vous voulez, ce faisant, il sera exécuté comme un utilisateur "réel", regardez le processus chrome avec un explorateur de processus et vous verrez la différence avec les étiquettes.

par exemple:

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)

chrome balise de liste ici

6
répondu Kobi K 2015-10-28 16:39:35

même si vous envoyez toutes les bonnes données (par exemple, le sélénium n'apparaît pas comme une extension, vous avez une résolution/profondeur de bits raisonnable, &c), il y a un certain nombre de services et d'outils qui profilent le comportement des visiteurs pour déterminer si l'acteur est un utilisateur ou un système automatisé.

par exemple, visiter un site puis immédiatement aller effectuer une action en déplaçant la souris directement sur le bouton pertinent, en moins d'une seconde, est quelque chose qu'Aucun utilisateur ne serait effectivement le faire.

il pourrait également être utile comme outil de débogage d'utiliser un site tel que https://panopticlick.eff.org / pour vérifier l'originalité de votre navigateur; il vous aidera également à vérifier s'il y a des paramètres spécifiques qui indiquent que vous êtes en cours d'exécution en sélénium.

5
répondu lfaraone 2015-10-25 22:01:14

On dirait qu'ils sont derrière un pare-feu applicatif web. Regardez modsecurity et owasp pour voir comment cela fonctionne. En réalité, ce que vous demandez est comment faire la détection de bot evasion. Ce n'est pas à cela que sert le pilote web de sélénium. Il est pour tester votre application web ne frappant pas d'autres applications web. C'est possible, mais en gros, vous devriez regarder ce qu'un WAF cherche dans leur ensemble de règles et l'éviter spécifiquement avec le sélénium si vous le pouvez. Même alors, il pourrait encore ne pas travailler parce que vous ne savez pas ce WAF qu'ils utilisent. Vous avez fait la bonne première étape, c'est-à-dire simuler l'agent utilisateur. Si cela n'a pas fonctionné, alors un WAF est en place et vous devez probablement obtenir plus délicat.

Edit: Point tiré d'une autre réponse. Assurez-vous que votre User agent est effectivement réglé correctement en premier. Peut-être qu'il a frappé un serveur web local ou renifler le trafic sortant.

4
répondu Bassel Samman 2015-10-23 23:53:12

Firefox est dit window.navigator.webdriver === true si vous travaillez avec un webdriver. C'était selon l'une des spécifications plus anciennes (par exemple: archive.org ) mais je ne l'ai pas trouvé dans le nouveau à l'exception d'une formulation très vague dans les annexes.

un test pour cela est dans le code de sélénium dans le fichier fingerprint_test.js où le commentaire à la fin dit "actuellement seulement mis en œuvre dans firefox" mais je il n'a pas été possible d'identifier de code dans cette direction avec un simple grep ing, ni dans L'arbre de libération de Firefox (41.0.2) ni dans L'arbre à Chrome.

j'ai aussi trouvé un commentaire pour un vieux commit concernant les empreintes digitales dans le pilote firefox b82512999938 de janvier 2015 . Ce code est toujours dans le Selenium GIT-master téléchargé hier à javascript/firefox-driver/extension/content/server.js avec un commentaire lié à l'annexe légèrement différente dans le spécifications actuelles du webdriver w3c.

3
répondu deamentiaemundi 2015-10-27 23:44:32

la détection bot que j'ai vue semble plus sophistiquée ou du moins différente de ce que j'ai lu dans les réponses ci-dessous.

expérience 1:

  1. j'ouvre un navigateur et une page web avec Selenium à partir d'une console Python.
  2. la souris est déjà à un endroit spécifique où je sais qu'un lien apparaîtra une fois la page chargée. Je ne déplace jamais la souris.
  3. j'appuie une fois sur le bouton gauche de la souris (ceci est nécessaire pour prendre le focus de la console où Python tourne vers le navigateur).
  4. j'appuie de nouveau sur le bouton gauche de la souris (rappelez-vous que le curseur est au-dessus d'un lien donné).
  5. Le lien s'ouvre normalement, comme il se doit.

expérience 2:

  1. Comme avant, j'ouvre un navigateur et le web page avec Selenium à partir d'une console Python.

  2. Cette fois, au lieu de cliquer avec la souris, j'utilise le Sélénium (dans la console Python) cliquer sur le même élément avec un décalage aléatoire.

  3. Le lien ne s'ouvre pas, mais je suis pris d'une page d'inscription.

IMPLICATIONS:

  • ouvrir un web navigateur via le sélénium ne m'empêche pas d'apparaître humain
  • il n'est pas nécessaire de déplacer la souris comme un humain pour être classé comme humain
  • cliquer sur quelque chose via le sélénium avec un décalage déclenche encore l'alarme

semble mystérieux, mais je suppose qu'ils peuvent juste déterminer si une action provient du sélénium ou non, alors qu'ils ne se soucient pas si le navigateur lui-même a été ouvert via le sélénium ou non. Ou peuvent-ils déterminer si la fenêtre a une mise au point? Serait intéressant d'entendre si quelqu'un a des idées.

3
répondu M3RS 2018-07-20 11:24:30

écrivez une page html avec le code suivant. Vous verrez que dans le DOM selenium applique un attribut webdriver dans le 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
répondu PC3TJ 2015-10-28 04:10:54

certains sites détectent ceci:

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
répondu Néstor Lim 2017-08-22 09:52:33