# How are browser sessions, profiles, auth and anti-bot handled?

> Browser & computer control — a good answer covers: Local vs remote/cloud browsers; persistent profiles and cookies; stealth; proxies; CAPTCHA handling.

Canonical page: https://llms-technical-reviews.com/browser-control/q/sessions/

## Verdict

Both projects run local Chrome over CDP or a vendor cloud browser. Anti-bot features are mostly in the paid clouds.

[browser-use](/p/browser-use/) configures everything in `BrowserProfile`. Settings include `user_data_dir` for persistent profiles, `storage_state` files for cookies, HTTP/SOCKS proxies and allowed or prohibited domain lists, which a security watchdog enforces. Local Chrome starts with a list of flags such as `--disable-blink-features=AutomationControlled`. `use_cloud=True` requests a Browser Use Cloud browser with proxies, country selection and fingerprinting. When that cloud's solver is running, the agent pauses on CAPTCHA events and reports the result to the model.

[Stagehand](/p/stagehand/) offers two factories. `localBrowser.launch` starts Chrome with a temp or fixed `userDataDir`, a proxy flag and headless mode, then loads its extension. `browserbase.launch` creates a Browserbase session. Its options include advanced stealth, fingerprint settings, managed or external proxies, regions, CAPTCHA solving with selector hints, persistent contexts, recording and "verified" sessions. Cookies and extra headers are set through context methods. Any browser it drives must accept the Stagehand extension.

For self-hosted runs, both offer only profiles and proxies. Choose by cloud: Browser Use Cloud with browser-use, or Browserbase with Stagehand. Note that Stagehand needs a browser that can load extensions.

More projects in this category are being researched.

## Per-project answers

### browser-use/browser-use (answered)

**BrowserSession model.** `BrowserSession` (`browser_use/browser/session.py:134`) is the central session manager, owning CDP WebSocket connections, target/session maps, and an event bus coordinating 12+ watchdogs. Configuration is stored in a `BrowserProfile` (`browser_use/browser/profile.py`) which controls browser launch args, proxy, extensions, display config, domain filtering, etc. The session supports both Pydantic model construction and direct parameter overloading from a comprehensible API surface.

**Local vs Cloud browsers.** Two modes: **local** launches a Chrome/Chromium process via CDP, providing temporary or persistent profiles, and **cloud** creates remote browser instances through `cloud.browser-use.com` API (`browser_use/browser/cloud/cloud.py`). Cloud mode authenticates via `BROWSER_USE_API_KEY` env var or auth config file, calls the cloud API's `/v{2,3,4}/browsers` endpoint to get a CDP URL, then connects normally. Proxy country codes are configurable for geo-targeting. The agent auto-detects which mode via `BrowserProfile.use_cloud` or explicit `cloud_browser_params`.

**Persistent profiles and cookies.** `BrowserProfile` supports `user_data_dir` for persistent profiles, and `storage_state` for saved cookies/session data from Playwright's storage format. The `StorageStateWatchdog` saves/restores cookies and local storage on browser connect/disconnect. Cookies are loaded from a file specified in `BrowserProfile.storage_state` or from a user-data-dir profile. The `DownloadStorageStateEvent` is dispatched when saving state.

**Stealth and anti-detection.** Chrome is launched with automation-control flags disabled (`'--disable-blink-features=AutomationControlled'`, `browser_use/browser/profile.py:201`). Multiple fingerprint-reducing Chrome components are disabled (`CHROME_DISABLED_COMPONENTS` list, `browser_use/browser/profile.py:45-93`), including `AutomationControlled`, `HeavyAdPrivacyMitigations`, `CalculateNativeWinOcclusion`, `OverscrollHistoryNavigation`. Cloud browsers add proxy rotation and stealth fingerprinting on the server side.

**Proxies.** `ProxySettings` (in `BrowserProfile`) supports HTTP/SOCKS5 proxies with authentication. Cloud browsers offer country-code proxy selection (`ProxyCountryCode`). The `SecurityWatchdog` enforces `allowed_domains`/`prohibited_domains` lists, intercepting navigation attempts to blocked domains at the CDP level.

**Watchdog architecture.** `BrowserSession` uses an event-bus pattern with specialized watchdogs (`browser_use/browser/watchdogs/`): `LocalBrowserWatchdog` (Chrome process launch), `DownloadsWatchdog` (PDF auto-download with filename sanitization), `PopupsWatchdog` (JS alerts/dialogs), `SecurityWatchdog` (domain filtering, IP blocking, sensitive data), `DOMWatchdog` (DOM snapshot + element highlighting), `ScreenshotWatchdog` (screenshot capture + optional resize), `CaptchaWatchdog` (proxy CAPTCHA solver events), `AboutBlankWatchdog` (empty page redirects), `CrashWatchdog` (browser crash detection), `StorageStateWatchdog` (cookie/profile persistence), `PermissionsWatchdog` (browser permission management), `RecordingWatchdog`/`HARRecordingWatchdog`. Each watchdog attaches handlers to the session's event bus and is started/stopped with the browser lifecycle.

**CDP connection management.** `BrowserSession.connect()` establishes a WebSocket to the CDP URL, initializes a `CDPClient`, creates a `SessionManager` for target/session tracking, enables page monitoring (lifecycle events, accessibility), and dispatches `BrowserConnectedEvent`. WebSocket reconnection handles transient disconnects with exponential backoff (3 attempts, 1/2/4s delays, 54s total timeout). Connections carry an intentional-stopped flag so cleanup handlers don't cascade.

**CAPTCHA.** The `CaptchaWatchdog` listens for CDP `BrowserUse.captchaSolverStarted/Finished` events from the browser proxy (e.g., the cloud browser's integrated solver or a third-party solving service). It exposes `wait_if_captcha_solving()` which the agent loop calls. Cloud browsers' proxy-based CAPTCHA solver is claimed to reduce CAPTCHA encounters via stealth fingerprinting and IP rotation.

> **Editor's note.** Correction: CrashWatchdog is commented out in `session.py` (~L1700/L1715) and is not active.

Citations: [browser_use/browser/session.py:134-340](https://github.com/browser-use/browser-use/blob/7be96ed8bafa8dfe1eef228b59cf5c884b8b2431/browser_use/browser/session.py#L134-L340) · [browser_use/browser/session.py:567-594](https://github.com/browser-use/browser-use/blob/7be96ed8bafa8dfe1eef228b59cf5c884b8b2431/browser_use/browser/session.py#L567-L594) · [browser_use/browser/session.py:786-830](https://github.com/browser-use/browser-use/blob/7be96ed8bafa8dfe1eef228b59cf5c884b8b2431/browser_use/browser/session.py#L786-L830) · [browser_use/browser/profile.py:45-230](https://github.com/browser-use/browser-use/blob/7be96ed8bafa8dfe1eef228b59cf5c884b8b2431/browser_use/browser/profile.py#L45-L230) · [browser_use/browser/cloud/cloud.py:1-100](https://github.com/browser-use/browser-use/blob/7be96ed8bafa8dfe1eef228b59cf5c884b8b2431/browser_use/browser/cloud/cloud.py#L1-L100) · [browser_use/browser/watchdogs/captcha_watchdog.py:44-100](https://github.com/browser-use/browser-use/blob/7be96ed8bafa8dfe1eef228b59cf5c884b8b2431/browser_use/browser/watchdogs/captcha_watchdog.py#L44-L100)

### browserbase/stagehand (answered)

**Local browser** (`localBrowser.ts`): The SDK launches a Chrome/Chromium process with CDP remote debugging enabled (`--remote-debugging-port`). It auto-detects Chrome on the system (macOS: canonical paths; Windows: Program Files; Linux: PATH). Configurable via `LocalBrowserLaunchOptions`: `headless`, `viewport`, `proxy`, `locale`, `userDataDir` (persistent profile), `args` (extra flags). Default flags disable background networking, component updates, sync, hang monitor, and prompt-on-repost. A data directory is created per-session (temp dir) and cleaned up on close unless `preserveUserDataDir: true`. The sandbox is disabled on Linux root or CI.

**Browserbase cloud** (`browserbaseSession.ts`): Sessions are created via `@browserbasehq/sdk` with extensive configuration:
- **Stealth/fingerprint**: `advancedStealth`, `fingerprint` (browser/device/OS/locale/screen simulation)
- **Proxies**: Browserbase managed proxies (`BrowserbaseProxyConfigSchema` with geolocation) or external proxies (`ExternalProxyConfigSchema` with server/credentials)
- **Regions**: `us-west-2`, `us-east-1`, `eu-central-1`, `ap-southeast-1`
- **CAPTCHA handling**: `solveCaptchas`, `captchaInputSelector`, `captchaImageSelector`
- **Persistence**: `context.id` + `context.persist` for persistent browser contexts across sessions
- **Recording**: `recordSession`, `logSession`
- **Verification**: `verified` sessions for high-trust sites
- **BlockAds**, `os`, `viewport`

**Extension provisioning** (`browserbaseExtension.ts`): The Stagehand extension (packed as a `.zip` archive) is uploaded to Browserbase and attached to the session. Uploads retry up to 4 times with backoff.

**Cookies and headers**: `BrowserContext` in the understudy (`context.ts`) supports `addCookies`, `clearCookies`, `setExtraHTTPHeaders`, and `setDomainPolicy` (for domain-specific fetch interception). Cookies are manipulated via the CDP `Web.ARC` or native cookie stores.

**Connection modes**: The client can either create a new session (with an optionally provisioned extension) or reconnect to an existing session by session ID (`connectSession`). The CDP URL (`webSocketDebuggerUrl`) is used to establish the WebSocket transport.

**Lifecycle**: The `Stagehand.create()` to `stagehand.close()` lifecycle ensures browser claims are released and sessions are invalidated on ambiguous init failures (via `claimStagehandBrowser`/`releaseStagehandBrowser`/`invalidateStagehandBrowser` in `factories.ts`).


Citations: [packages/sdk-ts/src/browser/localBrowser.ts:14-43](https://github.com/browserbase/stagehand/blob/c9c8a41778b2000c9a9bdfc4b68e6c0c4866ab1a/packages/sdk-ts/src/browser/localBrowser.ts#L14-L43) · [packages/sdk-ts/src/browser/localBrowser.ts:104-167](https://github.com/browserbase/stagehand/blob/c9c8a41778b2000c9a9bdfc4b68e6c0c4866ab1a/packages/sdk-ts/src/browser/localBrowser.ts#L104-L167) · [packages/sdk-ts/src/browser/browserbaseSession.ts:72-133](https://github.com/browserbase/stagehand/blob/c9c8a41778b2000c9a9bdfc4b68e6c0c4866ab1a/packages/sdk-ts/src/browser/browserbaseSession.ts#L72-L133) · [packages/protocol/schemas.ts:888-963](https://github.com/browserbase/stagehand/blob/c9c8a41778b2000c9a9bdfc4b68e6c0c4866ab1a/packages/protocol/schemas.ts#L888-L963) · [packages/sdk-ts/src/browser/factories.ts:244-256](https://github.com/browserbase/stagehand/blob/c9c8a41778b2000c9a9bdfc4b68e6c0c4866ab1a/packages/sdk-ts/src/browser/factories.ts#L244-L256) · [packages/extension/understudy/context.ts:86-99](https://github.com/browserbase/stagehand/blob/c9c8a41778b2000c9a9bdfc4b68e6c0c4866ab1a/packages/extension/understudy/context.ts#L86-L99)
