Skip to content

Support multiple and CIDR-based trusted_proxy entries - #517

Closed
smoltafet wants to merge 1 commit into
Pylons:mainfrom
smoltafet:feat/trusted-proxy-multiple-cidr
Closed

smoltafet wants to merge 1 commit into
Pylons:mainfrom
smoltafet:feat/trusted-proxy-multiple-cidr

Conversation

@smoltafet

Copy link
Copy Markdown

Fixes #478

Problem

trusted_proxy accepts exactly one address. When waitress runs behind a proxy whose address is not constant — the reporter runs traefik in K3s, where pod IPs change — a single trusted address is not enough, so proxy headers from legitimate proxies get cleared/ignored.

Change

adjustments.py

  • New as_trusted_proxies caster normalizes the trusted_proxy adjustment to a list of entries. Accepted inputs: a single string ("192.168.1.1", "10.0.0.0/8", "*"), a string with multiple entries separated by whitespace and/or commas (the form usable from the CLI / config files), or an iterable of strings. Empty input still means None (no trusted proxy), and the existing trusted_proxy_count / trusted_proxy_headers validation is unchanged.
  • Note: Adjustments.trusted_proxy is now a list of entries (or None) instead of a string; the one test asserting the attribute's value was updated accordingly. waitress.serve(..., trusted_proxy="192.168.1.1") and --trusted-proxy=192.168.1.1 behave exactly as before.

proxy_headers.py

  • New _is_trusted_proxy() matcher used by proxy_headers_middleware. A peer is trusted when any entry:
    • is "*" (existing behaviour, now also usable as one entry among several),
    • matches the peer address exactly (existing behaviour for single addresses and non-IP values),
    • or parses as an IP network via ipaddress.ip_network(..., strict=False) — covering both CIDR ranges (10.0.0.0/8, 2001:db8::/32) and single IPs — and contains the peer's IP address.
  • Entries that are not valid IPs/networks only match exactly, so no previously-accepted value changes meaning, and malformed entries are ignored rather than fatal.

proxy_headers_middleware itself accepts a string or an iterable for trusted_proxy, so standalone users of the middleware get the same behaviour.

Tests

  • tests/test_proxy_headers.py: list matching (hit and miss), IPv4 CIDR in/out of range, IPv6 CIDR, mixed CIDR + exact entries, "*" inside a list, invalid entries ignored.
  • tests/test_adjustments.py: normalization of single string, space-separated, comma-separated, list input, "*", and empty input.
  • Full suite: 835 passed, 8 skipped (baseline on master: 821 passed, 8 skipped — the delta is exactly the new/updated tests; no failures).

Disclosure: this change was prepared with AI assistance and verified by running the project's test suite locally.

trusted_proxy previously accepted exactly one address, which
does not work when the proxy's address is not constant (e.g.
traefik pods in Kubernetes). The adjustment now normalizes to
a list of entries (single string, whitespace/comma separated
string, or iterable), and the proxy-header middleware trusts a
peer when any entry is "*", matches the peer exactly, or is
an IP network (CIDR range or single IP) containing the peer's
address. Single-address configurations behave as before.
@smoltafet

Copy link
Copy Markdown
Author

Hi @kgaughan, could you take a look at this when you have a chance? Happy to make changes if anything needs work. Thanks!

@smoltafet

Copy link
Copy Markdown
Author

closing this one, no traction. thanks anyway

@smoltafet smoltafet closed this Oct 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for multiple, and CIDR based trusted_proxy source

1 participant