From 2ebc10f4e5e6e54e54cec5420d8fbba61c0a501a Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Tue, 8 Sep 2026 12:41:45 +0200 Subject: Initial commit: umbrella design for abusectl An abuse reporting sidecar for phishing mail: parse a flagged message, extract its indicators, resolve abuse contacts, and file the result to a MISP instance and to public abuse channels. This is the umbrella spec, agreed in one design session. Each part gets its own spec before it is built; this settles what the parts share and what would be expensive to change later: the case directory and its manifest format, the redaction rule, the ordering between MISP and the vendors, and how partial failure is recorded. It exists as a separate tool because qtmaildir does no network protocol work by design, and this needs RDAP, three vendor APIs and mail to abuse desks. qtmaildir invokes it by name the way it invokes mailsync.sh, and hosts the review dialog; the two are coupled only by the manifest format and a command name in config. Two properties are recorded as safety properties rather than preferences. Recipient identifiers are never captured, at extraction rather than at submission, so the tool cannot disclose an identifier it was never given; tracking tokens inside URLs are covered, since a parameter value is frequently the recipient's address. And nothing remote is fetched while parsing, because following a link confirms the address is live and fires the tracker. parse is the first part to build: stdlib only, no network, no config, and its output is the format every other part reads. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01KphFXTc2QajxXsHWyvGJ4R --- README.md | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 README.md (limited to 'README.md') diff --git a/README.md b/README.md new file mode 100644 index 0000000..78eb42f --- /dev/null +++ b/README.md @@ -0,0 +1,73 @@ +# abusectl + +Abuse reporting for phishing mail. Parses a flagged message, extracts its +indicators, resolves who to report each one to, and files the result to a +MISP instance and to public abuse channels. + +**Status: early.** The design is settled and the first part is being built. +Nothing here submits anything yet. + +## What it does + +``` +abusectl parse msg.eml # -> case directory, IOCs offline +abusectl contacts # + abuse contacts via RDAP network, read-only +abusectl report # + report bodies offline + # review the bodies, by hand or in a mail client +abusectl submit # MISP, then the vendors network, writes +``` + +Each subcommand runs on its own and is useful on its own. `parse` triages a +message with no configuration at all; `parse`, `contacts` and `report` +together produce a document you can send by hand with no API key anywhere. + +State lives in a **case directory** rather than in memory, so a review can +take a week and survive a reboot. + +## Two properties that are not negotiable + +**Recipient identifiers are never captured.** Not the `To`, `Cc`, +`Delivered-To` or `X-Original-To` headers, not your Message-IDs, not maildir +paths or account names. They are dropped at extraction rather than stripped at +submission, so the tool cannot disclose an identifier it was never given. +Tracking tokens inside URLs count: parameter values are redacted, parameter +names and paths are kept, because the names fingerprint the kit and the values +identify you. + +**Nothing remote is ever fetched while parsing.** Not the URLs, not the +redirect chains, not remote images. Following a link confirms your address is +live to the sender and fires exactly the tracker the message wanted. Redirect +chains are read from headers and link text, never by following them. + +## Reversible and irreversible + +`submit` writes to MISP first and stops if that fails. MISP is your own +instance and is correctable; a report to AbuseIPDB, URLhaus or VirusTotal +cannot be recalled. The reversible step gates the irreversible ones, and it is +also what answers "have I reported this infrastructure before". + +Every destination carries its own status, so a retry sends only what failed. A +rate-limited vendor does not mean re-reporting to the three that accepted. + +## Design + +`docs/specs/2026-09-08-abusectl-design.md` is the umbrella design. Each part +gets its own spec before it is built. + +## Requirements + +Python 3.11 or newer. `parse` and `report` need nothing else; `contacts` needs +an HTTP client and `submit` needs PyMISP. Development runs from a venv in the +checkout. + +## License + +GPLv2. See `LICENSE`. + +## Development Approach + +This project is developed using AI-assisted tools. Code is generated with the help of AI based on human-provided specifications, design decisions, and iterative feedback. + +All contributions are reviewed, tested, and curated by the maintainer before being included in the codebase. AI is used as a productivity and exploration tool, while human oversight remains central to all decisions. + +The goal is to combine the flexibility of AI-assisted development with standard open-source practices such as transparency, review, and accountability. -- cgit v1.2.3