反爬虫類中のchrome無頭ブラウザのいくつかの検出と迂回方式
4536 ワード
chromeヘッドレスブラウザのいくつかの検出方法
本試験で使用したchromeバージョンはMozilla/5.0(Macintosh;Intel Mac OS X 10_12_6)AppleWebKit/53.36(KHTML,like Gecko)Chrome/70.0.3514.2 Safari/53.36
1.UserAgent検出
ヘッドレスモードのUAにはHeadlessChromeキーが付きますMozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/70.0.3521.2 Safari/537.36
UAのキーワードをチェックすることができますif (/HeadlessChrome/.test(navigator.userAgent)) {
// headless...
}
2.Webdriver検出
ヘッドレスモードでnavigator.webdriverはtrueであるため、以下のような検出が可能である.// Webdriver Test
if (navigator.webdriver) {
// headless...
}
この検出を迂回するために、この属性を再設定すればよい.Object.defineProperty(navigator, 'webdriver', {
get: () => false,
});
プロトタイプからこのプロパティを削除することを推奨しますdelete navigator.__proto__.webdriver;
补充说明:大麦网または淘宝网のスライダ検証コードはまず環境を検出し、通常はsufei_を利用する.Dataファイルは現在のブラウザ情報を検出し、webdriverコードは以下のように検出される. function r() {
return "$cdc_asdjflasutopfhvcZLmcfl_"in u || f.webdriver
}
// ,
// https://g.alicdn.com/secdev/sufei_data/3.6.8/index.js
したがって、スライダをドラッグしようとするときは、まずこのアトリビュートを変更します.そうでなければ、パスを変更する方法でエラーが表示され、再試行が要求されます.
3.chrome属性検出
ヘッドレスモードでwindow.chromeプロパティはundefinedですが、通常のインタフェースモードでは、以下のように定義されます.csi: ƒ ()
embeddedSearch: {searchBox: {…}, newTabPage: {…}}
loadTimes: ƒ ()
app: (...)
runtime: (...)
webstore: (...)
get app: ƒ nativeGetter()
set app: ƒ nativeSetter()
get runtime: ƒ nativeGetter()
set runtime: ƒ nativeSetter()
get webstore: ƒ nativeGetter()
set webstore: ƒ nativeSetter(
従って、以下のような検出が可能となるif (!window.chrome || !window.chrome.runtime) {
// headless...
}
検出を迂回して属性を変更すればよい window.navigator.chrome = {
runtime: {},
// etc.
};
4.Permissions検査 (async () => {
const permissionStatus = await navigator.permissions.query({ name: 'notifications' });
if(Notification.permission === 'denied' && permissionStatus.state === 'prompt') {
// headless
}
})();
ヘッドレスモードでpermissionとnavigatorpermissions.queryは逆の値を返します.そのため、迂回する方法は以下の通りです.// Pass the Permissions Test.
await page.evaluateOnNewDocument(() => {
const originalQuery = window.navigator.permissions.query;
return window.navigator.permissions.query = (parameters) => (
parameters.name === 'notifications' ?
Promise.resolve({ state: Notification.permission }) :
originalQuery(parameters)
);
});
5.Plugins長さ検出
ヘッドレスモードでnavigator.plugins.lengthは0を返しますif (navigator.plugins.length === 0) {
// headless
}
迂回方式は次の通りです.Object.defineProperty(navigator, 'plugins', {
get: () => [1, 2, 3, 4, 5],
});
注意:逆登りは長さのほかに、内容もチェックします.長さを設定したら、内容を設定するのを忘れないでください.逆登りを防ぐ.
6.The Languages検出
navigator.Languages検出方法if (!navigator.languages || navigator.languages.length === 0) {
// headless
}
迂回方法 Object.defineProperty(navigator, 'languages', {
get: () => ['en-US', 'en'],
});
7.原文アドレス
https://intoli.com/blog/not-possible-to-block-chrome-headless/https://intoli.com/blog/making-chrome-headless-undetectable/https://github.com/infosimples/detect-headless https://stackoverflow.com/questions/19877924/what-is-the-list-of-possible-values-for-navigator-platform-as-of-today
ヘッドレスモードのUAにはHeadlessChromeキーが付きます
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/70.0.3521.2 Safari/537.36
UAのキーワードをチェックすることができます
if (/HeadlessChrome/.test(navigator.userAgent)) {
// headless...
}
2.Webdriver検出
ヘッドレスモードでnavigator.webdriverはtrueであるため、以下のような検出が可能である.// Webdriver Test
if (navigator.webdriver) {
// headless...
}
この検出を迂回するために、この属性を再設定すればよい.Object.defineProperty(navigator, 'webdriver', {
get: () => false,
});
プロトタイプからこのプロパティを削除することを推奨しますdelete navigator.__proto__.webdriver;
补充说明:大麦网または淘宝网のスライダ検証コードはまず環境を検出し、通常はsufei_を利用する.Dataファイルは現在のブラウザ情報を検出し、webdriverコードは以下のように検出される. function r() {
return "$cdc_asdjflasutopfhvcZLmcfl_"in u || f.webdriver
}
// ,
// https://g.alicdn.com/secdev/sufei_data/3.6.8/index.js
したがって、スライダをドラッグしようとするときは、まずこのアトリビュートを変更します.そうでなければ、パスを変更する方法でエラーが表示され、再試行が要求されます.
3.chrome属性検出
ヘッドレスモードでwindow.chromeプロパティはundefinedですが、通常のインタフェースモードでは、以下のように定義されます.csi: ƒ ()
embeddedSearch: {searchBox: {…}, newTabPage: {…}}
loadTimes: ƒ ()
app: (...)
runtime: (...)
webstore: (...)
get app: ƒ nativeGetter()
set app: ƒ nativeSetter()
get runtime: ƒ nativeGetter()
set runtime: ƒ nativeSetter()
get webstore: ƒ nativeGetter()
set webstore: ƒ nativeSetter(
従って、以下のような検出が可能となるif (!window.chrome || !window.chrome.runtime) {
// headless...
}
検出を迂回して属性を変更すればよい window.navigator.chrome = {
runtime: {},
// etc.
};
4.Permissions検査 (async () => {
const permissionStatus = await navigator.permissions.query({ name: 'notifications' });
if(Notification.permission === 'denied' && permissionStatus.state === 'prompt') {
// headless
}
})();
ヘッドレスモードでpermissionとnavigatorpermissions.queryは逆の値を返します.そのため、迂回する方法は以下の通りです.// Pass the Permissions Test.
await page.evaluateOnNewDocument(() => {
const originalQuery = window.navigator.permissions.query;
return window.navigator.permissions.query = (parameters) => (
parameters.name === 'notifications' ?
Promise.resolve({ state: Notification.permission }) :
originalQuery(parameters)
);
});
5.Plugins長さ検出
ヘッドレスモードでnavigator.plugins.lengthは0を返しますif (navigator.plugins.length === 0) {
// headless
}
迂回方式は次の通りです.Object.defineProperty(navigator, 'plugins', {
get: () => [1, 2, 3, 4, 5],
});
注意:逆登りは長さのほかに、内容もチェックします.長さを設定したら、内容を設定するのを忘れないでください.逆登りを防ぐ.
6.The Languages検出
navigator.Languages検出方法if (!navigator.languages || navigator.languages.length === 0) {
// headless
}
迂回方法 Object.defineProperty(navigator, 'languages', {
get: () => ['en-US', 'en'],
});
7.原文アドレス
https://intoli.com/blog/not-possible-to-block-chrome-headless/https://intoli.com/blog/making-chrome-headless-undetectable/https://github.com/infosimples/detect-headless https://stackoverflow.com/questions/19877924/what-is-the-list-of-possible-values-for-navigator-platform-as-of-today
// Webdriver Test
if (navigator.webdriver) {
// headless...
}
Object.defineProperty(navigator, 'webdriver', {
get: () => false,
});
delete navigator.__proto__.webdriver;
function r() {
return "$cdc_asdjflasutopfhvcZLmcfl_"in u || f.webdriver
}
// ,
// https://g.alicdn.com/secdev/sufei_data/3.6.8/index.js
ヘッドレスモードでwindow.chromeプロパティはundefinedですが、通常のインタフェースモードでは、以下のように定義されます.
csi: ƒ ()
embeddedSearch: {searchBox: {…}, newTabPage: {…}}
loadTimes: ƒ ()
app: (...)
runtime: (...)
webstore: (...)
get app: ƒ nativeGetter()
set app: ƒ nativeSetter()
get runtime: ƒ nativeGetter()
set runtime: ƒ nativeSetter()
get webstore: ƒ nativeGetter()
set webstore: ƒ nativeSetter(
従って、以下のような検出が可能となる
if (!window.chrome || !window.chrome.runtime) {
// headless...
}
検出を迂回して属性を変更すればよい
window.navigator.chrome = {
runtime: {},
// etc.
};
4.Permissions検査 (async () => {
const permissionStatus = await navigator.permissions.query({ name: 'notifications' });
if(Notification.permission === 'denied' && permissionStatus.state === 'prompt') {
// headless
}
})();
ヘッドレスモードでpermissionとnavigatorpermissions.queryは逆の値を返します.そのため、迂回する方法は以下の通りです.// Pass the Permissions Test.
await page.evaluateOnNewDocument(() => {
const originalQuery = window.navigator.permissions.query;
return window.navigator.permissions.query = (parameters) => (
parameters.name === 'notifications' ?
Promise.resolve({ state: Notification.permission }) :
originalQuery(parameters)
);
});
5.Plugins長さ検出
ヘッドレスモードでnavigator.plugins.lengthは0を返しますif (navigator.plugins.length === 0) {
// headless
}
迂回方式は次の通りです.Object.defineProperty(navigator, 'plugins', {
get: () => [1, 2, 3, 4, 5],
});
注意:逆登りは長さのほかに、内容もチェックします.長さを設定したら、内容を設定するのを忘れないでください.逆登りを防ぐ.
6.The Languages検出
navigator.Languages検出方法if (!navigator.languages || navigator.languages.length === 0) {
// headless
}
迂回方法 Object.defineProperty(navigator, 'languages', {
get: () => ['en-US', 'en'],
});
7.原文アドレス
https://intoli.com/blog/not-possible-to-block-chrome-headless/https://intoli.com/blog/making-chrome-headless-undetectable/https://github.com/infosimples/detect-headless https://stackoverflow.com/questions/19877924/what-is-the-list-of-possible-values-for-navigator-platform-as-of-today
(async () => {
const permissionStatus = await navigator.permissions.query({ name: 'notifications' });
if(Notification.permission === 'denied' && permissionStatus.state === 'prompt') {
// headless
}
})();
// Pass the Permissions Test.
await page.evaluateOnNewDocument(() => {
const originalQuery = window.navigator.permissions.query;
return window.navigator.permissions.query = (parameters) => (
parameters.name === 'notifications' ?
Promise.resolve({ state: Notification.permission }) :
originalQuery(parameters)
);
});
ヘッドレスモードでnavigator.plugins.lengthは0を返します
if (navigator.plugins.length === 0) {
// headless
}
迂回方式は次の通りです.
Object.defineProperty(navigator, 'plugins', {
get: () => [1, 2, 3, 4, 5],
});
注意:逆登りは長さのほかに、内容もチェックします.長さを設定したら、内容を設定するのを忘れないでください.逆登りを防ぐ.
6.The Languages検出
navigator.Languages検出方法if (!navigator.languages || navigator.languages.length === 0) {
// headless
}
迂回方法 Object.defineProperty(navigator, 'languages', {
get: () => ['en-US', 'en'],
});
7.原文アドレス
https://intoli.com/blog/not-possible-to-block-chrome-headless/https://intoli.com/blog/making-chrome-headless-undetectable/https://github.com/infosimples/detect-headless https://stackoverflow.com/questions/19877924/what-is-the-list-of-possible-values-for-navigator-platform-as-of-today
if (!navigator.languages || navigator.languages.length === 0) {
// headless
}
Object.defineProperty(navigator, 'languages', {
get: () => ['en-US', 'en'],
});
https://intoli.com/blog/not-possible-to-block-chrome-headless/https://intoli.com/blog/making-chrome-headless-undetectable/https://github.com/infosimples/detect-headless https://stackoverflow.com/questions/19877924/what-is-the-list-of-possible-values-for-navigator-platform-as-of-today