aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_rdap.py
AgeCommit message (Collapse)AuthorFilesLines
32 hourstest: make two rdap tests able to fail, and cover the hostile bootstrapDanilo M.1-2/+106
test_the_walk_is_capped could not fail. Its host had nine labels, so the bare-TLD guard alone bounded the walk to eight attempts and the cap was never reached, and the assertion read rdap._MAX_LABEL_WALK at assert time, so the expected value moved with any mutation. Raising the cap to a billion left the suite green. It now uses a twelve-label host and a hard-coded expected count of five, and raising the cap fails it with 11 != 5. test_a_newline_in_an_address_is_rejected asserted a guarantee that a different function happened to provide. email.utils.parseaddr rejects the CRLF fixture by itself, returning an empty address, so deleting both control-character checks from _valid_address left the suite green while the real defence was gone. parseaddr passes \x0b and \x0c straight through, and those reach a mail header raw, so a case for each is added alongside the CRLF one, which is still worth asserting. The new HostileBootstrap cases cover the bootstrap defects fixed in the previous commit: a planted integer CIDR, a malformed services value in seven shapes, a plaintext base URL, and the two paths where a bad entry must not hide a good one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wrfqr2xqQfhtXCscU7zrdz
32 hoursfeat: query RDAP, walking up the labels for a registrable domainDanilo M.1-0/+80
RDAP wants the registrable domain and a deep host is not one. Rather than bundling a Public Suffix List, which is a transcribed table that goes stale weekly and is the failure init.PROVIDERS already documents, this asks the registry, which is the authority on what is registrable. The walk is capped and never queries a bare TLD. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wrfqr2xqQfhtXCscU7zrdz
32 hoursfeat: read abuse addresses from a jCard, strictlyDanilo M.1-0/+85
Only an entity whose roles contain abuse counts. No fallback to a technical or registrant contact, who is a named human that never volunteered for abuse mail, and no fallback to abuse@<domain> by convention: for a phishing domain that mailbox belongs to the attacker, so constructing it would confirm both the catch and that the reporter's address is live. Addresses are validated where they enter rather than where they are used, because the value becomes a mail recipient later and a control character in it is header injection into mail this tool sends. Entity recursion is depth capped so remote JSON cannot hang the tool. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wrfqr2xqQfhtXCscU7zrdz
32 hoursfeat: select an RDAP server by longest prefix and by TLDDanilo M.1-0/+51
Longest prefix rather than first match: a block delegated to a new operator appears as a more specific range inside its parent, and the wider range would name the operator that gave it away. A TLD that publishes no RDAP service selects nothing, which is a normal outcome for many TLDs rather than a defect. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wrfqr2xqQfhtXCscU7zrdz
32 hoursfeat: cache the IANA bootstrap, and prefer a stale copy to noneDanilo M.1-0/+73
Seven day TTL under XDG_CACHE_HOME, deliberately not in a case directory: this is a copy of a public map, not evidence. A failed refetch falls back to the stale copy. Staleness is safe in this direction, since a server that has moved simply misses and reads as no contact, while losing IANA entirely would stop the user filing a report. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wrfqr2xqQfhtXCscU7zrdz
32 hoursfeat: add the RDAP transport, with a redirect cap and no downgradeDanilo M.1-0/+56
The only socket in this tool. A redirect is remote data directing our next request, so hops are capped and an https to http downgrade is refused: a downgraded query travels in clear text and discloses which netblock is under investigation to anyone on the path. The timeout is mandatory rather than defaulted, because urllib with no timeout blocks forever and a hung registry would hang a review. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wrfqr2xqQfhtXCscU7zrdz