BoundBench

Steel Browser

Open-source, self-hostable browser API (REST, WebSocket and Chrome DevTools) for AI agents and automation.

github.com/steel-dev/steel-browser · 2026-10-04 · e5902fc

Defense-in-depth score

2.4 / 10

Minimal

Steel Browser gives whoever drives it full control of a browser that holds logged-in sessions, and the network exposure and access control of its REST API and Chrome DevTools port in the shipped configuration are not locked down. Inside the root-run container, Chrome's own sandbox and site isolation are switched off, and the API will load Chrome extensions from arbitrary paths. Only run it on a private network behind your own authenticating proxy.

Key gaps (1)

  1. Untrusted web content driving or reaching the browser can exfiltrate data and take irreversible logged-in actions with no human involved. C5 · Untrusted input blast radius

Criteria

C1 Identity & least privilege

Minimal 0.05 / 1.00

Steel Browser has no per-caller identity or separation between callers: whoever drives it gets full control of the single shared browser, including every logged-in website session it holds. Access control on its HTTP, WebSocket and Chrome DevTools endpoints in the shipped configuration is not locked down.

C2 Approval gates

Minimal 0.00 / 1.00

As a tool server, Steel Browser does not give the host anything to gate on: endpoints carry no read-only or destructive hints, there is no dry-run, and the raw Chrome DevTools connection mixes reading and every possible browser action in one channel. Any irreversible action on a website (submitting forms, purchases, posts) is one CDP call away with no server-side confirmation.

C3 Tool & action scoping

Minimal 0.23 / 1.00

Request bodies are typed with Zod schemas and the file API checks that resolved paths stay inside its base directory, and named extensions are matched against a bundled directory. But URLs are passed straight to the browser and to a server-side fetch that follows redirects, with no block on localhost or cloud metadata addresses, and the session API accepts arbitrary extension paths and Chrome preferences. The full CDP channel is on by default, so the effective tool is 'do anything a browser can do'.

C4 Code-execution isolation

Moderate 0.57 / 1.00

Chromium executes untrusted page JavaScript and caller-supplied scripts via CDP inside the shipped Docker container. That container runs as root with no hardening, and because it runs as root the code automatically disables Chrome's own sandbox and also turns off site isolation. Chrome's environment is scrubbed to a few variables, but the container has unrestricted network access and a read-write bind mount of the host's ./.cache directory.

C5 Untrusted input blast radius

Minimal 0.25 / 1.00

Steel Browser's whole job is to load untrusted web pages for an agent. Scrape output separates content from metadata and records the source URL, but nothing marks content as untrusted or offers a read-only or no-egress mode. If an agent driving it is hijacked by page content, it can browse anywhere, use logged-in cookies, and submit forms with no server-side check.

C6 Memory, context & configuration integrity

Minimal 0.00 / 1.00

Steel has no AI memory store or instruction files, but the browser profile is its persistence: by default every session reuses the same Chrome user-data directory and nothing clears cookies or site storage between sessions or callers. Anything a malicious page plants (cookies, local storage, service workers) can carry into later sessions for any caller of the shared server. Uploaded files are cleaned on shutdown.

C7 Third-party extensions

Minimal 0.20 / 1.00

Chrome extensions are the extension surface. Named extensions are restricted to a directory bundled in the image, which by default holds only Steel's own recorder. However, the session API also accepts arbitrary filesystem paths through extra.orgExtensions.paths and loads them with no integrity check. Such an extension runs in the root-owned, unsandboxed browser with access to all sites.

C8 Secrets & sensitive-data protection

Minimal 0.45 / 1.00

Network header and body logging is off by default, the interaction recorder omits typed values and flags password fields, and no telemetry exporter is configured. But API responses expose sensitive session material. Browser cookies are long-lived account sessions.

C9 Audit & traceability

Minimal 0.33 / 1.00

Every API request is logged with client IP, URL, method and status, and the browser instrumentation records navigations, network and console events, which compose persists to a DuckDB file. Individual CDP commands sent by a client are not recorded as such, there is no caller identity beyond IP, and the stored logs are not protected from the clients they record. Writes are buffered and flushed every two seconds.

C10 Limits & kill switch

Minimal 0.33 / 1.00

Navigation in the action endpoints times out after 30 seconds, request bodies are capped at 100 MB and file storage per session at 100 MB, and releasing a session kills the Chrome process. But sessions have no timeout by default, the KILL_TIMEOUT setting is never read, delays are unbounded, and there are no rate limits despite the architecture docs claiming them.