PSF: Foundry Progress Sync. 57 high-fidelity blueprints established. Open Fleet routing (Kimi/Qwen) active. GTD updated.
This commit is contained in:
37
projects/org-skill-web-research/node_modules/puppeteer-extra-plugin-stealth/evasions/sourceurl/_fixtures/test.html
generated
vendored
Normal file
37
projects/org-skill-web-research/node_modules/puppeteer-extra-plugin-stealth/evasions/sourceurl/_fixtures/test.html
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Page Title</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="result">Please use `document.querySelector`..</h1>
|
||||
|
||||
<script>
|
||||
function test() {
|
||||
const err = new Error('Test Error')
|
||||
const isPptr = err.stack
|
||||
.toString()
|
||||
.includes('puppeteer_evaluation_script')
|
||||
|
||||
document.getElementById('result').innerHTML = isPptr ? 'FAIL' : 'PASS'
|
||||
console.log({ err, isPptr })
|
||||
}
|
||||
|
||||
function overrideFunction(item) {
|
||||
item.obj[item.propName] = (function(orig) {
|
||||
return function() {
|
||||
test()
|
||||
return orig.apply(this, arguments)
|
||||
}
|
||||
})(item.obj[item.propName])
|
||||
}
|
||||
|
||||
overrideFunction({
|
||||
propName: 'querySelector',
|
||||
obj: document
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
83
projects/org-skill-web-research/node_modules/puppeteer-extra-plugin-stealth/evasions/sourceurl/index.js
generated
vendored
Normal file
83
projects/org-skill-web-research/node_modules/puppeteer-extra-plugin-stealth/evasions/sourceurl/index.js
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
'use strict'
|
||||
|
||||
const { PuppeteerExtraPlugin } = require('puppeteer-extra-plugin')
|
||||
|
||||
/**
|
||||
* Strip sourceURL from scripts injected by puppeteer.
|
||||
* It can be used to identify the presence of pptr via stacktraces.
|
||||
*/
|
||||
class Plugin extends PuppeteerExtraPlugin {
|
||||
constructor(opts = {}) {
|
||||
super(opts)
|
||||
}
|
||||
|
||||
get name() {
|
||||
return 'stealth/evasions/sourceurl'
|
||||
}
|
||||
|
||||
async onPageCreated(page) {
|
||||
const client =
|
||||
page && typeof page._client === 'function' ? page._client() : page._client
|
||||
if (!client) {
|
||||
this.debug('Warning, missing properties to intercept CDP.', { page })
|
||||
return
|
||||
}
|
||||
|
||||
// Intercept CDP commands and strip identifying and unnecessary sourceURL
|
||||
// https://github.com/puppeteer/puppeteer/blob/9b3005c105995cd267fdc7fb95b78aceab82cf0e/new-docs/puppeteer.cdpsession.md
|
||||
const debug = this.debug
|
||||
client.send = (function(originalMethod, context) {
|
||||
return async function() {
|
||||
const [method, paramArgs] = arguments || []
|
||||
const next = async () => {
|
||||
try {
|
||||
return await originalMethod.apply(context, [method, paramArgs])
|
||||
} catch (error) {
|
||||
// This seems to happen sometimes when redirects cause other outstanding requests to be cut short
|
||||
if (
|
||||
error instanceof Error &&
|
||||
error.message.includes(
|
||||
`Protocol error (Network.getResponseBody): No resource with given identifier found`
|
||||
)
|
||||
) {
|
||||
debug(
|
||||
`Caught and ignored an error about a missing network resource.`,
|
||||
{ error }
|
||||
)
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!method || !paramArgs) {
|
||||
return next()
|
||||
}
|
||||
|
||||
// To find the methods/props in question check `_evaluateInternal` at:
|
||||
// https://github.com/puppeteer/puppeteer/blob/main/src/common/ExecutionContext.ts#L186
|
||||
const methodsToPatch = {
|
||||
'Runtime.evaluate': 'expression',
|
||||
'Runtime.callFunctionOn': 'functionDeclaration'
|
||||
}
|
||||
const SOURCE_URL_SUFFIX =
|
||||
'//# sourceURL=__puppeteer_evaluation_script__'
|
||||
|
||||
if (!methodsToPatch[method] || !paramArgs[methodsToPatch[method]]) {
|
||||
return next()
|
||||
}
|
||||
|
||||
debug('Stripping sourceURL', { method })
|
||||
paramArgs[methodsToPatch[method]] = paramArgs[
|
||||
methodsToPatch[method]
|
||||
].replace(SOURCE_URL_SUFFIX, '')
|
||||
|
||||
return next()
|
||||
}
|
||||
})(client.send, client)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function(pluginConfig) {
|
||||
return new Plugin(pluginConfig)
|
||||
}
|
||||
54
projects/org-skill-web-research/node_modules/puppeteer-extra-plugin-stealth/evasions/sourceurl/index.test.js
generated
vendored
Normal file
54
projects/org-skill-web-research/node_modules/puppeteer-extra-plugin-stealth/evasions/sourceurl/index.test.js
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
const test = require('ava')
|
||||
|
||||
const { vanillaPuppeteer, addExtra } = require('../../test/util')
|
||||
const Plugin = require('.')
|
||||
|
||||
const TEST_HTML_FILE = require('path').join(__dirname, './_fixtures/test.html')
|
||||
|
||||
test('vanilla: sourceurl is leaking', async t => {
|
||||
const browser = await vanillaPuppeteer.launch({ headless: true })
|
||||
const page = await browser.newPage()
|
||||
await page.goto('file://' + TEST_HTML_FILE, { waitUntil: 'load' })
|
||||
|
||||
// Trigger test
|
||||
await page.$('title')
|
||||
|
||||
const result = await page.evaluate(
|
||||
() => document.querySelector('#result').innerText
|
||||
)
|
||||
t.is(result, 'FAIL')
|
||||
|
||||
const result2 = await page.evaluate(() => {
|
||||
try {
|
||||
Function.prototype.toString.apply({})
|
||||
} catch (err) {
|
||||
return err.stack
|
||||
}
|
||||
})
|
||||
t.true(result2.includes('__puppeteer_evaluation_script'))
|
||||
})
|
||||
|
||||
test('stealth: sourceurl is not leaking', async t => {
|
||||
const puppeteer = addExtra(vanillaPuppeteer).use(Plugin())
|
||||
const browser = await puppeteer.launch({ headless: true })
|
||||
const page = await browser.newPage()
|
||||
|
||||
await page.goto('file://' + TEST_HTML_FILE, { waitUntil: 'load' })
|
||||
|
||||
// Trigger test
|
||||
await page.$('title')
|
||||
|
||||
const result = await page.evaluate(
|
||||
() => document.querySelector('#result').innerText
|
||||
)
|
||||
t.is(result, 'PASS')
|
||||
|
||||
const result2 = await page.evaluate(() => {
|
||||
try {
|
||||
Function.prototype.toString.apply({})
|
||||
} catch (err) {
|
||||
return err.stack
|
||||
}
|
||||
})
|
||||
t.false(result2.includes('__puppeteer_evaluation_script'))
|
||||
})
|
||||
4
projects/org-skill-web-research/node_modules/puppeteer-extra-plugin-stealth/evasions/sourceurl/package.json
generated
vendored
Normal file
4
projects/org-skill-web-research/node_modules/puppeteer-extra-plugin-stealth/evasions/sourceurl/package.json
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"private": true,
|
||||
"main": "index.js"
|
||||
}
|
||||
18
projects/org-skill-web-research/node_modules/puppeteer-extra-plugin-stealth/evasions/sourceurl/readme.md
generated
vendored
Normal file
18
projects/org-skill-web-research/node_modules/puppeteer-extra-plugin-stealth/evasions/sourceurl/readme.md
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
## 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/sourceurl/index.js#L9-L58)
|
||||
|
||||
- `opts` (optional, default `{}`)
|
||||
|
||||
**Extends: PuppeteerExtraPlugin**
|
||||
|
||||
Strip sourceURL from scripts injected by puppeteer.
|
||||
It can be used to identify the presence of pptr via stacktraces.
|
||||
|
||||
---
|
||||
Reference in New Issue
Block a user