mirror of
https://github.com/CloakHQ/CloakBrowser.git
synced 2026-06-23 11:41:46 +02:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0ba21faa1 | ||
|
|
b501d8f158 | ||
|
|
6007a6e511 | ||
|
|
96c55352e0 | ||
|
|
5d35fb9e4c | ||
|
|
c966e046e7 |
@@ -56,6 +56,9 @@ test-infra/
|
||||
# Website (deployed separately)
|
||||
site/
|
||||
|
||||
# Browser profile manager (deployed separately)
|
||||
manager/
|
||||
|
||||
# Release scripts
|
||||
publish.sh
|
||||
deploy.sh
|
||||
|
||||
@@ -6,6 +6,18 @@ Changes are tagged: **[wrapper]** for Python/JS wrapper, **[binary]** for Chromi
|
||||
|
||||
---
|
||||
|
||||
## [0.3.14] — 2026-03-12
|
||||
|
||||
- **[binary]** Upgrade Linux build to 145.0.7632.159.6 — fix persistent context detection by FingerprintJS
|
||||
- **[binary]** Storage quota normalization for persistent context profiles
|
||||
- **[binary]** Fix outerHeight calculation for non-incognito contexts
|
||||
- **[wrapper]** Add CLI for binary management — `python -m cloakbrowser install` / `npx cloakbrowser install` with visible download progress (closes #43)
|
||||
|
||||
## [0.3.13] — 2026-03-10
|
||||
|
||||
- **[wrapper]** Suppress Playwright's `--enable-unsafe-swiftshader` default arg — eliminates SwiftShader software renderer detection signal, letting the binary's GPU spoofing work cleanly
|
||||
- **[binary]** Upgrade Linux build to 145.0.7632.159.5 — fix WebGPU adapter limits and features for NVIDIA profiles
|
||||
|
||||
## [0.3.12] — 2026-03-10
|
||||
|
||||
- **[binary]** Upgrade Linux build to 145.0.7632.159.4
|
||||
|
||||
@@ -110,7 +110,7 @@ page.goto("https://example.com")
|
||||
|
||||
> ⭐ **Star** to show support — **[Watch releases](https://github.com/CloakHQ/CloakBrowser/subscription)** to get notified when new builds drop.
|
||||
|
||||
## Latest: v0.3.12 (Chromium 145.0.7632.159.4)
|
||||
## Latest: v0.3.14 (Chromium 145.0.7632.159.6)
|
||||
|
||||
- **`humanize=True`** — one flag makes all mouse, keyboard, and scroll interactions behave like a real user. Bézier curves, per-character typing, realistic scroll patterns. Two presets: `default` and `careful`
|
||||
- **CDP input behavior mimicking** — input events sent via CDP now produce the same signals as real user interactions. 5 new source-level patches covering pointer, keyboard, and mouse behavior
|
||||
@@ -313,6 +313,17 @@ Supports all the same options as `launch_context()`: `proxy`, `user_agent`, `vie
|
||||
|
||||
Async version: `launch_persistent_context_async()`.
|
||||
|
||||
### CLI
|
||||
|
||||
Pre-download the binary or check installation status from the command line:
|
||||
|
||||
```bash
|
||||
python -m cloakbrowser install # Download binary with progress output
|
||||
python -m cloakbrowser info # Show version, path, platform
|
||||
python -m cloakbrowser update # Check for and download newer binary
|
||||
python -m cloakbrowser clear-cache # Remove cached binaries
|
||||
```
|
||||
|
||||
### Utility Functions
|
||||
|
||||
```python
|
||||
@@ -706,6 +717,15 @@ COPY your_script.py /app/
|
||||
CMD ["python", "your_script.py"]
|
||||
```
|
||||
|
||||
**Building your own image from pip** — use `python -m cloakbrowser install` to download the binary during build with visible progress:
|
||||
|
||||
```dockerfile
|
||||
FROM python:3.12-slim
|
||||
RUN pip install cloakbrowser && python -m cloakbrowser install
|
||||
COPY your_script.py /app/
|
||||
CMD ["python", "/app/your_script.py"]
|
||||
```
|
||||
|
||||
**Building from source** — a [`Dockerfile`](Dockerfile) is also included if you prefer to build your own image:
|
||||
|
||||
```bash
|
||||
@@ -718,7 +738,9 @@ CloakBrowser works identically local, in Docker, and on VPS. No environment-spec
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Still getting blocked on aggressive sites (DataDome, Turnstile)?**
|
||||
---
|
||||
|
||||
### Still getting blocked on aggressive sites (DataDome, Turnstile)?
|
||||
|
||||
Some sites detect headless mode even with our C++ patches. Run in **headed mode** with a virtual display:
|
||||
|
||||
@@ -743,7 +765,9 @@ browser.close()
|
||||
|
||||
This runs a real headed browser rendered on a virtual display — no physical monitor needed. Combined with a residential proxy, this passes even the most aggressive detection services. Datacenter IPs are often flagged by IP reputation regardless of browser fingerprint — a residential proxy makes the difference.
|
||||
|
||||
**Sites challenge fresh sessions but work after first visit**
|
||||
---
|
||||
|
||||
### Sites challenge fresh sessions but work after first visit
|
||||
|
||||
Some sites challenge first-time visitors with no cookies over HTTP/2. This affects all Chromium browsers, not just CloakBrowser. Use a persistent profile to warm up cookies once, then reuse across sessions:
|
||||
|
||||
@@ -777,7 +801,10 @@ ctx = await launchPersistentContext({ userDataDir: './profile' });
|
||||
|
||||
For stateless/ephemeral use cases, `launch(args=["--disable-http2"])` forces HTTP/1.1 which bypasses the check. Only use this flag for sites that require it — most work fine with HTTP/2.
|
||||
|
||||
**Something not working? Make sure you're on the latest version**
|
||||
---
|
||||
|
||||
### Something not working? Make sure you're on the latest version
|
||||
|
||||
Older versions may use outdated stealth args or download an older binary:
|
||||
```bash
|
||||
pip install -U cloakbrowser # Python
|
||||
@@ -785,13 +812,19 @@ npm install cloakbrowser@latest # JavaScript
|
||||
docker pull cloakhq/cloakbrowser:latest # Docker
|
||||
```
|
||||
|
||||
**Binary download fails / timeout**
|
||||
---
|
||||
|
||||
### Binary download fails / timeout
|
||||
|
||||
Set a custom download URL or use a local binary:
|
||||
```bash
|
||||
export CLOAKBROWSER_BINARY_PATH=/path/to/your/chrome
|
||||
```
|
||||
|
||||
**New update broke something? Roll back to the previous version**
|
||||
---
|
||||
|
||||
### New update broke something? Roll back to the previous version
|
||||
|
||||
Install a specific wrapper version to downgrade both the wrapper and the binary it downloads:
|
||||
```bash
|
||||
pip install cloakbrowser==0.3.11 # Python
|
||||
@@ -800,23 +833,33 @@ docker pull cloakhq/cloakbrowser:0.3.11 # Docker
|
||||
```
|
||||
Each wrapper version pins its own binary version, so downgrading the wrapper automatically gets you the matching binary on next launch.
|
||||
|
||||
**macOS: "App is damaged" or Gatekeeper blocks launch**
|
||||
---
|
||||
|
||||
### macOS: "App is damaged" or Gatekeeper blocks launch
|
||||
|
||||
The binary is ad-hoc signed. macOS quarantines downloaded files. Run once to clear it:
|
||||
```bash
|
||||
xattr -cr ~/.cloakbrowser/chromium-*/Chromium.app
|
||||
```
|
||||
|
||||
**"playwright install" vs CloakBrowser binary**
|
||||
---
|
||||
|
||||
### "playwright install" vs CloakBrowser binary
|
||||
|
||||
You do NOT need `playwright install chromium`. CloakBrowser downloads its own binary. You only need Playwright's system deps:
|
||||
```bash
|
||||
playwright install-deps chromium
|
||||
```
|
||||
|
||||
**macOS: Blocked on some sites that pass on Linux**
|
||||
---
|
||||
|
||||
### macOS: Blocked on some sites that pass on Linux
|
||||
|
||||
The macOS fingerprint profile has known inconsistencies that aggressive bot detection catches. If a site blocks you on macOS but works on Linux, switch to a Windows fingerprint profile by passing `stealth_args=False` and manually setting `--fingerprint-platform=windows` with matching GPU flags (see [Fingerprint Management](#fingerprint-management) for the full flag list).
|
||||
|
||||
**Site detects incognito / private browsing mode**
|
||||
---
|
||||
|
||||
### Site detects incognito / private browsing mode
|
||||
|
||||
By default, `launch()` opens an incognito context. Some sites (like BrowserScan) detect this. Use `launch_persistent_context()` instead — it runs with a real user profile, so incognito detection passes:
|
||||
|
||||
@@ -838,7 +881,9 @@ const ctx = await launchPersistentContext({
|
||||
|
||||
This also gives you cookie and localStorage persistence across sessions.
|
||||
|
||||
**reCAPTCHA v3 scores are low (0.1–0.3)**
|
||||
---
|
||||
|
||||
### reCAPTCHA v3 scores are low (0.1–0.3)
|
||||
|
||||
Avoid `page.wait_for_timeout()` — it sends CDP protocol commands that reCAPTCHA detects. Use native sleep instead:
|
||||
|
||||
@@ -908,15 +953,21 @@ A: Yes. Pass `proxy="http://user:pass@host:port"` to `launch()`.
|
||||
|
||||
## Security
|
||||
|
||||
All binary releases are GPG-signed and include GitHub artifact attestations for supply chain verification.
|
||||
All releases are signed for supply chain verification.
|
||||
|
||||
```bash
|
||||
# Verify GPG signature
|
||||
# Verify GPG signature (binary release tag)
|
||||
gpg --keyserver keyserver.ubuntu.com --recv-keys C60C0DDC9D0DE2DD
|
||||
git verify-tag chromium-v145.0.7632.159.4
|
||||
git verify-tag chromium-v145.0.7632.159.6
|
||||
|
||||
# Verify binary attestation
|
||||
# Verify GitHub binary attestation (Sigstore)
|
||||
gh attestation verify cloakbrowser-linux-x64.tar.gz --repo CloakHQ/cloakbrowser
|
||||
|
||||
# Verify Docker image signature (Cosign/Sigstore)
|
||||
cosign verify \
|
||||
--certificate-identity-regexp "https://github.com/CloakHQ/CloakBrowser/" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
|
||||
cloakhq/cloakbrowser:latest
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
"""CLI for cloakbrowser — download and manage the stealth Chromium binary.
|
||||
|
||||
Usage:
|
||||
python -m cloakbrowser install # Download binary (with progress)
|
||||
python -m cloakbrowser info # Show binary version, path, platform
|
||||
python -m cloakbrowser update # Check for and download newer binary
|
||||
python -m cloakbrowser clear-cache # Remove cached binaries
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import sys
|
||||
|
||||
|
||||
def _setup_logging() -> None:
|
||||
"""Route cloakbrowser logger to stderr with clean output."""
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format="%(message)s",
|
||||
stream=sys.stderr,
|
||||
force=True,
|
||||
)
|
||||
# Suppress noisy HTTP request logs from httpx
|
||||
logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||
|
||||
|
||||
def cmd_install(args: argparse.Namespace) -> None:
|
||||
from .download import ensure_binary
|
||||
|
||||
path = ensure_binary()
|
||||
print(path)
|
||||
|
||||
|
||||
def cmd_info(args: argparse.Namespace) -> None:
|
||||
from .config import get_local_binary_override
|
||||
from .download import binary_info
|
||||
|
||||
info = binary_info()
|
||||
override = get_local_binary_override()
|
||||
|
||||
print(f"Version: {info['version']}")
|
||||
print(f"Platform: {info['platform']}")
|
||||
print(f"Binary: {info['binary_path']}")
|
||||
print(f"Installed: {info['installed']}")
|
||||
print(f"Cache: {info['cache_dir']}")
|
||||
if override:
|
||||
print(f"Override: {override} (CLOAKBROWSER_BINARY_PATH)")
|
||||
|
||||
|
||||
def cmd_update(args: argparse.Namespace) -> None:
|
||||
from .download import check_for_update
|
||||
|
||||
logger = logging.getLogger("cloakbrowser")
|
||||
logger.info("Checking for updates...")
|
||||
new_version = check_for_update()
|
||||
if new_version:
|
||||
print(f"Updated to Chromium {new_version}")
|
||||
else:
|
||||
print("Already up to date.")
|
||||
|
||||
|
||||
def cmd_clear_cache(args: argparse.Namespace) -> None:
|
||||
from .config import get_cache_dir
|
||||
from .download import clear_cache
|
||||
|
||||
if not get_cache_dir().exists():
|
||||
print("No cache to clear.")
|
||||
return
|
||||
clear_cache()
|
||||
print("Cache cleared.")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="cloakbrowser",
|
||||
description="Manage the CloakBrowser stealth Chromium binary.",
|
||||
)
|
||||
sub = parser.add_subparsers(dest="command")
|
||||
|
||||
sub.add_parser("install", help="Download the Chromium binary")
|
||||
sub.add_parser("info", help="Show binary version, path, and platform")
|
||||
sub.add_parser("update", help="Check for and download a newer binary")
|
||||
sub.add_parser("clear-cache", help="Remove all cached binaries")
|
||||
|
||||
args = parser.parse_args()
|
||||
if not args.command:
|
||||
parser.print_help()
|
||||
sys.exit(2)
|
||||
|
||||
_setup_logging()
|
||||
|
||||
commands = {
|
||||
"install": cmd_install,
|
||||
"info": cmd_info,
|
||||
"update": cmd_update,
|
||||
"clear-cache": cmd_clear_cache,
|
||||
}
|
||||
|
||||
try:
|
||||
commands[args.command](args)
|
||||
except KeyboardInterrupt:
|
||||
sys.exit(130)
|
||||
except Exception as e:
|
||||
print(f"Error: {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1 +1 @@
|
||||
__version__ = "0.3.12"
|
||||
__version__ = "0.3.14"
|
||||
|
||||
@@ -19,7 +19,7 @@ import os
|
||||
from typing import Any, Literal, TypedDict
|
||||
from urllib.parse import unquote, urlparse, urlunparse
|
||||
|
||||
from .config import DEFAULT_VIEWPORT, get_default_stealth_args
|
||||
from .config import DEFAULT_VIEWPORT, IGNORE_DEFAULT_ARGS, get_default_stealth_args
|
||||
from .download import ensure_binary
|
||||
|
||||
logger = logging.getLogger("cloakbrowser")
|
||||
@@ -111,7 +111,7 @@ def launch(
|
||||
executable_path=binary_path,
|
||||
headless=headless,
|
||||
args=chrome_args,
|
||||
ignore_default_args=["--enable-automation"],
|
||||
ignore_default_args=IGNORE_DEFAULT_ARGS,
|
||||
**_build_proxy_kwargs(proxy),
|
||||
**kwargs,
|
||||
)
|
||||
@@ -194,7 +194,7 @@ async def launch_async( # noqa: C901
|
||||
executable_path=binary_path,
|
||||
headless=headless,
|
||||
args=chrome_args,
|
||||
ignore_default_args=["--enable-automation"],
|
||||
ignore_default_args=IGNORE_DEFAULT_ARGS,
|
||||
**_build_proxy_kwargs(proxy),
|
||||
**kwargs,
|
||||
)
|
||||
@@ -305,7 +305,7 @@ def launch_persistent_context(
|
||||
executable_path=binary_path,
|
||||
headless=headless,
|
||||
args=chrome_args,
|
||||
ignore_default_args=["--enable-automation"],
|
||||
ignore_default_args=IGNORE_DEFAULT_ARGS,
|
||||
**_build_proxy_kwargs(proxy),
|
||||
**context_kwargs,
|
||||
)
|
||||
@@ -418,7 +418,7 @@ async def launch_persistent_context_async(
|
||||
executable_path=binary_path,
|
||||
headless=headless,
|
||||
args=chrome_args,
|
||||
ignore_default_args=["--enable-automation"],
|
||||
ignore_default_args=IGNORE_DEFAULT_ARGS,
|
||||
**_build_proxy_kwargs(proxy),
|
||||
**context_kwargs,
|
||||
)
|
||||
|
||||
+10
-2
@@ -15,15 +15,23 @@ from ._version import __version__
|
||||
# CHROMIUM_VERSION is the latest across all platforms (for display/reference).
|
||||
# Use get_chromium_version() for the current platform's actual version.
|
||||
# ---------------------------------------------------------------------------
|
||||
CHROMIUM_VERSION = "145.0.7632.159.4"
|
||||
CHROMIUM_VERSION = "145.0.7632.159.6"
|
||||
|
||||
PLATFORM_CHROMIUM_VERSIONS: dict[str, str] = {
|
||||
"linux-x64": "145.0.7632.159.4",
|
||||
"linux-x64": "145.0.7632.159.6",
|
||||
"darwin-arm64": "145.0.7632.109.2",
|
||||
"darwin-x64": "145.0.7632.109.2",
|
||||
"windows-x64": "145.0.7632.109.2",
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Playwright default args to suppress — these leak automation signals.
|
||||
# --enable-automation: exposes navigator.webdriver = true
|
||||
# --enable-unsafe-swiftshader: forces software WebGL rendering via SwiftShader,
|
||||
# producing a distinctive renderer string that no real user browser has
|
||||
# ---------------------------------------------------------------------------
|
||||
IGNORE_DEFAULT_ARGS = ["--enable-automation", "--enable-unsafe-swiftshader"]
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Default stealth arguments passed to the patched Chromium binary.
|
||||
# These activate source-level fingerprint patches compiled into the binary.
|
||||
|
||||
@@ -133,6 +133,17 @@ const browser = await launch({ proxy: 'http://proxy:8080', geoip: true, timezone
|
||||
|
||||
> **Note:** For rotating residential proxies, the DNS-resolved IP may differ from the exit IP. Pass explicit `timezone`/`locale` in those cases.
|
||||
|
||||
### CLI
|
||||
|
||||
Pre-download the binary or check installation status from the command line:
|
||||
|
||||
```bash
|
||||
npx cloakbrowser install # Download binary with progress output
|
||||
npx cloakbrowser info # Show version, path, platform
|
||||
npx cloakbrowser update # Check for and download newer binary
|
||||
npx cloakbrowser clear-cache # Remove cached binaries
|
||||
```
|
||||
|
||||
### Utilities
|
||||
|
||||
```javascript
|
||||
|
||||
+4
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cloakbrowser",
|
||||
"version": "0.3.12",
|
||||
"version": "0.3.14",
|
||||
"description": "Stealth Chromium that passes every bot detection test. Drop-in Playwright/Puppeteer replacement with source-level fingerprint patches.",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
@@ -15,6 +15,9 @@
|
||||
"import": "./dist/puppeteer.js"
|
||||
}
|
||||
},
|
||||
"bin": {
|
||||
"cloakbrowser": "./dist/cli.js"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* CLI for cloakbrowser — download and manage the stealth Chromium binary.
|
||||
*
|
||||
* Usage:
|
||||
* npx cloakbrowser install # Download binary (with progress)
|
||||
* npx cloakbrowser info # Show binary version, path, platform
|
||||
* npx cloakbrowser update # Check for and download newer binary
|
||||
* npx cloakbrowser clear-cache # Remove cached binaries
|
||||
*/
|
||||
|
||||
import { ensureBinary, binaryInfo, checkForUpdate, clearCache } from "./download.js";
|
||||
import { getLocalBinaryOverride, getCacheDir } from "./config.js";
|
||||
import fs from "node:fs";
|
||||
|
||||
const USAGE = `Usage: cloakbrowser <command>
|
||||
|
||||
Commands:
|
||||
install Download the Chromium binary
|
||||
info Show binary version, path, and platform
|
||||
update Check for and download a newer binary
|
||||
clear-cache Remove all cached binaries`;
|
||||
|
||||
async function cmdInstall(): Promise<void> {
|
||||
const binaryPath = await ensureBinary();
|
||||
console.log(binaryPath);
|
||||
}
|
||||
|
||||
function cmdInfo(): void {
|
||||
const info = binaryInfo();
|
||||
const override = getLocalBinaryOverride();
|
||||
|
||||
console.log(`Version: ${info.version}`);
|
||||
console.log(`Platform: ${info.platform}`);
|
||||
console.log(`Binary: ${info.binaryPath}`);
|
||||
console.log(`Installed: ${info.installed}`);
|
||||
console.log(`Cache: ${info.cacheDir}`);
|
||||
if (override) {
|
||||
console.log(`Override: ${override} (CLOAKBROWSER_BINARY_PATH)`);
|
||||
}
|
||||
}
|
||||
|
||||
async function cmdUpdate(): Promise<void> {
|
||||
console.error("Checking for updates...");
|
||||
const newVersion = await checkForUpdate();
|
||||
if (newVersion) {
|
||||
console.log(`Updated to Chromium ${newVersion}`);
|
||||
} else {
|
||||
console.log("Already up to date.");
|
||||
}
|
||||
}
|
||||
|
||||
function cmdClearCache(): void {
|
||||
const cacheDir = getCacheDir();
|
||||
if (!fs.existsSync(cacheDir)) {
|
||||
console.log("No cache to clear.");
|
||||
return;
|
||||
}
|
||||
clearCache();
|
||||
console.log("Cache cleared.");
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
const command = process.argv[2];
|
||||
|
||||
if (!command || command === "--help" || command === "-h") {
|
||||
console.log(USAGE);
|
||||
process.exit(command ? 0 : 2);
|
||||
}
|
||||
|
||||
try {
|
||||
switch (command) {
|
||||
case "install":
|
||||
await cmdInstall();
|
||||
break;
|
||||
case "info":
|
||||
cmdInfo();
|
||||
break;
|
||||
case "update":
|
||||
await cmdUpdate();
|
||||
break;
|
||||
case "clear-cache":
|
||||
cmdClearCache();
|
||||
break;
|
||||
default:
|
||||
console.error(`Unknown command: ${command}\n`);
|
||||
console.log(USAGE);
|
||||
process.exit(2);
|
||||
}
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
console.error(`Error: ${message}`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
+10
-2
@@ -27,10 +27,10 @@ export { WRAPPER_VERSION };
|
||||
// CHROMIUM_VERSION is the latest across all platforms (for display/reference).
|
||||
// Use getChromiumVersion() for the current platform's actual version.
|
||||
// ---------------------------------------------------------------------------
|
||||
export const CHROMIUM_VERSION = "145.0.7632.159.4";
|
||||
export const CHROMIUM_VERSION = "145.0.7632.159.6";
|
||||
|
||||
export const PLATFORM_CHROMIUM_VERSIONS: Record<string, string> = {
|
||||
"linux-x64": "145.0.7632.159.4",
|
||||
"linux-x64": "145.0.7632.159.6",
|
||||
"darwin-arm64": "145.0.7632.109.2",
|
||||
"darwin-x64": "145.0.7632.109.2",
|
||||
"windows-x64": "145.0.7632.109.2",
|
||||
@@ -188,6 +188,14 @@ export function getLocalBinaryOverride(): string | undefined {
|
||||
return process.env.CLOAKBROWSER_BINARY_PATH || undefined;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Playwright default args to suppress — these leak automation signals.
|
||||
// --enable-automation: exposes navigator.webdriver = true
|
||||
// --enable-unsafe-swiftshader: forces software WebGL rendering via SwiftShader,
|
||||
// producing a distinctive renderer string that no real user browser has
|
||||
// ---------------------------------------------------------------------------
|
||||
export const IGNORE_DEFAULT_ARGS = ["--enable-automation", "--enable-unsafe-swiftshader"];
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Default stealth arguments
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import type { Browser, BrowserContext } from "playwright-core";
|
||||
import type { LaunchOptions, LaunchContextOptions, LaunchPersistentContextOptions } from "./types.js";
|
||||
import { DEFAULT_VIEWPORT } from "./config.js";
|
||||
import { DEFAULT_VIEWPORT, IGNORE_DEFAULT_ARGS } from "./config.js";
|
||||
import { buildArgs } from "./args.js";
|
||||
import { ensureBinary } from "./download.js";
|
||||
import { parseProxyUrl } from "./proxy.js";
|
||||
@@ -45,7 +45,7 @@ export async function launch(options: LaunchOptions = {}): Promise<Browser> {
|
||||
executablePath: binaryPath,
|
||||
headless: options.headless ?? true,
|
||||
args,
|
||||
ignoreDefaultArgs: ["--enable-automation"],
|
||||
ignoreDefaultArgs: IGNORE_DEFAULT_ARGS,
|
||||
...(options.proxy
|
||||
? { proxy: typeof options.proxy === "string" ? parseProxyUrl(options.proxy) : options.proxy }
|
||||
: {}),
|
||||
@@ -163,7 +163,7 @@ export async function launchPersistentContext(
|
||||
executablePath: binaryPath,
|
||||
headless: options.headless ?? true,
|
||||
args,
|
||||
ignoreDefaultArgs: ["--enable-automation"],
|
||||
ignoreDefaultArgs: IGNORE_DEFAULT_ARGS,
|
||||
...(options.proxy
|
||||
? { proxy: typeof options.proxy === "string" ? parseProxyUrl(options.proxy) : options.proxy }
|
||||
: {}),
|
||||
|
||||
+2
-1
@@ -5,6 +5,7 @@
|
||||
|
||||
import type { Browser } from "puppeteer-core";
|
||||
import type { LaunchOptions } from "./types.js";
|
||||
import { IGNORE_DEFAULT_ARGS } from "./config.js";
|
||||
import { buildArgs } from "./args.js";
|
||||
import { ensureBinary } from "./download.js";
|
||||
import { parseProxyUrl } from "./proxy.js";
|
||||
@@ -62,7 +63,7 @@ export async function launch(options: LaunchOptions = {}): Promise<Browser> {
|
||||
executablePath: binaryPath,
|
||||
headless: options.headless ?? true,
|
||||
args,
|
||||
ignoreDefaultArgs: ["--enable-automation"],
|
||||
ignoreDefaultArgs: IGNORE_DEFAULT_ARGS,
|
||||
...options.launchOptions,
|
||||
});
|
||||
|
||||
|
||||
@@ -58,6 +58,9 @@ geoip = ["geoip2>=4.0"]
|
||||
patchright = ["patchright>=1.40"]
|
||||
dev = ["pytest>=7.0", "pytest-asyncio>=0.23"]
|
||||
|
||||
[project.scripts]
|
||||
cloakbrowser = "cloakbrowser.__main__:main"
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://github.com/CloakHQ/CloakBrowser"
|
||||
Documentation = "https://github.com/CloakHQ/CloakBrowser#readme"
|
||||
|
||||
Reference in New Issue
Block a user