diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-09 09:45:18 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-09 09:45:18 +0200 |
| commit | 6d5822b57bed2e2114814d8063d497372ea378ee (patch) | |
| tree | ce6f6d7f1dab6cf5c0bcd342527dff20817ba951 /tests/fixtures/redirector.eml | |
| parent | 524678a063a9bee80ce07e66ddc0ee18af4e4622 (diff) | |
| download | abusectl-6d5822b57bed2e2114814d8063d497372ea378ee.tar.gz abusectl-6d5822b57bed2e2114814d8063d497372ea378ee.zip | |
fix: percent-encode the component interpolated into an RDAP query
contacts.is_queryable() is the admission point and remains the real gate,
but this property has leaked three times already, each time the same shape:
a validator applied to one branch and forgotten on its sibling. First the
url branch was guarded and domain leaked, then domain was guarded and the
IP branch leaked through an IPv6 scope id.
query_ip and query_domain interpolated their component straight into the
path, so a caller reaching them without passing through worklist() could
put a separator, a query or a fragment on the wire. safe="" rather than
urllib's default safe="/" is the point: the default leaves the path
separator intact, which is exactly the traversal shape that leaked before.
query_domain still returns the UNQUOTED candidate, because that is what the
manifest records and the review dialog shows.
The tests call both functions directly, bypassing contacts, since a future
branch that skips the admission point is the failure this layer exists to
survive.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wrfqr2xqQfhtXCscU7zrdz
Diffstat (limited to 'tests/fixtures/redirector.eml')
0 files changed, 0 insertions, 0 deletions
