feat(session): accept CIDR ranges in trusted_proxies - #98
Merged
Merged
Conversation
SessionConfig.is_trusted_proxy() matches an IP peer against single addresses and CIDR ranges (IPv4-mapped IPv6 peers count as IPv4), and keeps exact string matching for non-IP entries such as testclient. The middleware uses it for both the peer check and the X-Forwarded-For walk. Entries containing '/' that do not parse as a range fail validation. Closes #73
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 #73.
Changes
SessionConfig.is_trusted_proxy(address):ipaddress.ip_network(..., strict=False)parses the entries, so host bits in an entry like10.0.0.8/24are ignored.::ffff:10.1.2.3, as dual-stack sockets report it) matches IPv4 entries.testclient, keep exact string matching.lru_cache, not stored on the model, so a config made withmodel_copy(update=...)(which skips validation) never matches against stale ranges.get_client_ip()uses it for the trusted-peer check and for the rightmost-untrustedX-Forwarded-Forwalk./that does not parse as a range (for example10.0.0.0/33) raises at config creation.docs/SESSION.mddrop the "CIDR ranges are not supported" note and gain a range example. The CHANGELOG[Unreleased]section has an Added entry.Compatibility
Every entry that matched a peer before still matches the same peer. Matching only widens for IP entries: equal addresses written differently (
2001:DB8::1/2001:db8::1) and the IPv4-mapped form now also match.The one new rejection is an entry containing
/that is not a valid range. Such an entry could only ever have matched a peer string containing/, which no socket reports.Tests
tests/session/test_client_ip.pycovers:testclient.X-Forwarded-Forwalk that skips every hop inside a trusted range.model_copyupdate.Mutation checks:
Local results:
zensical build --strict: passes.CACHEX_REQUIRE_LIVE_SERVERS=1against Redis and Memcached: 716 passed, 100% coverage.tests/sessionon Python 3.10: passes.