Security

Last updated 2026-09-14.

This service accepts a domain name from anyone and then reads records that the owner of that domain controls. That makes every scanned value untrusted input, and the design follows from that.

Server-side request forgery

Exactly one server-side HTTP fetch exists: the MTA-STS policy file, which RFC 8461 places on an mta-sts subdomain of the scanned domain. That fetch is restricted to HTTPS on port 443, resolves the hostname itself, checks every address the name resolves to against a block list covering loopback, private RFC 1918 space, carrier-grade NAT, link-local including cloud metadata endpoints, documentation and reserved ranges, and their IPv6 equivalents including IPv4-mapped forms — then connects to the exact address it validated. Connecting to a validated address rather than resolving a second time is what defeats DNS rebinding. Redirects are not followed, the body is capped, and there are connect and read timeouts.

No other URL is fetched, no port scanning is performed, and no host or port supplied by a user is ever contacted.

DNS query limits

A scanned domain controls the records the scanner reads, including SPF includes that point at further records. Every scan runs against a hard query budget, caches every answer, detects include cycles, and bounds recursion independently of the budget, so no published record can turn one scan into unbounded lookups.

Rate limiting

Three independent controls: a per-client hourly budget, a per-domain cooldown so the scanner cannot be aimed repeatedly at a third party, and a global concurrency ceiling. Recent results are served from cache rather than re-queried. Limits return HTTP 429 with a retry hint rather than failing obscurely.

Output encoding

DNS record values are attacker-controlled strings that get displayed back. All HTML is built through a template function that escapes interpolated values by default; the rare pre-rendered fragment has to declare itself. The Content-Security-Policy allows scripts only from this origin, with no inline-script exception, because there is no inline script anywhere in the application.

Payments

Card details never reach this service; checkout is hosted by Stripe. A completed redirect from Stripe is not treated as proof of payment — the checkout session is fetched from Stripe's API and its payment status checked before anything is unlocked. Webhooks are verified against the raw request body using the endpoint signing secret before the payload is examined, and every event is claimed in the database before it is acted on, so Stripe's at-least-once delivery cannot fulfil an order twice.

Accounts

Passwords are hashed with scrypt at parameters costing roughly 64 MB of memory per hash. Sessions are server-side records referenced by a random cookie that is HttpOnly, SameSite and Secure in production. Login attempts are rate limited per email address.

Secrets

Secrets are supplied through the environment, never committed, and excluded from backups of the database. Log output passes through a redaction step that masks anything resembling an API key or bearer token before it is written.

Reporting a vulnerability

Report security issues to mAIb Tech. Please give enough detail to reproduce the problem, and please do not test against other people's domains or attempt to degrade the service for other users. Reports are welcome and will be acknowledged.