Conversation
…ed-card gap
`wire dial nick@127.0.0.1:8771` now reaches a local-dev / sandbox relay. The
federation-handle domain validator rejected any `:port`, so a custom-port
loopback relay couldn't be named in a handle at all (the V0_13_2 E4 item).
- `endpoints::is_loopback_host` — one shared predicate (exact `127.0.0.1` /
`localhost` / `::1`) now used by `infer_scope_from_url`, the validator, the
URL builder, and the phishing-warning suppression, so scheme and scope
classification can't drift.
- `is_valid_domain` accepts a `host:port` authority ONLY for a loopback host
(port 1..=65535). Non-loopback host+port stays rejected — public handles are
port-less; a public relay on a custom port belongs behind a 443 TLS edge.
- new `relay_url_for_domain` picks `http://` for a loopback authority, `https://`
otherwise, replacing the 4 unconditional `format!("https://{domain}")` fallback
sites (pair_profile, cli/pairing, cli/setup `wire up --relay`, mcp tool_add).
- `is_known_relay_domain` treats loopback as known — no spurious cross-relay
phishing warning for the operator's own machine.
Security (from the adversarial design review):
- MCP `tool_add` now runs the same poisoned-card DID-key fingerprint hard-refuse
the CLI `cmd_add` had — a rogue relay serving a card whose key != its claimed
DID is rejected on BOTH paths (was CLI-only; E4's loopback path made the MCP
gap newly reachable).
- THREAT_MODEL T14 documents the loopback-SSRF trade-off (prompt-injected dial to
a loopback port); bilateral accept + the fingerprint refuse remain the gates.
Tests: loopback parse / non-loopback reject / port-range unit tests +
relay_url_for_domain scheme regression guard; in-situ `wire dial nick@127.0.0.1:PORT`
pair + message round-trip over http loopback. Full lib suite green (615).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XmVWMe6fE54U1drShE1yMT
…oc, +tests Built-thing review of the E4 change (3 MINOR, no blockers): - Exclude IPv6 `::1` from `is_loopback_host`: it was accepted by the validator but `relay_url_for_domain` produced a bracket-less, malformed `http://::1:port`. IPv6 loopback handles aren't a real use case and need `[::1]:port` bracketing the handle path doesn't carry — reject cleanly instead. (`::1` was vestigial in `infer_scope_from_url` anyway: its host-extraction never yields a bare `::1`.) - Correct the `is_loopback_host` doc: it's the single predicate for the E4 TRUST-PATH gates, not literally every loopback check — `session.rs::url_is_loopback` is a separate, deliberately-broader /8 predicate for same-box session discovery. - Tests: reject `bob@:8771` (empty host) and `bob@::1:8771` (IPv6 exclusion). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XmVWMe6fE54U1drShE1yMT
Deploying wireup-landing with
|
| Latest commit: |
13888e5
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://a62e7705.wireup-landing.pages.dev |
| Branch Preview URL: | https://e4-clean.wireup-landing.pages.dev |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
wire dial nick@127.0.0.1:8771now reaches a local-dev / sandbox relay. The federation-handle domain validator rejected any:port, so a custom-port loopback relay couldn't be named in a handle at all — the E4 item indocs/V0_13_2_PLATFORM_HARDENING.md. (Builds on #357; the invite flow remains the path for non-loopback custom-port relays.)Change
endpoints::is_loopback_hostpredicate (exact127.0.0.1/localhost) now keys every E4 gate — the validator, the URL scheme builder,infer_scope_from_url, and the phishing-warning suppression — so scheme and scope can't drift.is_valid_domainaccepts ahost:portauthority only for a loopback host (port 1..=65535). Non-loopback host+port stays rejected.relay_url_for_domain→http://for loopback,https://otherwise, replacing all 4format!("https://{domain}")fallback sites (incl.wire up --relay 127.0.0.1:PORT).is_known_relay_domaintreats loopback as known — no spurious cross-relay phishing warning for the operator's own machine.Security (from the adversarial design review — 2 reviewers, gate-1 + gate-2)
tool_addnow runs the CLI's poisoned-card DID-key fingerprint hard-refuse — a rogue relay serving a card whose key ≠ its claimed DID is rejected on both the CLI and MCP paths (was CLI-only; E4's loopback path made the MCP gap newly reachable).::1handles intentionally rejected (would need[::1]:portbracketing the handle path doesn't carry) rather than half-accepted into a malformed URL.wire_accept+ the fingerprint refuse remain the gates.Tests
Loopback parse / non-loopback reject / port-range / empty-host / IPv6-reject unit tests + a
relay_url_for_domainpublic-path regression guard. In-situ:wire dial nick@127.0.0.1:PORT→ bilateral pair → message round-trip delivered + verified overhttp://127.0.0.1:PORT(the exact path that errored "domain invalid" before). Full lib suite green (615); pairing e2e (handle_pair + bilateral) green.🤖 Generated with Claude Code