aboutsummaryrefslogtreecommitdiffstats
path: root/abusectl
AgeCommit message (Collapse)AuthorFilesLines
3 daysfeat: command line for init and parseDanilo M.2-0/+234
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KphFXTc2QajxXsHWyvGJ4R
3 daysfeat: first-run config builderDanilo M.1-0/+295
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KphFXTc2QajxXsHWyvGJ4R
3 daysfix: reject non-list relays and empty cases valuesDanilo M.1-2/+20
An empty cases string resolved to Path("") = cwd, scattering evidence wherever the command happened to run. A string trusted_relays (easy to hand-write without brackets) iterated as characters, failing on '1' with an error naming nothing findable in the file. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KphFXTc2QajxXsHWyvGJ4R
3 daysfeat: read and validate the configDanilo M.1-0/+86
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KphFXTc2QajxXsHWyvGJ4R
3 daysrefactor: one URL scan serving both the report and the flaggingDanilo M.1-29/+24
The IOC assembly needed each URL in two forms: redacted for the report, original to recognise a suspect token, since by the time a query value reads REDACTED there is nothing left to look at. That arrived as a second scanner rebuilding a {redacted: original} mapping by repeating urls()'s own walk, which is two functions that have to stay in step by hand. One private _scan_urls() returns both forms instead. urls() keeps its signature and is now a sort over its keys, and the two forms cannot drift because nothing derives one from the other twice. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KphFXTc2QajxXsHWyvGJ4R
3 daysfeat: assemble IOCs in the manifest's shapeDanilo M.1-0/+105
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KphFXTc2QajxXsHWyvGJ4R
3 daysfeat: case directory with an atomically written manifestDanilo M.1-0/+132
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KphFXTc2QajxXsHWyvGJ4R
3 daysfeat: extract URLs and attachment hashes, fetching nothingDanilo M.1-0/+120
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KphFXTc2QajxXsHWyvGJ4R
3 daysfeat: extract sender domains and auth verdictsDanilo M.1-1/+68
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KphFXTc2QajxXsHWyvGJ4R
3 daysfeat: walk the Received chain to the trust boundaryDanilo M.1-0/+114
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KphFXTc2QajxXsHWyvGJ4R
3 daysfix: redact fragment and strip userinfo, flag hidden query in pathDanilo M.1-11/+69
The query string was not the only place a recipient identifier can hide. A fragment (#e=victim@...) is published as-is since we report the URL's literal text, not what a browser would send. Userinfo (user:pass@host) leaks a credential as well as an identifier, so it is stripped outright rather than redacted in place. A path segment can also smuggle an encoded query (%3Fe=victim@...); suspect_path_segments now flags a segment that decodes to something containing '=' or '@', still leaving the decision to redact or not to human review. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KphFXTc2QajxXsHWyvGJ4R
3 daysfeat: redact recipient identifiers inside URLsDanilo M.1-0/+105
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KphFXTc2QajxXsHWyvGJ4R
3 daysfeat: package skeletonDanilo M.1-0/+17
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KphFXTc2QajxXsHWyvGJ4R