289 lines
14 KiB
Markdown
289 lines
14 KiB
Markdown
|
|
## API
|
||
|
|
|
||
|
|
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
|
||
|
|
|
||
|
|
#### Table of Contents
|
||
|
|
|
||
|
|
- [utils()](#utils)
|
||
|
|
- [.stripProxyFromErrors(handler)](#stripproxyfromerrorshandler)
|
||
|
|
- [.stripErrorWithAnchor(err, anchor)](#striperrorwithanchorerr-anchor)
|
||
|
|
- [.replaceProperty(obj, propName, descriptorOverrides)](#replacepropertyobj-propname-descriptoroverrides)
|
||
|
|
- [.preloadCache()](#preloadcache)
|
||
|
|
- [.makeNativeString(name?)](#makenativestringname)
|
||
|
|
- [.patchToString(obj, str)](#patchtostringobj-str)
|
||
|
|
- [.patchToStringNested(obj)](#patchtostringnestedobj)
|
||
|
|
- [.redirectToString(proxyObj, originalObj)](#redirecttostringproxyobj-originalobj)
|
||
|
|
- [.replaceWithProxy(obj, propName, handler)](#replacewithproxyobj-propname-handler)
|
||
|
|
- [.mockWithProxy(obj, propName, pseudoTarget, handler)](#mockwithproxyobj-propname-pseudotarget-handler)
|
||
|
|
- [.createProxy(pseudoTarget, handler)](#createproxypseudotarget-handler)
|
||
|
|
- [.splitObjPath(objPath)](#splitobjpathobjpath)
|
||
|
|
- [.replaceObjPathWithProxy(objPath, handler)](#replaceobjpathwithproxyobjpath-handler)
|
||
|
|
- [.execRecursively(obj, typeFilter, fn)](#execrecursivelyobj-typefilter-fn)
|
||
|
|
- [.stringifyFns(fnObj)](#stringifyfnsfnobj)
|
||
|
|
- [.materializeFns(fnStrObj)](#materializefnsfnstrobj)
|
||
|
|
|
||
|
|
### [utils()](https://github.com/berstend/puppeteer-extra/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/_utils/index.js#L12-L12)
|
||
|
|
|
||
|
|
A set of shared utility functions specifically for the purpose of modifying native browser APIs without leaving traces.
|
||
|
|
|
||
|
|
Meant to be passed down in puppeteer and used in the context of the page (everything in here runs in NodeJS as well as a browser).
|
||
|
|
|
||
|
|
Note: If for whatever reason you need to use this outside of `puppeteer-extra`:
|
||
|
|
Just remove the `module.exports` statement at the very bottom, the rest can be copy pasted into any browser context.
|
||
|
|
|
||
|
|
Alternatively take a look at the `extract-stealth-evasions` package to create a finished bundle which includes these utilities.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### .[stripProxyFromErrors(handler)](https://github.com/berstend/puppeteer-extra/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/_utils/index.js#L21-L82)
|
||
|
|
|
||
|
|
- `handler` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** The JS Proxy handler to wrap (optional, default `{}`)
|
||
|
|
|
||
|
|
Wraps a JS Proxy Handler and strips it's presence from error stacks, in case the traps throw.
|
||
|
|
|
||
|
|
The presence of a JS Proxy can be revealed as it shows up in error stack traces.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### .[stripErrorWithAnchor(err, anchor)](https://github.com/berstend/puppeteer-extra/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/_utils/index.js#L90-L101)
|
||
|
|
|
||
|
|
- `err` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** The error to sanitize
|
||
|
|
- `anchor` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The string the anchor line starts with
|
||
|
|
|
||
|
|
Strip error lines from stack traces until (and including) a known line the stack.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### .[replaceProperty(obj, propName, descriptorOverrides)](https://github.com/berstend/puppeteer-extra/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/_utils/index.js#L120-L127)
|
||
|
|
|
||
|
|
- `obj` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** The object which has the property to replace
|
||
|
|
- `propName` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The property name to replace
|
||
|
|
- `descriptorOverrides` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** e.g. { value: "alice" } (optional, default `{}`)
|
||
|
|
|
||
|
|
Replace the property of an object in a stealthy way.
|
||
|
|
|
||
|
|
Note: You also want to work on the prototype of an object most often,
|
||
|
|
as you'd otherwise leave traces (e.g. showing up in Object.getOwnPropertyNames(obj)).
|
||
|
|
|
||
|
|
Example:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
replaceProperty(WebGLRenderingContext.prototype, 'getParameter', {
|
||
|
|
value: 'alice'
|
||
|
|
})
|
||
|
|
// or
|
||
|
|
replaceProperty(Object.getPrototypeOf(navigator), 'languages', {
|
||
|
|
get: () => ['en-US', 'en']
|
||
|
|
})
|
||
|
|
```
|
||
|
|
|
||
|
|
- **See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty>**
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### .[preloadCache()](https://github.com/berstend/puppeteer-extra/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/_utils/index.js#L137-L150)
|
||
|
|
|
||
|
|
Preload a cache of function copies and data.
|
||
|
|
|
||
|
|
For a determined enough observer it would be possible to overwrite and sniff usage of functions
|
||
|
|
we use in our internal Proxies, to combat that we use a cached copy of those functions.
|
||
|
|
|
||
|
|
This is evaluated once per execution context (e.g. window)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### .[makeNativeString(name?)](https://github.com/berstend/puppeteer-extra/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/_utils/index.js#L169-L173)
|
||
|
|
|
||
|
|
- `name` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Optional function name (optional, default `''`)
|
||
|
|
|
||
|
|
Utility function to generate a cross-browser `toString` result representing native code.
|
||
|
|
|
||
|
|
There's small differences: Chromium uses a single line, whereas FF & Webkit uses multiline strings.
|
||
|
|
To future-proof this we use an existing native toString result as the basis.
|
||
|
|
|
||
|
|
The only advantage we have over the other team is that our JS runs first, hence we cache the result
|
||
|
|
of the native toString result once, so they cannot spoof it afterwards and reveal that we're using it.
|
||
|
|
|
||
|
|
Note: Whenever we add a `Function.prototype.toString` proxy we should preload the cache before,
|
||
|
|
by executing `utils.preloadCache()` before the proxy is applied (so we don't cause recursive lookups).
|
||
|
|
|
||
|
|
Example:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
makeNativeString('foobar') // => `function foobar() { [native code] }`
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### .[patchToString(obj, str)](https://github.com/berstend/puppeteer-extra/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/_utils/index.js#L189-L218)
|
||
|
|
|
||
|
|
- `obj` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** The object for which to modify the `toString()` representation
|
||
|
|
- `str` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Optional string used as a return value (optional, default `''`)
|
||
|
|
|
||
|
|
Helper function to modify the `toString()` result of the provided object.
|
||
|
|
|
||
|
|
Note: Use `utils.redirectToString` instead when possible.
|
||
|
|
|
||
|
|
There's a quirk in JS Proxies that will cause the `toString()` result to differ from the vanilla Object.
|
||
|
|
If no string is provided we will generate a `[native code]` thing based on the name of the property object.
|
||
|
|
|
||
|
|
Example:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
patchToString(
|
||
|
|
WebGLRenderingContext.prototype.getParameter,
|
||
|
|
'function getParameter() { [native code] }'
|
||
|
|
)
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### .[patchToStringNested(obj)](https://github.com/berstend/puppeteer-extra/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/_utils/index.js#L225-L227)
|
||
|
|
|
||
|
|
- `obj` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** (optional, default `{}`)
|
||
|
|
|
||
|
|
Make all nested functions of an object native.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### .[redirectToString(proxyObj, originalObj)](https://github.com/berstend/puppeteer-extra/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/_utils/index.js#L235-L272)
|
||
|
|
|
||
|
|
- `proxyObj` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** The object that toString will be called on
|
||
|
|
- `originalObj` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** The object which toString result we wan to return
|
||
|
|
|
||
|
|
Redirect toString requests from one object to another.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### .[replaceWithProxy(obj, propName, handler)](https://github.com/berstend/puppeteer-extra/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/_utils/index.js#L287-L296)
|
||
|
|
|
||
|
|
- `obj` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** The object which has the property to replace
|
||
|
|
- `propName` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The name of the property to replace
|
||
|
|
- `handler` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** The JS Proxy handler to use
|
||
|
|
|
||
|
|
All-in-one method to replace a property with a JS Proxy using the provided Proxy handler with traps.
|
||
|
|
|
||
|
|
Will stealthify these aspects (strip error stack traces, redirect toString, etc).
|
||
|
|
Note: This is meant to modify native Browser APIs and works best with prototype objects.
|
||
|
|
|
||
|
|
Example:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
replaceWithProxy(WebGLRenderingContext.prototype, 'getParameter', proxyHandler)
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### .[mockWithProxy(obj, propName, pseudoTarget, handler)](https://github.com/berstend/puppeteer-extra/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/_utils/index.js#L311-L319)
|
||
|
|
|
||
|
|
- `obj` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** The object which has the property to replace
|
||
|
|
- `propName` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The name of the property to replace or create
|
||
|
|
- `pseudoTarget` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** The JS Proxy target to use as a basis
|
||
|
|
- `handler` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** The JS Proxy handler to use
|
||
|
|
|
||
|
|
All-in-one method to mock a non-existing property with a JS Proxy using the provided Proxy handler with traps.
|
||
|
|
|
||
|
|
Will stealthify these aspects (strip error stack traces, redirect toString, etc).
|
||
|
|
|
||
|
|
Example:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
mockWithProxy(
|
||
|
|
chrome.runtime,
|
||
|
|
'sendMessage',
|
||
|
|
function sendMessage() {},
|
||
|
|
proxyHandler
|
||
|
|
)
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### .[createProxy(pseudoTarget, handler)](https://github.com/berstend/puppeteer-extra/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/_utils/index.js#L334-L340)
|
||
|
|
|
||
|
|
- `pseudoTarget` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** The JS Proxy target to use as a basis
|
||
|
|
- `handler` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** The JS Proxy handler to use
|
||
|
|
|
||
|
|
All-in-one method to create a new JS Proxy with stealth tweaks.
|
||
|
|
|
||
|
|
This is meant to be used whenever we need a JS Proxy but don't want to replace or mock an existing known property.
|
||
|
|
|
||
|
|
Will stealthify certain aspects of the Proxy (strip error stack traces, redirect toString, etc).
|
||
|
|
|
||
|
|
Example:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
createProxy(navigator.mimeTypes.__proto__.namedItem, proxyHandler) // => Proxy
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### .[splitObjPath(objPath)](https://github.com/berstend/puppeteer-extra/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/_utils/index.js#L351-L359)
|
||
|
|
|
||
|
|
- `objPath` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The full path to an object as dot notation string
|
||
|
|
|
||
|
|
Helper function to split a full path to an Object into the first part and property.
|
||
|
|
|
||
|
|
Example:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
splitObjPath(`HTMLMediaElement.prototype.canPlayType`)
|
||
|
|
// => {objName: "HTMLMediaElement.prototype", propName: "canPlayType"}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### .[replaceObjPathWithProxy(objPath, handler)](https://github.com/berstend/puppeteer-extra/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/_utils/index.js#L372-L376)
|
||
|
|
|
||
|
|
- `objPath` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The full path to an object (dot notation string) to replace
|
||
|
|
- `handler` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** The JS Proxy handler to use
|
||
|
|
|
||
|
|
Convenience method to replace a property with a JS Proxy using the provided objPath.
|
||
|
|
|
||
|
|
Supports a full path (dot notation) to the object as string here, in case that makes it easier.
|
||
|
|
|
||
|
|
Example:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
replaceObjPathWithProxy(
|
||
|
|
'WebGLRenderingContext.prototype.getParameter',
|
||
|
|
proxyHandler
|
||
|
|
)
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### .[execRecursively(obj, typeFilter, fn)](https://github.com/berstend/puppeteer-extra/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/_utils/index.js#L385-L402)
|
||
|
|
|
||
|
|
- `obj` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** (optional, default `{}`)
|
||
|
|
- `typeFilter` **[array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)** e.g. `['function']` (optional, default `[]`)
|
||
|
|
- `fn` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** e.g. `utils.patchToString`
|
||
|
|
|
||
|
|
Traverse nested properties of an object recursively and apply the given function on a whitelist of value types.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### .[stringifyFns(fnObj)](https://github.com/berstend/puppeteer-extra/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/_utils/index.js#L417-L431)
|
||
|
|
|
||
|
|
- `fnObj` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** An object containing functions as properties (optional, default `{hello:()=>'world'}`)
|
||
|
|
|
||
|
|
Everything we run through e.g. `page.evaluate` runs in the browser context, not the NodeJS one.
|
||
|
|
That means we cannot just use reference variables and functions from outside code, we need to pass everything as a parameter.
|
||
|
|
|
||
|
|
Unfortunately the data we can pass is only allowed to be of primitive types, regular functions don't survive the built-in serialization process.
|
||
|
|
This utility function will take an object with functions and stringify them, so we can pass them down unharmed as strings.
|
||
|
|
|
||
|
|
We use this to pass down our utility functions as well as any other functions (to be able to split up code better).
|
||
|
|
|
||
|
|
- **See: utils.materializeFns**
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
#### .[materializeFns(fnStrObj)](https://github.com/berstend/puppeteer-extra/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/_utils/index.js#L439-L451)
|
||
|
|
|
||
|
|
- `fnStrObj` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** An object containing stringified functions as properties (optional, default `{hello:"() => 'world'"}`)
|
||
|
|
|
||
|
|
Utility function to reverse the process of `utils.stringifyFns`.
|
||
|
|
Will materialize an object with stringified functions (supports classic and fat arrow functions).
|
||
|
|
|
||
|
|
---
|