Skip to main content

ZeroDOM

PyPI License Discord Glama

Point it at an app as two users. It finds the broken access control.

ZeroDOM drives your real, logged-in browser as two identities, replays the same requests as each, and flags where one user reaches what another can't — IDOR / broken access control, caught deterministically. Open-core, runs local, no account, no API key, nothing leaves your machine.

Under the hunt is a deterministic, token-lean perception engine for AI agents — the same core powers scan, crawl and any browser-driving task. IDOR is just where it bites hardest.

A normal user is denied the admin console (401), then reaches it by flipping one client-controlled cookie. ZeroDOM replays the same request as both identities and reports the 401-vs-200 split.

Quickstart

See it run in 10 seconds — no account, no browser download (bare zerodom <url> is a static fetch):

pip install zerodom
zerodom https://news.ycombinator.com     # the interaction graph + a token report

Find an IDOR. Save two logged-in sessions as Playwright storage_state files (one per account), then diff a protected endpoint across both:

zerodom compare https://app.example.com/api/admin/dashboard \
  --as user=user.json --as admin=admin.json
{
  "identities": { "user": { "status": 401 }, "admin": { "status": 200 } },
  "only_admin": ["Manage users", "Billing & plans", "Overview"],
  "note": "admin authorized (200) where user denied (401) — broken access control if the only difference is client-controllable"
}

Same request, two identities, a 401-vs-200 split → a lead to confirm. No LLM guessing: ZeroDOM surfaces the tell with the exact replay that proves it. You confirm the bug.

How it hunts

  • zerodom compare — one endpoint across identities: a 401-vs-200 split, or a byte-identical cross-tenant response, is the IDOR tell.
  • zerodom sweep URL --as user=… --as admin=… — the whole app in one command: crawls as one identity to map the GET surface, replays every in-scope URL across all identities, reports only the deterministic tells (--format md for a report table).
  • zerodom crawl / scan / audit — recon: routes/forms/API plus the callable API surface (method + body) and DOM-XSS sinks read from the page's JS, response-header posture (CSP/CORS/cookie) and a csrf-posture correlation, and resolving the selectors in an existing test suite.
  • zerodom repeat / probe / race — act & verify: a Repeater (--save HAR/.http evidence), a tampered-body diff for mass assignment (probe --tamper), and a concurrent burst to flag a check-then-act race (race; HTTP/2 multiplexing via the zerodom[race] extra).

It drives your real Chrome (relay mode) over chrome.debugger — cookies, MFA, SSO already done — or a throwaway browser (--stealth). Read-only by default; scope is enforceable and lockable. Route through Burp/Caido with --proxy. Only test targets you're authorized to.

From an AI agent (MCP)

ZeroDOM is a native MCP server. Claude, Cursor, LangGraph, CrewAI, the OpenAI Agents SDK, Pydantic AI and more load the full 39-tool set from one config:

{ "mcpServers": { "zerodom": { "command": "uvx", "args": ["--from", "zerodom", "zerodom-mcp"] } } }

Run zerodom setup for a guided first-run. Runnable per-framework examples: examples/integrations/.

Why the agent sees so few tokens

A live page becomes a flat list where every entry has an id that resolves to exactly one element, and the CSS selector never enters the model's context:

[01] a 'Show HN: ZeroDOM — agents only need to know what they can click'
[02] a 'dev'
[03] a '214 comments'

Deterministic (lxml in, graph out, no LLM). Measured and re-runnable: ~71% fewer tokens than Playwright MCP's aria_snapshot(mode="ai") (mean; ~53–96% per site), 99.00% of 10,756 audited selectors across 111 live sites resolve to exactly one element, parse median 55ms.

Open core

Everything in the package — parser, CLI, relay, stealth, scan/crawl/compare/audit, the clearance ladder, the MCP server — is the free, Apache-2.0 Core, complete on its own: one operator, local, no account, no key. Enterprise is an additive team layer (fleet dashboard, compliance export packs, SSO/RBAC, SLA) that never gates, phones home from, or adds telemetry to the Core. Details: contact@vexralabs.com.


GitHub · Docs · Site · Discord — Apache-2.0, a Vexra Labs project.

Metadata

Release files for zerodom 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for zerodom 0.1.3
File Size Uploaded Provenance Actions
zerodom-0.1.3.tar.gz 578.8 kB With provenance Details for zerodom-0.1.3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for zerodom 0.1.3
File Interpreter ABI Platform Actions
zerodom-0.1.3-py3-none-any.whl Python 3 none any Details for zerodom-0.1.3-py3-none-any.whl

Total release size: 800.1 kB

Release files / zerodom-0.1.3.tar.gz

Download URL zerodom-0.1.3.tar.gz
Size 578.8 kB
Tags Source
SHA-256 checksum
How to use checksums
360fe8f51479ca9b1799c4b3bd4d4fe9d02f768940ab1e3a089c1f02cb14dcf9
BLAKE2b-256 checksum
How to use checksums
b0911f0ead9e76a48bdab88bd7528c78bf044f77aa318d6131a17fe7e20dc2b7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

Release files / zerodom-0.1.3-py3-none-any.whl

Download URL zerodom-0.1.3-py3-none-any.whl
Size 221.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f927db342040fcb628e12985a9db16375c2b15b71ccbdea55f6693b4ea75d2db
BLAKE2b-256 checksum
How to use checksums
94b825790f8e659ca586a21a0df991fae4bc37bd95fffa05fa1f99f52685128b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

Security for zerodom 0.1.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for zerodom-0.1.3.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page