Repository navigation
fix(ip): align client IP resolution with the reference engine - #136
Merged
Merged
Conversation
Port the reference extract_client_ip: canonical identity (IPv4-mapped IPv6 maps to IPv4), trusted proxy matching, trusted_proxy_depth semantics, port and bracket handling, the unix token and the redacted spoof report. The route_config check stores the result on request.state.client_ip and every check, ban, rate-limit key and event reads it instead of the raw connecting address. IP list entries and CIDRs are compared in canonical form. Closes #135
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.
Closes #135
This aligns client IP resolution with the reference engine (
guard_core/_utils/ip_extraction.py), so an IPv4 client on a dual-stack listener (::ffff:a.b.c.d) resolves to the same identity the lists, bans and rate-limit keys use.Engine (
@guardcore/core)extractClientIpis a full port of the reference: canonical identity (IPv4-mapped IPv6 without a scope id maps to IPv4,::1.2.3.4is no longer misread, zones are kept), trusted proxy matching on the connecting address as given,trustedProxyDepthcounted from the right with empty entries kept, port and bracket stripping, metacharacter and invalid entry rejection, the right-to-left walk when the depth over-counts proxy hops, theunixtoken for a request with no peer address, the cachedstate.client_ip, and the redacted spoof report for a header from an untrusted peer. The reference warn-once log lines are ported.route_configcheck stores the identity onrequest.state.client_ip.ip_security,rate_limit,suspicious_activity,cloud_provider,user_agentandemergency_moderead it, and the event bus, response factory, request logging, block payloads and the WebSocket guard use the same value (the WebSocket guard and two conformance harnesses used aclientIpstate key that nothing else read, so they now useclient_ip).ip-identity.tsholds the canonical text rules and oneipInList, replacing four separate list matchers. Entries and CIDRs compare in canonical form, so an IPv4 entry or CIDR matches an IPv4-mapped client, like_ip_in_list.canonicalizeIp(used by the ban manager) now comes from the same module.trustedProxiesacceptsunix(referenceallow_unix), and plain IP entries are validated with strict address parsing instead of ipaddr.js's lenient parser.Raw
clientHostreads replacedip-security.ts,rate-limit.ts,suspicious-activity.ts,cloud-provider.ts,user-agent.ts,emergency-mode.ts,route-config.ts(log line),block-events.ts,event-bus.ts,responses/factory.ts,utils.ts(scan and activity log context),websocket-guard.ts,bypass/handler.ts, and the four adapters' behavioral usage call.Tests
tests/test-utils/client-ip-parity.test.tsdrives 85 inputs whose expected values were produced by running the referenceextract_client_ip(ip-extraction-cases.ts), plus pipeline tests for blacklist, whitelist, CIDR, bans, rate-limit keys, emergency whitelist, trustedX-Forwarded-For, spoofedX-Forwarded-Forfrom an untrusted peer and the no-address path.::ffff:127.0.0.1.route_configran (state.client_ipset); the exempt-ips case that expected an IPv4 entry not to match an IPv4-mapped client now expects the reference behavior.pnpm build,pnpm lint,pnpm test,pnpm test:coverage(100/100/97/100) andmake conformancepass locally.