Issue
I am using selenium chromeDriver for automated testing. But I cannot "hide" the window.navigator.webdriver
property. When I open chrome(v64-80.0.3987.100) through the driver, it always returns true when viewed in the console. Here is my code:
System.setProperty("webdriver.firefox.marionette", "false");
System.setProperty("webdriver.chrome.driver", webDriverPath);
ChromeOptions options = new ChromeOptions();
options.addArguments("--no-sandbox");
options.addArguments("--disable-extensions");
options.addArguments("--blink-settings=imagesEnabled=false");
options.addArguments("--disable-infobars");
options.addArguments("--disable-dev-shm-usage");
options.setExperimentalOption("useAutomationExtension", false);
options.addArguments("--incognito");
options.addArguments("--start-maximized");
options.setExperimentalOption("excludeSwitches", new String[]{"enable-automation"});
options.addArguments("--lang=zh-CN,zh,en");
options.addArguments("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36");
options.addArguments("--window-size=1920,1080");
ChromeDriver driver = new ChromeDriver(options);
driver.executeScript("Object.defineProperty(navigator, \"webdriver\", {\n" + " get() { return undefined; },\n" + " set(v) { return v; },\n" + " configurable: true,\n" + " enumerable: false\n" + "});");
driver.manage().timeouts().pageLoadTimeout(30L, TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(5L, TimeUnit.SECONDS);
If I use a lower version of chrome (like v64-76.0.3809.100), it returns undefined. Can anyone help me?
Solution
The presence of the window.navigator.webdriver
property is mandated by the W3C WebDriver Specification. It is both a security feature and a feature to allow better testability of web pages. If you are attempting to automate a page with a WebDriver-powered bot, and you do not own the page being automated, and you are attempting to hide the fact that you’re using a bot from the page’s owners, that is exactly the kind of thing that the property is intended to expose.
It looks like the developers of Chrome and chromedriver have now closed the security loophole they had allowed in previous versions. I suppose it’s possible you could build your own hacked version of the browser and the driver to not set that property when browsing sites with WebDriver, but that would be the only way.
As an editorial comment, attempting to hide browsing by a WebDriver-powered bot is most often a fool’s errand. There are multiple ways of detecting such a bot beyond the navigator.webdriver
property, and it would be nearly impossible to mask them all. Even if it appeared to work for awhile, eventually, the site in question will come up with more detection mechanisms. Moreover, such activity more than likely violates the Terms of Service of nearly any site one would care to attempt this for. It would be far better to find another mechanism for accomplishing your goal.
Answered By - JimEvans
Answer Checked By - Marie Seifert (JavaFixing Admin)