Security
SSRF defence, isolation and what we never store.
Every URL is treated as hostile
A screenshot API is a request-forgery machine aimed at its own infrastructure unless it is built otherwise. Before any browser starts:
- Only
httpandhttpsare accepted.file:,gopher:,ws:and custom schemes are rejected. - The hostname is resolved, and every address it returns is checked. One private answer rejects the whole request — a host that resolves to both a public and a private address is the shape of a DNS rebinding attack.
- Blocked ranges include loopback, RFC1918, link-local (including
169.254.169.254), CGNAT, multicast, IPv6 unique-local, and the IPv4-mapped IPv6 form of all of them. - Cloud metadata hostnames and Kubernetes service names are blocked by name as well as by address.
- Decimal, octal and hexadecimal IP encodings resolve to the same normalised address before the check, so they cannot slip past it.
The same policy applies to redirects, subresources (images, fonts, XHR, iframes), storage endpoints and webhook targets.
Isolation
Each job runs in its own browser context with downloads disabled, permissions denied by default, service workers blocked and no host filesystem access. Custom scripts run only in the page context: no require, no filesystem, no environment variables, no CDP. Infinite loops end at the job timeout.
What we never store
API keys (only a hash), signing secrets in plaintext, cookie values, Authorization headers, storage credentials, proxy passwords, or your provider keys. Request logs redact query parameters that look like credentials.
Artifacts without caching are deleted after a short window. With caching, they live for the TTL you chose, in a namespace that belongs to your organization alone.