From 62f35f0c105887b02abb0780c8578afbbf505878 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Tue, 9 Jun 2026 11:16:30 +0200 Subject: [PATCH] SSRF protection: Edge case handling for CGNAT and v4/v6 mapping (Z#23236468) --- src/pretix/helpers/monkeypatching.py | 3 ++- src/tests/helpers/test_urllib.py | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pretix/helpers/monkeypatching.py b/src/pretix/helpers/monkeypatching.py index 1eb46fb5f1..6d63fbf634 100644 --- a/src/pretix/helpers/monkeypatching.py +++ b/src/pretix/helpers/monkeypatching.py @@ -148,13 +148,14 @@ def monkeypatch_urllib3_ssrf_protection(): if not getattr(settings, "ALLOW_HTTP_TO_PRIVATE_NETWORKS", False): ip_addr = ipaddress.ip_address(sa[0]) + check_ip4 = ip_addr.ipv4_mapped if getattr(ip_addr, "ipv4_mapped", None) else ip_addr if ip_addr.is_multicast: raise HTTPError(f"Request to multicast address {sa[0]} blocked") if ip_addr.is_loopback or ip_addr.is_link_local: raise HTTPError(f"Request to local address {sa[0]} blocked") if ip_addr.is_private: raise HTTPError(f"Request to private address {sa[0]} blocked") - if ip_addr in _cgnat_net: + if check_ip4 in _cgnat_net: raise HTTPError(f"Request to RFC 6598 address {sa[0]} blocked") sock = None diff --git a/src/tests/helpers/test_urllib.py b/src/tests/helpers/test_urllib.py index b50c129163..37841c591c 100644 --- a/src/tests/helpers/test_urllib.py +++ b/src/tests/helpers/test_urllib.py @@ -43,6 +43,8 @@ def test_private_ip_blocked(): requests.get("https://10.0.0.1", timeout=0.1) with pytest.raises(HTTPError, match="Request to RFC 6598 address.*"): requests.get("https://100.100.100.100", timeout=0.1) + with pytest.raises(HTTPError, match="Request to RFC 6598 address.*"): + requests.get("https://[::ffff:100.64.0.1]", timeout=0.1) @pytest.mark.django_db @@ -58,6 +60,7 @@ def test_private_ip_blocked(): [(AF_INET6, SOCK_STREAM, 6, '', ('fe80::1', 443, 0, 0))], [(AF_INET6, SOCK_STREAM, 6, '', ('ff00::1', 443, 0, 0))], [(AF_INET6, SOCK_STREAM, 6, '', ('fc00::1', 443, 0, 0))], + [(AF_INET6, SOCK_STREAM, 6, "", ("::ffff:100.64.0.1", 443, 0, 0))], ]) def test_dns_resolving_to_local_blocked(res): with mock.patch('socket.getaddrinfo') as mock_addr: