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.5

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.5
File Size Uploaded Provenance Actions
zerodom-0.1.5.tar.gz 640.2 kB With provenance Details for zerodom-0.1.5.tar.gz

Built distribution (wheel)

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

Total release size: 871.3 kB

Release files / zerodom-0.1.5.tar.gz

Download URL zerodom-0.1.5.tar.gz
Size 640.2 kB
Tags Source
SHA-256 checksum
How to use checksums
e100627ecc04d0c5ee43f46f2ed87ef98488566cdfa3b9b4864d4fa41adc9a85
BLAKE2b-256 checksum
How to use checksums
75a8870acac99ad8bcda15609b419867a5bee53c6cc57484fbf643d3f508f1f0
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 Nov 2, 2026.

Transparency log

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

Download URL zerodom-0.1.5-py3-none-any.whl
Size 231.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dd6f826eac2a17e962fdf52575940b60fc7beae0fbe64748e3b03ca922eca8a7
BLAKE2b-256 checksum
How to use checksums
de0e2b9f0afd7f426c06e84b4eb189abe96cce57090023d4630ab7c7e7684a10
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 Nov 2, 2026.

Transparency log

Security for zerodom 0.1.5

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.5.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 Nov 2, 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