ipaddress can classify a parsed address against a CIDR network; the harder question is which peer address to trust.
Python ipaddress membership: parse the peer before an allowlist
Operation contract
An internal webhook accepts traffic from one documented IPv4 range. ip_address parses the address and membership checks the network. This program proves that pure predicate. It does not prove where peer_text came from. A header supplied by the requester is not a peer identity unless a trusted proxy rewrites it and the application trusts that proxy. Outbound target rules protect a different network direction.
Failure and ownership boundary
IPv4 and IPv6 are different families. Malformed text raises ValueError and must not fall through to allow. If the service sits behind several proxies, define exactly which hop supplies the canonical peer, strip untrusted forwarding headers at the edge, and test that path. A private or reserved range is not automatically authorized.
Working program
from ipaddress import ip_address, ip_network
allowed = ip_network("192.0.2.0/24")
for peer_text in ("192.0.2.47", "203.0.113.7", "invalid"):
try:
accepted = ip_address(peer_text) in allowed
except ValueError:
accepted = False
print(peer_text, accepted)Output
192.0.2.47 True
203.0.113.7 False
invalid FalseCosts and limits
A membership test is cheap for one network. A large policy list needs an indexed or precomputed structure, while trusted-peer extraction remains a separate boundary.
Common Mistakes
- Do not trust an arbitrary forwarded header as the peer address.
- A private or reserved address is not permission by itself.
- Malformed addresses must not fall back to allow.
Connected lessons
Python urlsplit: parsing a URL does not authorize a request target, Flask routing: application factories, converters and test clients, Python JSON validation: reject duplicate members and non-integer amounts.
