carlos / platform Public
Reviewed 7ebc545e. The “no privilege over the public door” claim remains false: unknown can make downstream address handling fall back to a caller-controlled header or loopback.
| Round-3 finding | Disposition | |---|---| | R3-1: address trust grants application/gate authority | Partly. Rotating XFF no longer changes the local gate’s limiter key. Application authority remains possible through the new unknown representation; see finding 1. | | R3-2: ownership residuals have no maximum lifetime | Partly. The bounds are now stated honestly, but classifying the residuals as harmless still depends on the disproved no-privilege claim. | | R3-3: forwarded scheme differs by placement | Closed. Task 5 explicitly supplies https locally; the receiving TLS edge supplies it remotely. | | R3-4: renewal/example contradictions | Closed. Publication advances only below the bucket revision (plan:473); the option takes one argument (plan:745). |
The no-port RemoteAddr itself is handled safely: both gate.go:230 and analytics.go:86 fall back to the raw string. Go’s SetXForwarded deletes XFF on that parse failure, after which Task 5 sets unknown. I found no reachable parser that panics on the synthetic address. The findings below come from source tracing, not execution of the unbuilt plan.
- P1 —
unknowncan restore caller-address authority or make the application see loopback.
Task 5 supplies X-Forwarded-For: unknown (plan:652), while the scrubber leaves Client-IP untouched (homemap.go:806).
Rails 8.0.2 provides a concrete counterexample. Its address resolver discards non-IP XFF values. With unknown, its forwarded-address list becomes empty, disabling the comparison that normally rejects a conflicting Client-IP. It can therefore return an attacker-selected Client-IP. Without that header, it falls back to the backend peer address. Rails RemoteIp implementation.
For an application behind CARLOS’s loopback TCP proxy (edge.go:2182), that fallback is loopback. Rails then considers the request local when both peer and resolved addresses are loopback. Rails local? implementation.
Thus an application authorizing by resolved IP or locality can admit a door request that its public counterpart rejects. This also restores the security consequence of stale cross-app ownership.
Required: preserve Paul’s no-caller-address ruling, but specify downstream handling that cannot accept alternate address headers or fall back to privileged peers. Add real framework tests for local and backhauled requests, with and without Client-IP. Merely asserting the raw XFF value is insufficient.
- P2 — Cache variation sees different headers from the application.
The door removes inbound forwarding headers (plan:711). Task 5 regenerates them only on pr.Out. Meanwhile, cache lookup uses the inbound request (edge.go:1583), and storage computes Vary from that same inbound request (edge.go:1702).
Consider an application returning cacheable, address-dependent content with Vary: X-Forwarded-For. A local door response generated for unknown is stored under an empty XFF value. An ordinary public request without XFF matches it, even though its upstream address would be a real client IP. The reverse ordering also serves the wrong representation. Successful backhaul instead supplies inbound unknown, creating different behavior by placement.
This exposes an existing inbound/outbound cache mismatch through the new door.
Required: make cache selection reflect effective upstream forwarding values, or exclude responses varying on rewritten headers. Test public→door and door→public cache reuse, including backhaul.
- P2 — Failed hop verification breaks the promised address representation.
Task 5 explicitly leaves acceptHop unchanged (plan:666). If the receiving edge cannot verify the sender’s mesh key, it strips forwarding headers and continues as an ordinary request (homemap.go:793).
The door context never crossed the connection. Consequently, the receiving proxy generates XFF from the sending edge’s network address instead of preserving unknown. Analytics also uses that peer address. The unconditional “no real address” and placement-equivalence promises therefore fail during verification failure.
Required: define this failure outcome explicitly and add a two-edge mismatched-key test. If unknown is mandatory, delivery must refuse rather than silently substitute an infrastructure address.
- P3 — The stated gate and visitor aggregation contracts are inaccurate.
Plan:14 promises one guessing limit and one visitor per app per box. The gate actually includes the route host in its limiter key (gate.go:151). After backhaul, it keys on the sending edge’s address, not the app marker.
Analytics hashes host and User-Agent alongside the address (meter.go:178); successful backhaul supplies unknown instead of the local app marker.
Required: document these actual partitions and test them, or specify the changes needed to deliver the promised aggregation.
The plan is not ready to build.