Un site Web peut-il détecter quand vous utilisez du sélénium avec chromedriver?

365

J'ai testé Selenium avec Chromedriver et j'ai remarqué que certaines pages peuvent détecter que vous utilisez Selenium même s'il n'y a aucune automatisation. Même lorsque je navigue simplement manuellement en utilisant Chrome via Selenium et Xephyr, je reçois souvent une page disant qu'une activité suspecte a été détectée. J'ai vérifié mon agent utilisateur et mon empreinte digitale de navigateur, et ils sont tous exactement identiques au navigateur Chrome normal.

Lorsque je navigue sur ces sites en chrome normal, tout fonctionne bien, mais au moment où j'utilise Selenium, je suis détecté.

En théorie, chromedriver et chrome devraient avoir exactement la même apparence pour tout serveur Web, mais d'une manière ou d'une autre, ils peuvent le détecter.

Si vous voulez du code de test, essayez 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 demandes. J'ai enquêté sur cela et je ne peux pas comprendre comment ils peuvent dire qu'un utilisateur utilise Selenium.

Comment font-ils?

MODIFIER LA MISE À JOUR:

J'ai installé le plugin Selenium IDE dans Firefox et j'ai été banni lorsque je suis allé sur stubhub.com dans le navigateur Firefox normal avec uniquement le plugin supplémentaire.

ÉDITER:

Lorsque j'utilise Fiddler pour afficher les requêtes HTTP envoyées d'avant en arrière, j'ai remarqué que les demandes de «faux navigateur» ont souvent «sans cache» dans l'en-tête de la réponse.

ÉDITER:

des résultats comme celui - ci Existe - t-il un moyen de détecter que je suis dans une page Selenium Webdriver à partir de Javascript suggère qu'il ne devrait y avoir aucun moyen de détecter lorsque vous utilisez un webdriver. Mais ces preuves suggèrent le contraire.

ÉDITER:

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 du chrome.

ÉDITER:

Il s'agit de l'une des charges utiles d'empreintes digitales 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

ÉDITER:

Les VPN fonctionnent pour un usage unique mais sont détectés après le chargement de la première page. De toute évidence, certains javascript sont en cours d'exécution pour détecter le sélénium.

Ryan Weinstein
la source
4
@RyanWeinstein: Ce n'est pas du trafic. Je suppose que Selenium doit exposer certains crochets JavaScript qui peuvent être détectés sur le JavaScript côté client.
Mikko Ohtamaa
5
Ou s'il s'agit de trafic, c'est un modèle de trafic ... vous parcourez les pages trop rapidement.
Mikko Ohtamaa
6
Je ne navigue pas trop vite. Je ne charge qu'une seule page et je la parcours normalement à l'aide de ma souris et de mon clavier. De plus, cela n'a pas de sens que Selenium doive exposer les crochets, car il exécute littéralement chrome.exe. Il exécute simplement le chrome normal et vous permet d'en obtenir des données. D'autres idées? Je pensais que cela avait peut-être quelque chose à voir avec les cookies. Ça me rend fou.
Ryan Weinstein
5
Ce site utilise la distilltechnologie de détection de bots et fournit du contenu en utilisant akamaitechnologies.comCDN de diffrent ips par exemple 95.100.59.245, 104.70.243.66,23.202.161.241
SIslam
5
Je rencontre le même problème avec Selenium et le pilote Firefox. La chose intéressante à noter est que j'exécute Selenium dans une machine virtuelle VMWare Workstation qui accède à Internet via un NAT. La machine hôte peut accéder à stubhub, tandis que la machine virtuelle ne peut pas accéder lors de l'utilisation de Selenium, ou même de l'instance de navigateur lancée par Selenium. J'ai fait bloquer l'instance de VM Browser et stubhub reconnaît toujours la machine et l'a bloquée. Il doit donc effectuer une empreinte digitale du navigateur et de la machine d'une manière ou d'une autre.
Brian Cain

Réponses:

55

Pour les utilisateurs Mac

Remplacement d'une cdc_variable à l'aide de Vim ou Perl

Vous pouvez utiliser vim, ou comme @Vic Seedoubleyew l'a souligné dans la réponse de @ Erti-Chris Eelmaa, perlpour remplacer la cdc_variable dans chromedriver( Voir l'article de @ Erti-Chris Eelmaa pour en savoir plus sur cette variable ). Utiliser vimou perlvous évite d'avoir à recompiler le code source ou à utiliser un éditeur hexadécimal. Assurez-vous de faire une copie de l'original chromedriveravant de tenter de le modifier. De plus, les méthodes ci-dessous ont été testées chromedriver version 2.41.578706.


Utiliser Vim

vim /path/to/chromedriver

Après avoir exécuté la ligne ci-dessus, vous verrez probablement un tas de charabia. Procédez comme suit:

  1. Recherchez cdc_en tapant /cdc_et en appuyant sur return.
  2. Activez l'édition en appuyant sur a.
  3. Supprimez tout montant $cdc_lasutopfhvcZLmcflet remplacez ce qui a été supprimé par un nombre égal de caractères. Si vous ne le faites pas, chromedriveréchouera.
  4. Une fois l'édition terminée, appuyez sur esc.
  5. Pour enregistrer les modifications et quitter, tapez :wq!et appuyez sur return.
  6. Si vous ne souhaitez pas enregistrer les modifications, mais que vous souhaitez quitter, tapez :q!et appuyez sur return.
  7. Vous avez terminé.

Accédez à la modification chromedriveret double-cliquez dessus. Une terminalfenêtre devrait s'ouvrir. Si vous ne voyez pas killeddans la sortie, vous avez réussi à modifier le pilote.


Utiliser Perl

La ligne ci-dessous remplace cdc_par 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 l' chromedriveréchec.

Explication de Perl

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

par exemple, s/string/replacment/g

Donc,

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 de 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 renvoie rien, alors cdc_a été remplacé.

Inversement, vous pouvez utiliser ceci:

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

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

Accédez à la modification chromedriveret double-cliquez dessus. Une terminalfenêtre devrait s'ouvrir. Si vous ne voyez pas killeddans la sortie, vous avez réussi à modifier le pilote.


Emballer

Après avoir modifié le chromedriverbinaire, assurez-vous que le nom du chromedriverbinaire modifié est chromedriveret que le binaire d'origine est soit déplacé de son emplacement d'origine, soit renommé.


Mon expérience avec cette méthode

J'étais précédemment détecté sur un site Web alors que j'essayais de me connecter, mais après le remplacement cdc_par une chaîne de taille égale, j'ai pu me connecter. Comme d'autres l'ont dit cependant, si vous avez déjà été détecté, vous pourriez être bloqué pour un pléthore d'autres raisons, même après avoir utilisé cette méthode. Vous devrez donc peut-être essayer d'accéder au site qui vous détectait à l'aide d'un VPN, d'un réseau différent ou de quoi d'autre.

colossatr0n
la source
@LekaBaper Merci pour l'avertissement. La version chromedriver que j'ai utilisée était la version 2.41.578706.
colossatr0n
2
N'a pas fonctionné même lorsque j'ai utilisé cette modification chromedriver.exe sur un nouvel ordinateur physique sur un réseau différent.
Ahmed Memon
c'est donner une erreur dit, cette version ne peut pas fonctionner dans cet ordinateur :(
Walid Bousseta
@ colossatr0n Y a-t-il un fork open-source indétectable que vous connaissez?
ishandutta2007
3
Notez que les gens de chromedriver ont déclaré que ce problème ne serait pas résolu, vous pouvez donc vous attendre à devoir utiliser un fork ou éditer le binaire pour un avenir indéfini. bugs.chromium.org/p/chromedriver/issues/detail?id=3220
Kodiologue
144

Fondamentalement, le fonctionnement de la détection du sélénium consiste à tester les variables javascript prédéfinies qui apparaissent lors de l'exécution avec du sélénium. Les scripts de détection de bot regardent généralement tout ce qui contient le mot "sélénium" / "webdriver" dans l'une des variables (sur l'objet fenêtre), et documentent également les variables appelées $cdc_et $wdc_. Bien sûr, tout cela dépend du navigateur sur lequel vous vous trouvez. Tous les différents navigateurs exposent des choses différentes.

Pour moi, j'ai utilisé le chrome, donc, tout ce que j'avais à faire était de m'assurer qu'il $cdc_n'existait plus en tant que variable de document, et le tour est joué (télécharger le code source de chromedriver, modifier chromedriver et recompiler $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, je me suis tourné $cdc_vers tout ce que j'ai fait randomblabla_.

Voici un pseudo-code qui illustre certaines des techniques que les réseaux de robots 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 de faire le remplacement manuellement, sans réellement effectuer de compilation.

Erti-Chris Eelmaa
la source
26
Oui, cela a fonctionné sans problème, notez qu'un problème est que si vous tombez dans la "liste noire" AVANT ce changement, il est assez difficile de sortir. si vous voulez sortir de la liste noire existante, vous devez implémenter les empreintes digitales de faux canevas, désactiver le flash, changer l'IP et changer l'ordre des en-têtes de demande (swap language et Accept headers). Une fois que vous êtes tombé dans la liste noire, ils ont de très bonnes mesures pour vous suivre, même si vous changez IP, même si vous ouvrez Chrome dans incognito, etc.
Erti-Chris Eelmaa
2
J'ai trouvé le fichier "/ Users / your_username / chrome / src / chrome / test / chromedriver / js"
JonghoKim
7
J'ai simplement remplacé $cdcpar xxxxdans chromedriver.exeun éditeur hexadécimal et cela a fonctionné! J'ai également remarqué que si vous maximisez la fenêtre du navigateur (plutôt que d'utiliser une taille prédéfinie), elle est détectée moins souvent.
szx
2
était-ce sur windows, osx ou linux? L'édition hexadécimale sur osx ne semble pas fonctionner.
Nish
5
hex-édité avec $ zzz_zzzzzzzzzzzzzzzzzzzzzz_ (même quantité de caractères) mais n'a pas fonctionné.
Aymon Fournier
100

Comme nous l'avons déjà compris dans la question et les réponses publiées, il y a un anti-Web-scraping et un service de détection de Bot appelé "Distil Networks" en jeu ici. Et, selon l' interview du PDG de l'entreprise :

Même s'ils peuvent créer de nouveaux bots, nous avons trouvé un moyen d'identifier Selenium l'outil qu'ils utilisent, nous bloquons donc Selenium quel que soit le nombre de fois qu'ils itèrent sur ce bot . Nous le faisons maintenant avec Python et beaucoup de technologies différentes. Une fois que nous voyons un modèle émerger d'un type de bot, nous travaillons pour inverser la technologie qu'ils utilisent et l'identifier comme malveillant.

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

  • ce n'est pas lié aux actions que vous prenez avec le sélénium - une fois que vous accédez au site, vous êtes immédiatement détecté et banni. J'ai essayé d'ajouter des retards aléatoires artificiels entre les actions, faites une pause après le chargement de la page - rien n'y fait
  • il ne s'agit pas non plus d'empreintes digitales du navigateur - essayé dans plusieurs navigateurs avec des profils propres et non, des modes de navigation privée - rien n'y fait
  • puisque, selon l'indice de l'interview, il s'agissait de «rétro-ingénierie», je soupçonne que cela se fait avec du code JS en cours d'exécution dans le navigateur, révélant qu'il s'agit d'un navigateur automatisé via un sélecteur Web sélénium

Décidé de l'afficher comme réponse, car clairement:

Un site Web peut-il détecter quand vous utilisez du sélénium avec chromedriver?

Oui.


De plus, ce que je n'ai pas expérimenté, c'est du sélénium plus ancien et des versions de navigateur plus anciennes - en théorie, il pourrait y avoir quelque chose implémenté / ajouté au sélénium à un certain moment sur lequel le détecteur de bots de Distil Networks s'appuie actuellement. Ensuite, si tel est le cas, nous pourrions détecter (oui, détectons le détecteur) à quel point / version un changement pertinent a été effectué, consulter le journal des modifications et les changesets et, peut-être, cela pourrait nous donner plus d'informations sur où chercher et qu'est-ce qu'ils utilisent pour détecter un navigateur propulsé par un pilote Web. C'est juste une théorie qui doit être testée.

alecxe
la source
@RyanWeinstein bien, nous n'avons aucune preuve réelle et nous ne pouvons que spéculer et tester. Pour l'instant, je dirais qu'ils ont un moyen de nous détecter en utilisant du sélénium. Essayez d'expérimenter avec des versions au sélénium - cela peut vous donner quelques indices.
alecxe
1
Cela pourrait-il avoir à voir avec la façon dont les ports éphémères sont déterminés? La méthode reste à l'écart des plages bien connues. github.com/SeleniumHQ/selenium/blob/…
Elliott de Launay
9
Easyjet utilise le service distilnetwork, oui, il peut bloquer les robots factices, mais pas les robots compliqués, car nous l'avons testé avec plus de 2000 demandes par jour de différentes adresses IP (que nous réutilisons à nouveau la même adresse), donc fondamentalement, chaque adresse IP va pour 5 à 10 demandes par jour et je peux dire que tous ces services de détection de bots sont juste là pour développer et vendre des algorithmes de travail à 45%, le scrapper que nous avons utilisé était facile à détecter, je peux le bloquer pendant que destilnetworks, squareshield et autres ne pouvait pas ce qui m'a poussé à ne jamais utiliser l'un d'eux.
Jeffery ThaGintoki
3
Je pense qu'ils détectent navigator.webdriver dans chrome webdriver. J'ai essayé de faire navigator.webdriver = false avec l'aide de intoli.com/blog/not-possible-to-block-chrome-headless et stackoverflow.com/questions/47297877/… . Il renvoie une page de détection de bot au lieu de distilnetworks.com/distil_identify_cookie.html
hoozecn
24

Exemple de mise 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 !+""
aianitro
la source
13
pourquoi le dernier essai n'est-il pas clos? d'ailleurs pouvez-vous expliquer un peu votre réponse.
ishandutta2007
16

Obscurcissement du résultat JavaScripts

J'ai vérifié le code source de chromedriver. Cela injecte des fichiers javascript dans le navigateur.
Chaque fichier javascript de ce lien est injecté dans les pages Web: https://chromium.googlesource.com/chromium/src/+/master/chrome/test/chromedriver/js/

J'ai donc utilisé l'ingénierie inverse et masqué les fichiers js par l'édition Hex. Maintenant, j'étais sûr qu'aucune variable javascript, nom de fonction et chaîne fixe n'était utilisée pour découvrir l'activité du sélénium. Mais encore certains sites et reCaptcha détectent le sélénium!
Peut-être vérifient-ils les modifications causées par l'exécution de chromedriver js :)


Modifier 1:

Modification des paramètres du «navigateur» de Chrome

J'ai découvert qu'il y a quelques paramètres dans «navigateur» qui découvrent brièvement l'utilisation de chromedriver. Ce sont les paramètres:

  • "navigator.webdriver" En mode non automatisé, il est "non défini". En mode automatisé, c'est «vrai».
  • "navigator.plugins" Sur chrome sans tête a 0 longueur. J'ai donc ajouté de faux éléments pour tromper le processus de vérification de la longueur du plugin.
  • " navigator.languages" a été défini sur la valeur de chrome par défaut '["en-US", "en", "es"]'.

Donc, ce dont j'avais besoin était une extension chrome pour exécuter javascript sur les pages Web. J'ai fait une extension avec le code js fourni dans l'article et utilisé un autre article pour ajouter l'extension zippée à mon projet.J'ai réussi à changer les valeurs; Mais toujours rien n'a changé!

Je n'ai pas trouvé d'autres variables comme celles-ci mais cela ne signifie pas qu'elles n'existent pas. ReCaptcha détecte toujours le chromedriver, il devrait donc y avoir plus de variables à changer. La prochaine étape devrait être l'ingénierie inverse des services de détection que je ne veux pas faire.

Maintenant, je ne sais pas si cela vaut la peine de passer plus de temps sur ce processus d'automatisation ou de rechercher des méthodes alternatives!

ShayanKM
la source
12

Essayez d'utiliser du sélénium avec un profil 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 fonctionnera en tant qu'utilisateur réel, regardez le processus chrome avec un explorateur de processus et vous verrez la différence avec les balises.

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)

liste de balises chrome ici

Kobi K
la source
11

partial interface Navigator { readonly attribute boolean webdriver; };

L'attribut Webdriver IDL de l'interface Navigator doit renvoyer la valeur de l'indicateur webdriver-active, qui est initialement fausse.

Cette propriété permet aux sites Web de déterminer que l'agent utilisateur est sous contrôle de WebDriver et peut être utilisée pour atténuer les attaques par déni de service.

Tiré directement de la version préliminaire de WebDriver de l'éditeur W3C 2017 . Cela implique fortement que, à tout le moins, les futures itérations des pilotes de sélénium seront identifiables pour éviter les abus. En fin de compte, il est difficile de dire sans le code source, ce qui fait que le pilote Chrome en particulier est détectable.

Bryce
la source
4
"c'est difficile à dire sans le code source" .. et bien le code source est disponible gratuitement
Corey Goldberg
6
Je voulais dire sans le code source du site Web en question. Il est difficile de dire contre quoi ils vérifient.
bryce
8

Firefox est censé window.navigator.webdriver === truefonctionner si vous travaillez avec un pilote Web. C'était selon l'une des spécifications les plus anciennes (par exemple: archive.org ) mais je ne pouvais pas le trouver dans le nouveau sauf pour une formulation très vague dans les annexes.

Un test pour cela se trouve dans le code sélénium dans le fichier fingerprint_test.js où le commentaire à la fin dit "Actuellement uniquement implémenté dans firefox" mais je n'ai pas pu identifier de code dans cette direction avec une simple greping, ni dans le version actuelle (41.0.2) de l'arborescence des versions de Firefox ni dans l'arborescence Chromium.

J'ai également trouvé un commentaire pour un commit plus ancien 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 sur javascript/firefox-driver/extension/content/server.jsavec un commentaire reliant à l'appendice légèrement différent dans la spécification actuelle du pilote Web w3c.

deamentiaemundi
la source
2
Je viens de tester un pilote Web avec Firefox 55 et je peux confirmer que ce n'est pas vrai. La variable window.navigator.webdrivern'est pas définie.
speedplane
1
Mise à jour: j'ai testé avec Firefox 65, et c'est vrai:window.navigator.webdriver == true
speedplane
La version 76 de Firefox montre toujours que c'est vrai
user2284144
8

En plus de l'excellente réponse de @ Erti-Chris Eelmaa - il est ennuyeux window.navigator.webdriveret il est en lecture seule. L'événement si vous en changez la valeur falseaura toujours true. C'est pourquoi le navigateur piloté par un logiciel automatisé peut toujours être détecté. MDN

La variable est gérée par le drapeau --enable-automationen chrome. Les lancements de chromedriver chrome avec le drapeau et le chrome définit le window.navigator.webdriverà true. Vous pouvez le trouver ici . Vous devez ajouter à "exclure les commutateurs" le drapeau. Par exemple (golang):

package main

import (
    "github.com/tebeka/selenium"
    "github.com/tebeka/selenium/chrome"
)

func main() {

caps := selenium.Capabilities{
    "browserName": "chrome",
}

chromeCaps := chrome.Capabilities{
    Path:            "/path/to/chrome-binary",
    ExcludeSwitches: []string{"enable-automation"},
}
caps.AddChrome(chromeCaps)

wd, err := selenium.NewRemote(caps, fmt.Sprintf("http://localhost:%d/wd/hub", 4444))
}
FDG
la source
6

On dirait qu'ils sont derrière un pare-feu d'application Web. Jetez un oeil à modsecurity et owasp pour voir comment ceux-ci fonctionnent. En réalité, ce que vous demandez, c'est comment faire pour éviter la détection des bots. Ce n'est pas à cela que sert le pilote Web sélénium. C'est pour tester votre application web sans frapper d'autres applications web. C'est possible, mais fondamentalement, vous devez regarder ce qu'un WAF recherche dans son ensemble de règles et l'éviter spécifiquement avec du sélénium si vous le pouvez. Même alors, cela pourrait ne pas fonctionner car vous ne savez pas quel WAF ils utilisent. Vous avez fait la bonne première étape, c'est-à-dire truquer l'agent utilisateur. Si cela n'a pas fonctionné, alors un WAF est en place et vous devrez probablement devenir plus délicat.

Edit: Point tiré d'une autre réponse. Assurez-vous d'abord que votre agent utilisateur est correctement configuré. Peut-être le faire frapper un serveur Web local ou renifler le trafic sortant.

Bassel Samman
la source
Je pense que vous êtes sur la bonne voie. J'ai testé avec ma configuration et remplacé l'agent utilisateur par une chaîne d'agent utilisateur valide qui a réussi et reçu le même résultat, stubhub a bloqué la demande.
Brian Cain
1
Ce sujet est très vaste, je dirais que si vous ne le comprenez pas et que vous voulez le comprendre, ce n'est pas le bon endroit. Commencez par owasp. Examinez les tests de pénétration et la sécurité Web. En outre, comme je l'ai déjà dit, examinez la modsécurité et le WAF pour spécifiquement ce sujet.
Bassel Samman
1
S'il s'agissait d'un problème d'en-tête HTTP, le navigateur normal ne serait-il pas bloqué? Les en-têtes HTTP sont exactement les mêmes. Aussi qu'est-ce que je regarde exactement avec ce lien github? Avez-vous essayé d'utiliser du sélénium pour aller sur stubhub? Quelque chose est très très différent.
Ryan Weinstein du
1
Je suis désolé pour la confusion. J'examinerai cela et vous n'avez plus besoin de m'aider si vous ne le souhaitez pas. La plupart de mon expérience est dans la programmation d'applications de systèmes, donc je ne connaissais pas ces règles de sécurité mods dont vous parlez. Je vais jeter un œil et essayer de m'instruire. Je n'essaie pas de contourner quoi que ce soit, je voulais simplement savoir comment ces sites Web détectent un utilisateur utilisant du sélénium.
Ryan Weinstein
1
Je suis aussi développeur :). L'apprentissage est une cause à laquelle je peux me rallier. Cela ne me dérange pas d'aider, je voulais juste préciser que je ne connaissais pas vos intentions et ne pouvais pas exactement vous aider à contourner la sécurité de leur site Web. Mais pour répondre à votre question, ce n'est pas le sélénium qu'ils détectent. Les règles ont détecté un comportement suspect et décidé de prendre les mesures appropriées contre le client incriminé. Ils vous attrapent plus par ce que vous ne faites pas que par ce que vous faites. Dans le lien repo, vous pouvez extraire ce fichier pour vous faire une idée base_rules / modsecurity_crs_20_protocol_violations.conf
Bassel Samman
6

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

Par exemple, visiter un site, puis immédiatement effectuer une action en déplaçant la souris directement sur le bouton correspondant, en moins d'une seconde, est quelque chose qu'aucun utilisateur ne ferait réellement.

Il peut également être utile en tant qu'outil de débogage d'utiliser un site tel que https://panopticlick.eff.org/ pour vérifier le caractère unique de votre navigateur; cela vous aidera également à vérifier s'il existe des paramètres spécifiques qui indiquent que vous exécutez dans Selenium.

lfaraone
la source
3
J'ai déjà utilisé ce site Web et l'empreinte digitale est identique à mon navigateur normal. De plus, je n'automatise rien. Je navigue comme d'habitude.
Ryan Weinstein,
6

La détection de bot que j'ai vue semble plus sophistiquée ou au 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 précis où je sais qu'un lien apparaîtra une fois la page chargée. Je ne bouge jamais la souris.
  3. J'appuie une fois sur le bouton gauche de la souris (cela est nécessaire pour se concentrer de la console sur laquelle Python s'exécute vers le navigateur).
  4. J'appuie à nouveau sur le bouton gauche de la souris (rappelez-vous, le curseur est au-dessus d'un lien donné).
  5. Le lien s'ouvre normalement, comme il se doit.

EXPÉRIENCE 2:

  1. Comme précédemment, j'ouvre un navigateur et la page Web avec Selenium à partir d'une console Python.

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

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

IMPLICATIONS:

  • l'ouverture d'un navigateur Web via Selenium 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 Selenium avec un décalage déclenche toujours l'alarme

Cela semble mystérieux, mais je suppose qu'ils peuvent simplement déterminer si une action provient de Selenium ou non, alors qu'ils ne se soucient pas de savoir si le navigateur lui-même a été ouvert via Selenium ou non. Ou peuvent-ils déterminer si la fenêtre a le focus? Serait intéressant d'entendre si quelqu'un a des idées.

M3RS
la source
3
Ma conviction est que Selenium injecte quelque chose dans la page via javascript pour trouver et accéder aux éléments. Cette injection est ce que je crois qu'ils détectent.
zeusalmighty
Vous avez raison, ce test est 100% valide. J'avais fait un test similaire avec les mêmes résultats. Je pourrais envoyer l'onglet Entrée ou envoyer des clés. Au moment où j'accède aux éléments, la page a cessé de fonctionner. Donc, si le pilote injecte du javascript dans le navigateur. Nous pourrions simplement crypter ce javascript en utilisant l'extension chrome et décrypter sur la page suivante en utilisant la même extension. J'essaierai de l'examiner les jours suivants.
trixo
6

Une autre chose que j'ai trouvée est que certains sites Web utilisent une plate-forme qui vérifie l'agent utilisateur. Si la valeur contient: "HeadlessChrome", le comportement peut être étrange lors de l'utilisation du mode sans tête.

La solution consiste à remplacer la valeur de l'agent utilisateur, par exemple en Java:

chromeOptions.addArguments("--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36");
Adi Ohana
la source
5

Certains sites le détectent:

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) {}
Néstor
la source
Cela ne fonctionne pas pour Chrome et Firefox, sélénium 3.5.0, ChromeDriver 2.31.488774, geckodriver 0.18.0
jerrypy
4

Écrivez une page html avec le code suivant. Vous verrez que dans le sélénium DOM applique un attribut webdriver dans le HTML externe

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

PC3TJ
la source
4
L'attribut est ajouté uniquement dans Firefox.
Louis
1
Et il est possible de le supprimer de l'extension sélénium qui contrôle le navigateur. Cela fonctionnera de toute façon.
m3nda
3

J'ai trouvé la modification de la variable "clé" javascript comme ceci:

//Fools the website into believing a human is navigating it
        ((JavascriptExecutor)driver).executeScript("window.key = \"blahblah\";");

fonctionne pour certains sites Web lors de l'utilisation de Selenium Webdriver avec Google Chrome, car de nombreux sites recherchent cette variable afin d'éviter d'être mis au rebut par Selenium.

Juliagu
la source
2

Il me semble que le moyen le plus simple de le faire avec Selenium est d'intercepter le XHR qui renvoie l'empreinte digitale du navigateur.

Mais comme il s'agit d'un problème de sélénium uniquement, il vaut mieux utiliser autre chose. Le sélénium est censé rendre les choses comme ça plus faciles, pas beaucoup plus difficiles.

pguardiario
la source
Quelles sont les autres options pour le sélénium?
Tai
Je suppose que les requêtes seraient l'option principale de python. Si vous envoyez les mêmes demandes exactes que celles envoyées par votre navigateur, vous apparaîtrez comme un navigateur normal.
pguardiario
2

Vous pouvez essayer d'utiliser le paramètre "enable-automation"

var options = new ChromeOptions();

// hide selenium
options.AddExcludedArguments(new List<string>() { "enable-automation" });

var driver = new ChromeDriver(ChromeDriverService.CreateDefaultService(), options);

Mais, je tiens à vous avertir que cette capacité a été corrigée dans ChromeDriver 79.0.3945.16 . Donc, vous devriez probablement utiliser des versions plus anciennes de Chrome.

En outre, comme autre option, vous pouvez essayer d'utiliser InternetExplorerDriver au lieu de Chrome. Quant à moi, IE ne bloque pas du tout sans aucun piratage.

Et pour plus d'informations, essayez de jeter un œil ici:

Webdriver au sélénium: modification de l'indicateur navigator.webdriver pour empêcher la détection du sélénium

Impossible de masquer l'infobar "Chrome est contrôlé par un logiciel automatisé" dans Chrome v76

Sergiy Matvienko
la source