mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-19 21:52:21 +03:00
Implements end-to-end proxy egress isolation with address-family enforcement and closes four real IP-leak paths surfaced by the proxy subsystem audit. IPv6-only egress: - Detect proxy family (IPv6/IPv4 literal, or per-account auto/ipv4/ipv6 directive) and pin the connect family (family:6/4 + autoSelectFamily:false) on both ProxyAgent (proxyTls) and a custom SOCKS connector that threads socket_options.family into SocksClient (fetch-socks can't), so Happy Eyeballs cannot pick IPv4 for an IPv6-only policy. - De-bracket IPv6-literal proxy hosts (socksOptions.host + proxyHealth tcpCheck) — fixes ENOTFOUND on [::1]-style SOCKS proxies and health checks. - Fail-closed when an IPv6-only hostname proxy has no AAAA (PROXY_FAMILY_UNAVAILABLE) instead of leaking over v4. - DB migration 099 adds the proxy family column; family is preserved through the resolveProxyForConnection cascade and proxies/upstreamProxy modules. Leak fixes: - L1: web TLS clients (grok/claude/chatgpt/perplexity) now fail-closed on proxy-resolution error instead of silently going direct (was the highest-risk asymmetry). - L2: safeResolveProxy fail-closed by default (PROXY_FAIL_OPEN opt-out). - L3: API-key usage/quota fetch routed through the connection proxy context. - L4: NVIDIA validation proxy bypass (#3226) documented. Tests: 46 TDD unit tests + BDD egress-isolation matrix. typecheck:core + eslint clean. Gemini 'critical' SOCKS finding verified as a false positive (socks accepts proxy.host; see PR thread). Integrated into release/v3.8.24.
30 lines
1.3 KiB
Gherkin
30 lines
1.3 KiB
Gherkin
Feature: Proxy egress isolation and IPv6-only enforcement
|
|
As an operator routing provider traffic through proxies
|
|
I want every request to egress only through the assigned proxy (and only over IPv6 when an IPv6 proxy is set)
|
|
So that the real host IP and IPv4 are never leaked
|
|
|
|
Scenario: IPv6-literal proxy de-brackets and connects over IPv6
|
|
Given a proxy configured as socks5://[2001:db8::1]:1080
|
|
When the dispatcher options are built
|
|
Then the SOCKS host is 2001:db8::1 and the resolved family is 6
|
|
|
|
Scenario: IPv6 hostname proxy forces IPv6-only egress
|
|
Given a proxy hostname with family=ipv6
|
|
When the dispatcher family is resolved
|
|
Then the connect family is pinned to 6
|
|
|
|
Scenario: IPv6-only egress is fail-closed when no AAAA exists
|
|
Given a proxy hostname with family=ipv6 and no AAAA record
|
|
When the family is asserted
|
|
Then it is refused and never egresses over IPv4
|
|
|
|
Scenario: Family directive contradicting a literal is rejected
|
|
Given a proxy 203.0.113.7 with family=ipv6
|
|
When the dispatcher family is resolved
|
|
Then it throws a configuration error
|
|
|
|
Scenario: Web TLS clients are fail-closed
|
|
Given a web TLS client whose proxy resolution throws
|
|
When the proxy URL is resolved
|
|
Then it throws instead of connecting directly
|