
자동화 감지 및 누출을 피하기 위한 puppeteer와 playwright용 패치 모음입니다. Cloudflare 및 DataDome CAPTCHA 페이지를 우회하는 데 도움이 됩니다. 패치 적용/해제가 쉽고, 필요에 따라 활성화/비활성화할 수 있습니다.
이 저장소는 널리 사용되는 웹 자동화 라이브러리를 개선하기 위한 패치를 포함하고 있습니다. 구체적으로 puppeteer 및 playwright 패키지를 대상으로 합니다.
자동화 라이브러리나 브라우저 동작의 일부 측면은 설정이나 명령줄 스위치로 조정할 수 없습니다. 따라서 우리는 라이브러리의 소스 코드를 패치하여 이러한 문제를 해결합니다. 이 접근 방식은 깨지기 쉬워 라이브러리의 소스 코드가 변경됨에 따라 문제가 발생할 수 있지만, 커뮤니티의 도움을 받아 패치를 최신 상태로 유지하는 것이 이 저장소의 목표입니다.
기본 상태의 Puppeteer와 Playwright에는 쉽게 탐지되는 심각한 누출(leak)이 있습니다. 프록시, 지문(fingerprint), 행동 스크립트가 아무리 훌륭해도 패치가 되어 있지 않다면, 주요 웹사이트에는 커다란 위험 신호로 보일 뿐입니다.
🕵️ rebrowser-bot-detector를 사용하여 자동화 설정이 주요 최신 탐지 기법에 얼마나 취약한지 쉽게 테스트할 수 있습니다 (소스 및 자세한 정보)
| 패치 전 👎 | 패치 후 👍 |
|---|---|
![]() | ![]() |
패치와 발생 가능한 모든 오류를 직접 처리하고 싶지 않다면, 바로 사용할 수 있는(drop-in) 솔루션이 있습니다. 이 패키지들은 원본 코드에 rebrowser-patches를 적용한 것에 불과하며, 그 이상도 이하도 아닙니다.
Puppeteer: rebrowser-puppeteer (소스) 및 rebrowser-puppeteer-core (소스)
Playwright (Node.js): rebrowser-playwright (소스) 및 rebrowser-playwright-core (소스)
Playwright (Python): rebrowser-playwright (소스)
가장 쉬운 사용 방법은 package.json을 수정하여 새 패키지를 사용하되 이전 이름을 별칭으로 유지하는 것입니다. 이렇게 하면 자동화 소스 코드를 변경할 필요가 없습니다. 방법은 다음과 같습니다:
package.json을 열고 "puppeteer": "^23.3.1" 및 "puppeteer-core": "^23.3.1"을 "puppeteer": "npm:rebrowser-puppeteer@^23.3.1" 및 "puppeteer-core": "npm:rebrowser-puppeteer-core@^23.3.1"로 교체하세요. 참고: 23.3.1은 단지 예시일 뿐이며, npm에서 최신 버전을 확인하세요.npm install(또는 yarn install)을 실행하세요.또 다른 방법은 원본 패키지 대신 새 패키지를 실제로 사용하는 것입니다. 따라야 할 단계는 다음과 같습니다:
package.json을 열고 puppeteer 및 puppeteer-core 패키지를 rebrowser-puppeteer 및 rebrowser-puppeteer-core로 교체하세요. 패키지 버전은 변경하지 말고 이름만 교체하세요.npm install(또는 yarn install)을 실행하세요.puppeteer 및 puppeteer-core가 언급된 부분을 찾아 rebrowser-puppeteer 및 rebrowser-puppeteer-core로 바꾸세요.🚀 끝입니다! rebrowser-bot-detector 페이지를 방문하여 패치된 브라우저를 테스트해 보세요.
우리의 목표는 이 드롭인 대체 패키지들을 최신 버전으로 유지 관리하고 지원하는 것이지만, 주로 최신 버전에 집중하고 있습니다. 따라서 여전히 90년대 초반의 puppeteer 13.3.7을 사용하고 있다면 업그레이드할 좋은 시기일 수 있습니다. API가 시간이 지나도 상당히 안정적이기 때문에 뭔가가 깨질 가능성은 낮습니다.
Runtime.Enable 누출(leak) 수정널리 사용되는 자동화 라이브러리는 Runtime. 도메인의 이벤트를 수신할 수 있게 해주는 CDP 명령 Runtime.Enable에 의존합니다. 이는 모든 자동화 프로세스의 핵심 기능인 페이지에서 JavaScript를 평가하는 데 사용되는 실행 컨텍스트를 관리하는 데 중요합니다.
그러나 이 명령의 사용을 탐지하여 브라우저가 Puppeteer나 Playwright 같은 자동화 소프트웨어에 의해 제어되고 있음을 드러내는 기술이 있습니다. 이 기술은 Cloudflare, DataDome 등을 포함한 모든 주요 안티봇 소프트웨어에서 사용됩니다.
이 누출에 대한 조사 내용을 담은 전체 기사를 준비했으며, 블로그에서 읽을 수 있습니다.
이 기술에 대한 자세한 내용은 DataDome의 블로그 게시물을 읽어보세요: How New Headless Chrome & the CDP Signal Are Impacting Bot Detection.
간단히 말하면, Runtime.Enable이 사용된 경우 페이지에서 자동으로 호출되는 몇 줄의 JavaScript입니다.
우리의 수정은 모든 프레임에서 자동 Runtime.Enable 명령을 비활성화합니다. 대신 프레임이 생성될 때 알 수 없는 ID를 가진 컨텍스트를 수동으로 생성합니다. 그런 다음 코드를 실행해야 할 때 컨텍스트 ID를 얻는 여러 가지 방법이 있습니다.
🟢 장점: 메인 월드에 대한 접근을 유지하면서 웹 워커와 iframe에서도 작동하는 최고의 방법입니다. 기존 코드베이스를 변경할 필요가 없습니다.
🔴 단점: 현재까지 발견된 단점은 없습니다.
Page.createIsolatedWorld를 통해 새 격리 컨텍스트를 생성하고 해당 ID를 저장합니다.🟢 장점: 모든 코드가 별도의 격리 월드에서 실행되므로 페이지 스크립트가 MutationObserver 및 기타 기술을 통해 변경 사항을 탐지하는 것을 방지할 수 있습니다.
🔴 단점: 메인 컨텍스트의 변수와 코드에 접근할 수 없습니다. 일부 사용 사례에서는 필요하지만, 격리 컨텍스트는 대부분의 시나리오에서 일반적으로 잘 작동합니다. 또한 웹 워커는 새 월드 생성을 허용하지 않으므로 워커 내부에서 코드를 실행할 수 없습니다. 이는 틈새 사용 사례지만 일부 상황에서는 중요할 수 있습니다. 이 문제에 대한 해결 방법이 있으니 Puppeteer & Playwright에서 격리 컨텍스트의 메인 컨텍스트 객체에 접근하는 방법을 읽어보세요.
Runtime.Enable을 호출한 다음 즉시 Runtime.Disable을 호출합니다.이렇게 하면 Runtime.executionContextCreated 이벤트가 트리거되어 올바른 컨텍스트 ID를 포착할 수 있습니다.
🟢 장점: 메인 컨텍스트에 대한 전체 접근 권한을 갖게 됩니다.
🔴 단점: 이 짧은 시간 동안 페이지가 누출로 이어지는 코드를 호출할 약간의 가능성이 있습니다. 탐지 코드는 일반적으로 CAPTCHA 페이지나 로그인/가입 폼과 같은 특정 작업 중, 주로 페이지가 로드된 직후에 호출되므로 위험은 낮습니다. 비즈니스 로직은 보통 조금 나중에 호출됩니다.
🎉 우리의 테스트에 따르면 이 모든 접근 방식은 현재 Cloudflare나 DataDome에 탐지되지 않습니다.
참고: 환경 변수를 사용하여 이 패치의 설정을 즉석에서 변경할 수 있습니다. 이를 통해 비즈니스 로직에 따라 패치된 버전과 패치되지 않은 버전을 쉽게 전환할 수 있습니다.
REBROWSER_PATCHES_RUNTIME_FIX_MODE=addBinding — addBinding 기법 (기본값)REBROWSER_PATCHES_RUNTIME_FIX_MODE=alwaysIsolated — 모든 스크립트를 항상 격리 컨텍스트에서 실행REBROWSER_PATCHES_RUNTIME_FIX_MODE=enableDisable — Enable/Disable 기법 사용REBROWSER_PATCHES_RUNTIME_FIX_MODE=0 — 이 누출에 대한 수정을 완전히 비활성화REBROWSER_PATCHES_DEBUG=1 — 일부 디버깅 메시지 활성화이러한 변수는 다양한 방식으로 설정할 수 있습니다. 예를 들어 코드에서:
process.env.REBROWSER_PATCHES_RUNTIME_FIX_MODE = "alwaysIsolated"
또는 명령줄에서:
REBROWSER_PATCHES_RUNTIME_FIX_MODE=alwaysIsolated node app.js
기본적으로 Puppeteer는 page.evaluate()의 모든 스크립트에 //# sourceURL=pptr:...를 추가합니다. 원격 웹사이트는 이 동작을 탐지하고 위험 신호를 올릴 수 있습니다.
이 패치는 이를 //# sourceURL=app.js로 변경합니다. 환경 변수를 통해서도 조정할 수 있습니다:
# use any generic filename
REBROWSER_PATCHES_SOURCE_URL=jquery.min.js
# use 0 to completely disable this patch
REBROWSER_PATCHES_SOURCE_URL=0
때로는 브라우저 수준에서 CDP 세션에 접근하는 것이 매우 유용할 수 있습니다. 예를 들어 사용자 정의 CDP 명령을 구현하려는 경우입니다. 현재 페이지 인스턴스에 대한 CDP 세션을 반환하는 page._client() 메서드는 있지만, 브라우저 인스턴스에는 그런 메서드가 없습니다.
이 패치는 Browser 클래스에 새 메서드 _connection()을 추가하므로 다음과 같이 사용할 수 있습니다:
browser._connection().on('Rebrowser.addRunEvent', (params) => { ... })
참고: 외부 웹사이트 스크립트로는 탐지할 수 없으며, 단지 편의를 위한 것입니다.
기본 유틸리티 월드 이름은 '__puppeteer_utility_world__' + packageVersion입니다. 때로는 다른 이름으로 변경하고 싶을 수 있습니다. 이 패치는 이를 util로 변경하고 환경 변수를 통해 사용자 지정할 수 있게 해줍니다:
REBROWSER_PATCHES_UTILITY_WORLD_NAME=customUtilityWorld
# use 0 to completely disable this patch
REBROWSER_PATCHES_UTILITY_WORLD_NAME=0
이 환경 변수는 즉석에서 변경할 수 없습니다. 모듈이 임포트되는 시점에 사용되므로 스크립트를 실행하기 전에 설정해야 합니다.
| 패치 전 👎 | 패치 후 👍 |
|---|---|
![]() | ![]() |
참고: 외부 웹사이트 스크립트로는 탐지할 수 없지만, Google이 자체 Chrome에서 이 정보를 사용할 수도 있습니다. 누구도 알 수 없습니다.
이 패키지는 설치된 라이브러리 대상으로 실행되도록 설계되었습니다. 라이브러리를 설치한 다음 패처를 호출하면 바로 사용할 수 있습니다.
프로젝트의 루트 폴더에서 다음을 실행하세요:
npx rebrowser-patches@latest patch --packageName puppeteer-core
다음 명령으로 모든 변경 사항을 쉽게 되돌릴 수 있습니다:
npx rebrowser-patches@latest unpatch --packageName puppeteer-core
패키지 폴더의 전체 경로를 지정하여 패치할 수도 있습니다. 예를 들어:
npx rebrowser-patches@latest patch --packagePath /web/app/node_modules/puppeteer-core-custom
npx rebrowser-patches@latest --help를 실행하면 모든 명령줄 옵션을 확인할 수 있지만, 현재는 하나의 라이브러리에 대한 패치 하나만 있으므로 별도로 구성할 필요가 없습니다.
⚠️ 프로젝트 폴더에서 npm install 또는 yarn install을 실행한 후에는 패치의 모든 변경 사항이 덮어써질 수 있습니다. 패치를 유지하려면 패처를 다시 실행해야 합니다.
이미 패키지를 패치했고 rebrowser-patches의 최신 버전으로 업데이트하려면, node_modules/puppeteer-core를 삭제한 다음 npm install 또는 yarn install --check-files을 실행하고, 그 후 npx rebrowser-patches@latest patch를 실행하는 것이 가장 쉬운 방법입니다.
이 모든 버전은 Node.js 버전의 Playwright를 감싸는 래퍼일 뿐입니다. Playwright 패키지 내부에서 driver 폴더를 찾아 --packagePath=$yourDriverFolder/$yourPlatform/package로 이 패치를 실행해야 합니다.
✅ 최신 완전 테스트 버전: 24.8.1 (2025-05-06 출시)
Playwright 패치에는 다음이 포함됩니다:
Runtime.enable 누출: addBinding 및 alwaysIsolated 모드.REBROWSER_PATCHES_UTILITY_WORLD_NAME 환경 변수를 통해 유틸리티 월드 이름을 변경하는 기능.중요: page.pause() 메서드는 수정이 활성화된 상태에서는 작동하지 않으며, 추가 조사가 필요합니다. 디버깅 중에는 REBROWSER_PATCHES_RUNTIME_FIX_MODE=0 환경 변수를 사용하여 수정을 완전히 비활성화하면 됩니다.
현재 이 패치는 Chrome에서만 작동합니다. WebKit이나 Firefox에서 사용하려면 새 이슈를 열어 주세요.
✅ 최신 완전 테스트 버전: 1.52.0 (2025-04-17 출시)
puppeteer-extra와 함께 rebrowser-puppeteer를 사용하는 방법은?addExtra 메서드를 사용하세요. 예시는 다음과 같습니다:
// before
import puppeteer from 'puppeteer-extra'
// after
import { addExtra } from 'puppeteer-extra'
import rebrowserPuppeteer from 'rebrowser-puppeteer-core'
const puppeteer = addExtra(rebrowserPuppeteer)
현재 웹 자동화 투명성을 개선하기 위한 더 많은 패치를 개발 중이며, 곧 이 저장소에 공개될 예정입니다. ⭐️ 스타 또는 watch 버튼을 클릭하여 프로젝트를 지원해 주세요.
💭 아이디어, 생각, 질문이 있으시면 이메일로 팀에 연락하거나 이슈 섹션을 이용해 주세요.
⚠️ 이 수정만으로는 브라우저가 완벽하게 방탄이고 탐지 불가능해지지 않는다는 점을 알아야 합니다. 프록시, 적절한 user-agent와 지문(canvas, WebGL) 등 다른 많은 측면을 처리해야 합니다.
항상 명심하세요: JS 주입을 통해 브라우저 내부를 덜 조작할수록 좋습니다. console, navigator 등과 같은 내부 객체가 Proxy 객체나 Object.defineProperty에 의해 영향을 받았다는 것을 탐지하는 방법이 있습니다. 까다롭지만, 항상 숨바꼭질 게임입니다.
모든 방법을 시도했는데도 여전히 문제가 있다면, 이슈 섹션에 질문을 남기거나 Rebrowser의 클라우드 솔루션을 고려해 보세요.
이 패키지는 Rebrowser의 후원과 관리를 받고 있습니다. 우리는 수백 개의 고유한 지문을 사용하여 클라우드에서 브라우저 자동화와 웹 스크래핑을 확장할 수 있게 해줍니다.
우리의 클라우드 브라우저는 높은 성공률을 자랑하며, 실행 중 라이브러리가 Runtime.Enable을 사용하거나 개선할 수 있는 다른 위험 신호가 있을 때 알림을 제공하는 등 유용한 기능을 갖추고 있습니다. 지금 계정을 만들어 최첨단 플랫폼을 테스트할 초대를 받고 자동화 비즈니스를 한 단계 끌어올리세요.
Windows 머신에서 이 패처를 실행하려고 하면 patch 명령을 찾을 수 없어 오류가 발생할 것입니다. 이 문제를 해결하려면 patch.exe가 포함된 Git을 설치해야 합니다. 설치한 후 PATH에 추가해야 합니다:
set PATH=%PATH%;C:\Program Files\Git\usr\bin\
다음 명령으로 patch.exe가 올바르게 설치되었는지 확인할 수 있습니다:
patch -v
zfcsoftware/puppeteer-real-browser - 자동화 커뮤니티에 대한 일반적인 아이디어와 기여
Kaliiiiiiiiii-Vinyzu/patchright - Playwright 누출을 수정하는 패치 모음
kaliiiiiiiiii/brotector - 최신 테스트, CDP와 devtools를 구별하는 알고리즘
prescience-data/harden-puppeteer - 격리된 월드에서의 실행을 개척한 선구자 중 하나
puppeteer-extra-plugin-stealth - 모든 것이 시작된 곳, 모든 기여자와 커뮤니티에 큰 감사를 드립니다 🙏 berstend와 동료들은 최고(goats)입니다