Rename to hkt.sh
This commit is contained in:
59
node_modules/puppeteer-extra-plugin-stealth/evasions/webgl.vendor/index.js
generated
vendored
Normal file
59
node_modules/puppeteer-extra-plugin-stealth/evasions/webgl.vendor/index.js
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
'use strict'
|
||||
|
||||
const { PuppeteerExtraPlugin } = require('puppeteer-extra-plugin')
|
||||
|
||||
const withUtils = require('../_utils/withUtils')
|
||||
|
||||
/**
|
||||
* Fix WebGL Vendor/Renderer being set to Google in headless mode
|
||||
*
|
||||
* Example data (Apple Retina MBP 13): {vendor: "Intel Inc.", renderer: "Intel(R) Iris(TM) Graphics 6100"}
|
||||
*
|
||||
* @param {Object} [opts] - Options
|
||||
* @param {string} [opts.vendor] - The vendor string to use (default: `Intel Inc.`)
|
||||
* @param {string} [opts.renderer] - The renderer string (default: `Intel Iris OpenGL Engine`)
|
||||
*/
|
||||
class Plugin extends PuppeteerExtraPlugin {
|
||||
constructor(opts = {}) {
|
||||
super(opts)
|
||||
}
|
||||
|
||||
get name() {
|
||||
return 'stealth/evasions/webgl.vendor'
|
||||
}
|
||||
|
||||
/* global WebGLRenderingContext WebGL2RenderingContext */
|
||||
async onPageCreated(page) {
|
||||
await withUtils(page).evaluateOnNewDocument((utils, opts) => {
|
||||
const getParameterProxyHandler = {
|
||||
apply: function(target, ctx, args) {
|
||||
const param = (args || [])[0]
|
||||
const result = utils.cache.Reflect.apply(target, ctx, args)
|
||||
// UNMASKED_VENDOR_WEBGL
|
||||
if (param === 37445) {
|
||||
return opts.vendor || 'Intel Inc.' // default in headless: Google Inc.
|
||||
}
|
||||
// UNMASKED_RENDERER_WEBGL
|
||||
if (param === 37446) {
|
||||
return opts.renderer || 'Intel Iris OpenGL Engine' // default in headless: Google SwiftShader
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
// There's more than one WebGL rendering context
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext#Browser_compatibility
|
||||
// To find out the original values here: Object.getOwnPropertyDescriptors(WebGLRenderingContext.prototype.getParameter)
|
||||
const addProxy = (obj, propName) => {
|
||||
utils.replaceWithProxy(obj, propName, getParameterProxyHandler)
|
||||
}
|
||||
// For whatever weird reason loops don't play nice with Object.defineProperty, here's the next best thing:
|
||||
addProxy(WebGLRenderingContext.prototype, 'getParameter')
|
||||
addProxy(WebGL2RenderingContext.prototype, 'getParameter')
|
||||
}, this.opts)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function(pluginConfig) {
|
||||
return new Plugin(pluginConfig)
|
||||
}
|
||||
222
node_modules/puppeteer-extra-plugin-stealth/evasions/webgl.vendor/index.test.js
generated
vendored
Normal file
222
node_modules/puppeteer-extra-plugin-stealth/evasions/webgl.vendor/index.test.js
generated
vendored
Normal file
@@ -0,0 +1,222 @@
|
||||
const test = require('ava')
|
||||
|
||||
const {
|
||||
getVanillaFingerPrint,
|
||||
getStealthFingerPrint
|
||||
} = require('../../test/util')
|
||||
const { vanillaPuppeteer, addExtra } = require('../../test/util')
|
||||
|
||||
const Plugin = require('.')
|
||||
const { errors } = require('puppeteer')
|
||||
|
||||
// FIXME: This changed in more recent chrome versions
|
||||
// test('vanilla: videoCard is Google Inc', async t => {
|
||||
// const pageFn = async page => await page.evaluate(() => window.chrome) // eslint-disable-line
|
||||
// const { videoCard } = await getVanillaFingerPrint(pageFn)
|
||||
// t.deepEqual(videoCard, ['Google Inc.', 'Google SwiftShader'])
|
||||
// })
|
||||
|
||||
test('stealth: videoCard is Intel Inc', async t => {
|
||||
const pageFn = async page => await page.evaluate(() => window.chrome) // eslint-disable-line
|
||||
const { videoCard } = await getStealthFingerPrint(Plugin, pageFn)
|
||||
t.deepEqual(videoCard, ['Intel Inc.', 'Intel Iris OpenGL Engine'])
|
||||
})
|
||||
|
||||
test('stealth: customized values', async t => {
|
||||
const pageFn = async page => await page.evaluate(() => window.chrome) // eslint-disable-line
|
||||
const { videoCard } = await getStealthFingerPrint(Plugin, pageFn, {
|
||||
vendor: 'foo',
|
||||
renderer: 'bar'
|
||||
})
|
||||
t.deepEqual(videoCard, ['foo', 'bar'])
|
||||
})
|
||||
|
||||
/* global WebGLRenderingContext */
|
||||
async function extendedTests() {
|
||||
const results = {}
|
||||
|
||||
async function test(name, fn) {
|
||||
const detectionPassed = await fn()
|
||||
if (detectionPassed) console.log(`Chrome headless detected via ${name}`)
|
||||
results[name] = detectionPassed
|
||||
}
|
||||
|
||||
const canvas = document.createElement('canvas')
|
||||
const context = canvas.getContext('webgl')
|
||||
|
||||
await test('descriptorsOK', _ => {
|
||||
const descriptors = Object.getOwnPropertyDescriptors(
|
||||
WebGLRenderingContext.prototype
|
||||
)
|
||||
const str = descriptors.getParameter.toString()
|
||||
return str === `[object Object]`
|
||||
})
|
||||
|
||||
await test('toStringOK', _ => {
|
||||
const str = context.getParameter.toString()
|
||||
return str === `function getParameter() { [native code] }`
|
||||
})
|
||||
|
||||
await test('toStringOK2', _ => {
|
||||
const str = WebGLRenderingContext.prototype.getParameter.toString()
|
||||
return str === `function getParameter() { [native code] }`
|
||||
})
|
||||
|
||||
// Make sure we not reveal our proxy through errors
|
||||
await test('errorOK', _ => {
|
||||
try {
|
||||
return context.getParameter()
|
||||
} catch (err) {
|
||||
return !err.stack.includes(`at Object.apply`)
|
||||
}
|
||||
})
|
||||
|
||||
// Should not throw (that was old stealth behavior)
|
||||
await test('elementOK', _ => {
|
||||
try {
|
||||
return context.getParameter(123) === null
|
||||
} catch (_) {
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
test('vanilla: webgl is native', async t => {
|
||||
const pageFn = async page => {
|
||||
// page.on('console', msg => {
|
||||
// console.log('Page console: ', msg.text())
|
||||
// })
|
||||
return await page.evaluate(extendedTests) // eslint-disable-line
|
||||
}
|
||||
const { pageFnResult: result } = await getVanillaFingerPrint(pageFn)
|
||||
|
||||
const wasHeadlessDetected = Object.values(result).some(e => e === false)
|
||||
if (wasHeadlessDetected) {
|
||||
console.log(result)
|
||||
}
|
||||
t.false(wasHeadlessDetected)
|
||||
})
|
||||
|
||||
test('stealth: webgl is native', async t => {
|
||||
const pageFn = async page => await page.evaluate(extendedTests) // eslint-disable-line
|
||||
const { pageFnResult: result } = await getStealthFingerPrint(Plugin, pageFn)
|
||||
|
||||
const wasHeadlessDetected = Object.values(result).some(e => e === false)
|
||||
if (wasHeadlessDetected) {
|
||||
console.log(result)
|
||||
}
|
||||
t.false(wasHeadlessDetected)
|
||||
})
|
||||
|
||||
/**
|
||||
* A very simple method to retrieve the name of the default videocard of the system
|
||||
* using webgl.
|
||||
*
|
||||
* Example (Apple Retina MBP 13): {vendor: "Intel Inc.", renderer: "Intel(R) Iris(TM) Graphics 6100"}
|
||||
*
|
||||
* @see https://stackoverflow.com/questions/49267764/how-to-get-the-video-card-driver-name-using-javascript-browser-side
|
||||
* @returns {Object}
|
||||
*/
|
||||
function getVideoCardInfo(context = 'webgl') {
|
||||
const gl = document.createElement('canvas').getContext(context)
|
||||
if (!gl) {
|
||||
return {
|
||||
error: 'no webgl'
|
||||
}
|
||||
}
|
||||
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info')
|
||||
if (debugInfo) {
|
||||
return {
|
||||
vendor: gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL),
|
||||
renderer: gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL)
|
||||
}
|
||||
}
|
||||
return {
|
||||
error: 'no WEBGL_debug_renderer_info'
|
||||
}
|
||||
}
|
||||
|
||||
test('stealth: handles WebGLRenderingContext', async t => {
|
||||
const puppeteer = addExtra(vanillaPuppeteer).use(Plugin())
|
||||
const browser = await puppeteer.launch({ headless: true })
|
||||
const page = await browser.newPage()
|
||||
|
||||
const videoCardInfo = await page.evaluate(getVideoCardInfo, 'webgl')
|
||||
t.is(videoCardInfo.error, undefined)
|
||||
t.is(videoCardInfo.vendor, 'Intel Inc.')
|
||||
t.is(videoCardInfo.renderer, 'Intel Iris OpenGL Engine')
|
||||
})
|
||||
|
||||
test('stealth: handles WebGL2RenderingContext', async t => {
|
||||
const puppeteer = addExtra(vanillaPuppeteer).use(Plugin())
|
||||
const browser = await puppeteer.launch({ headless: true })
|
||||
const page = await browser.newPage()
|
||||
|
||||
const videoCardInfo = await page.evaluate(getVideoCardInfo, 'webgl2')
|
||||
t.is(videoCardInfo.error, undefined)
|
||||
t.is(videoCardInfo.vendor, 'Intel Inc.')
|
||||
t.is(videoCardInfo.renderer, 'Intel Iris OpenGL Engine')
|
||||
})
|
||||
|
||||
test('vanilla: normal toString stuff', async t => {
|
||||
const browser = await vanillaPuppeteer.launch({ headless: true })
|
||||
const page = await browser.newPage()
|
||||
|
||||
const test1 = await page.evaluate(() => {
|
||||
return WebGLRenderingContext.prototype.getParameter.toString + ''
|
||||
})
|
||||
t.is(test1, 'function toString() { [native code] }')
|
||||
|
||||
const test2 = await page.evaluate(() => {
|
||||
return WebGLRenderingContext.prototype.getParameter.toString()
|
||||
})
|
||||
t.is(test2, 'function getParameter() { [native code] }')
|
||||
})
|
||||
|
||||
test('stealth: will not leak toString stuff', async t => {
|
||||
const puppeteer = addExtra(vanillaPuppeteer).use(Plugin())
|
||||
const browser = await puppeteer.launch({ headless: true })
|
||||
const page = await browser.newPage()
|
||||
|
||||
const test1 = await page.evaluate(() => {
|
||||
return WebGLRenderingContext.prototype.getParameter.toString + ''
|
||||
})
|
||||
t.is(test1, 'function toString() { [native code] }') // returns function () { [native code] }
|
||||
|
||||
const test2 = await page.evaluate(() => {
|
||||
return WebGLRenderingContext.prototype.getParameter.toString()
|
||||
})
|
||||
t.is(test2, 'function getParameter() { [native code] }')
|
||||
})
|
||||
|
||||
test('stealth: sets user opts correctly', async t => {
|
||||
const puppeteer = addExtra(vanillaPuppeteer).use(
|
||||
Plugin({ vendor: 'alice', renderer: 'bob' })
|
||||
)
|
||||
const browser = await puppeteer.launch({ headless: true })
|
||||
const page = await browser.newPage()
|
||||
|
||||
const videoCardInfo = await page.evaluate(getVideoCardInfo, 'webgl')
|
||||
t.is(videoCardInfo.error, undefined)
|
||||
t.is(videoCardInfo.vendor, 'alice')
|
||||
t.is(videoCardInfo.renderer, 'bob')
|
||||
})
|
||||
|
||||
test('stealth: does not affect protoype', async t => {
|
||||
const puppeteer = addExtra(vanillaPuppeteer).use(
|
||||
Plugin({ vendor: 'alice', renderer: 'bob' })
|
||||
)
|
||||
const browser = await puppeteer.launch({ headless: true })
|
||||
const page = await browser.newPage()
|
||||
|
||||
const result = await page.evaluate(() => {
|
||||
try {
|
||||
return WebGLRenderingContext.prototype.getParameter(37445)
|
||||
} catch (err) {
|
||||
return err.message
|
||||
}
|
||||
})
|
||||
t.is(result, 'Illegal invocation')
|
||||
})
|
||||
4
node_modules/puppeteer-extra-plugin-stealth/evasions/webgl.vendor/package.json
generated
vendored
Normal file
4
node_modules/puppeteer-extra-plugin-stealth/evasions/webgl.vendor/package.json
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"private": true,
|
||||
"main": "index.js"
|
||||
}
|
||||
21
node_modules/puppeteer-extra-plugin-stealth/evasions/webgl.vendor/readme.md
generated
vendored
Normal file
21
node_modules/puppeteer-extra-plugin-stealth/evasions/webgl.vendor/readme.md
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
## API
|
||||
|
||||
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
|
||||
|
||||
#### Table of Contents
|
||||
|
||||
- [class: Plugin](#class-plugin)
|
||||
|
||||
### class: [Plugin](https://github.com/berstend/puppeteer-extra/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/webgl.vendor/index.js#L17-L55)
|
||||
|
||||
- `opts` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** Options (optional, default `{}`)
|
||||
- `opts.vendor` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** The vendor string to use (default: `Intel Inc.`)
|
||||
- `opts.renderer` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** The renderer string (default: `Intel Iris OpenGL Engine`)
|
||||
|
||||
**Extends: PuppeteerExtraPlugin**
|
||||
|
||||
Fix WebGL Vendor/Renderer being set to Google in headless mode
|
||||
|
||||
Example data (Apple Retina MBP 13): {vendor: "Intel Inc.", renderer: "Intel(R) Iris(TM) Graphics 6100"}
|
||||
|
||||
---
|
||||
Reference in New Issue
Block a user