Skip to main content

MigrateSafe

tests PyPI DOI License: MIT

Read-only security audit for domain migrations.

When a web platform moves from old.example to new.example, there is a window in which two names, two hosting environments and two sets of DNS, TLS and e-mail settings coexist. MigrateSafe checks that window for dangling records, certificate anomalies, transport/session downgrades, spoofable mail, broken redirects and configuration drift.

It implements the fourteen verification checks (C1–C14) from:

A. A. More, “MigrateSafe: A threat model and verification framework for secure domain migration of web-hosted cryptocurrency trading platforms,” Zenodo, preprint, Oct. 2026, doi: 10.5281/zenodo.23576774.

Install

Requires Python 3.9+ and dnspython.

pip install migratesafe

Or run from a checkout without installing (dnspython must be available):

python3 -m migratesafe audit --new new.example --old old.example

Usage

# full audit of a completed migration
migratesafe audit --new new.example --old old.example

# only the checks that matter up to a given phase (P0 preparation ... P4 retirement)
migratesafe audit --new new.example --old old.example --phase P1

# a subset of checks, with a JSON report for CI or record keeping
migratesafe audit --new new.example --checks C5,C9,C13 --json report.json

# include a scan of the application source for leftover references to the old name
migratesafe audit --new new.example --old old.example --project ~/code/exchange --config migratesafe.json

migratesafe list

Exit codes: 0 all passed, 1 warnings or errors, 2 at least one failure, which makes it usable as a CI gate.

Checks

ID Check Threats How it is verified
C1 Zone inventory T1, T2 Hostnames from CT logs (crt.sh) and common-name probing are compared with your inventory
C2 Dangling targets T1 CNAME/MX/NS targets that no longer resolve; known takeover fingerprints on SaaS targets
C3 Delegation T3 Parent NS set equals zone NS set; every nameserver answers authoritatively
C4 DNSSEC T3 DS at parent and AD-validated answers, or a documented exception
C5 CAA T4 issue/issuewild restrict CAs and an iodef contact exists
C6 CT audit T1, T4 Recent certificates are from allowed issuers / permitted by CAA
C7 New-origin TLS T4, T5 Valid chain, expiry, SAN scope, TLS 1.0/1.1 refused
C8 Former-host keys T4 The former host no longer serves a trusted certificate for your names
C9 HSTS T5 max-age ≥ 1 year with includeSubDomains from phase P3
C10 Legacy redirect T5, T8 301/308 to https://new, path preserved, no open redirect
C11 Session cookies T1, T5 Host-only, Secure, HttpOnly, SameSite
C12 Allow-lists and configuration T2, T8 Source scan for the old name; Laravel .env checks (APP_URL, SESSION_DOMAIN, ...)
C13 E-mail authentication T2, T6 SPF -all, DKIM, DMARC p=reject; Null MX + v=spf1 -all on a retired name
C14 Retention and lookalikes T2, T7 RDAP expiry and transfer lock; registered typo/TLD lookalikes

Threat classes: T1 dangling records / subdomain takeover, T2 residual trust, T3 delegation hijack, T4 certificate anomalies, T5 transport/session downgrade, T6 e-mail spoofing, T7 lookalike domains, T8 configuration drift.

CT data comes from the public crt.sh service, which can lag behind the logs by hours and occasionally returns incomplete results; treat C1/C6 output as a lower bound and re-run if crt.sh is unavailable.

Some things cannot be observed from outside (revoked sessions, provider dashboards, registrar MFA); those are reported as MANUAL items so they still appear on the checklist.

Configuration (optional)

See example-config.json:

{
  "inventory": {"new.example": "migrate", "www.new.example": "migrate", "status.old.example": "delete"},
  "allowed_issuers": ["Let's Encrypt"],
  "dkim_selectors": ["default"],
  "old_host_ip": "203.0.113.10",
  "dnssec_exception": false,
  "old_domain_mail": "retired",
  "session_paths": ["/", "/login"],
  "config_ignore": ["CHANGELOG.md"]
}

Safety and ethics

MigrateSafe is read-only. It performs ordinary DNS queries, HTTPS requests and TLS handshakes, and reads public CT and RDAP data. It never claims resources, requests certificates or modifies anything. Values of secret-looking keys are masked when .env lines are reported. Only audit domains you own or are authorised to test.

Evaluation (fault injection)

evaluation/ runs all fourteen checks, unchanged, against a simulated Internet (DNS, HTTP, TLS, CT and RDAP in memory). It starts from a correctly migrated baseline and injects 28 faults covering threats T1–T8:

python3 -m evaluation.run      # writes evaluation/results.md and results.json

Current result: 27/28 faults flagged by the expected check, 1 (registered lookalike) reported as INFO by design, and 0 false positives on the baseline. See evaluation/results.md for the per-fault table and limitations.

Tests

python3 -m unittest discover -s tests -v

Author

Er. Abhijeet Ashok More (myabhya). Director, Cyin Solutions Pvt Ltd; Founder, Sumantrak. ORCID 0009-0001-4934-0204 · Google Scholar · LinkedIn

Citation

@misc{more2026migratesafe,
  author       = {More, Abhijeet Ashok},
  title        = {MigrateSafe: A Threat Model and Verification Framework for Secure Domain
                  Migration of Web-Hosted Cryptocurrency Trading Platforms},
  year         = {2026},
  publisher    = {Zenodo},
  doi          = {10.5281/zenodo.23576774},
  note         = {Preprint}
}

License

MIT, see LICENSE.

Metadata

Release files for migratesafe 0.1.0

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

Source distribution (sdist)

Source distribution for migratesafe 0.1.0
File Size Uploaded Provenance
migratesafe-0.1.0.tar.gz 30.1 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 58.4 kB

Release files / migratesafe-0.1.0.tar.gz

Download URL migratesafe-0.1.0.tar.gz
Size 30.1 kB
Tags Source
SHA-256 checksum
How to use checksums
ad5a6bf98f9d3b6ee8df4483cd61cac72ba87cb41da5105bdc8e1ca17a89883a
BLAKE2b-256 checksum
How to use checksums
54b0d1b683c54e1e9f53248303c664d13fe5c42d16d5efb1d4f857f64cba08e1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.15

Release files / migratesafe-0.1.0-py3-none-any.whl

Download URL migratesafe-0.1.0-py3-none-any.whl
Size 28.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3d8657ea35a2d58c6e6071ec195a595d937d8d06f54cd19a5cf675c16c2b4cb2
BLAKE2b-256 checksum
How to use checksums
f3bd67e2796ec91ddd9b0ab481e9b03e18e154ad818f0a1f3da126ec033e1a3d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.15

Security for migratesafe 0.1.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

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