From e4d2bd83edef2fb750355a27069a36cd78762e02 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Tue, 26 May 2026 16:56:55 +0200 Subject: [PATCH] SSRF protection: Block requests to CGNAT addresses (Z#23235334) --- src/pretix/helpers/monkeypatching.py | 4 ++++ src/tests/helpers/test_urllib.py | 8 ++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/pretix/helpers/monkeypatching.py b/src/pretix/helpers/monkeypatching.py index 6b3509f64a..1eb46fb5f1 100644 --- a/src/pretix/helpers/monkeypatching.py +++ b/src/pretix/helpers/monkeypatching.py @@ -40,6 +40,8 @@ from urllib3.util.connection import ( ) from urllib3.util.timeout import _DEFAULT_TIMEOUT +_cgnat_net = ipaddress.ip_network('100.64.0.0/10') + def monkeypatch_vobject_performance(): """ @@ -152,6 +154,8 @@ def monkeypatch_urllib3_ssrf_protection(): 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: + raise HTTPError(f"Request to RFC 6598 address {sa[0]} blocked") sock = None try: diff --git a/src/tests/helpers/test_urllib.py b/src/tests/helpers/test_urllib.py index d4342bbe26..b50c129163 100644 --- a/src/tests/helpers/test_urllib.py +++ b/src/tests/helpers/test_urllib.py @@ -41,6 +41,8 @@ def test_private_ip_blocked(): requests.get("http://10.0.0.1", timeout=0.1) with pytest.raises(HTTPError, match="Request to private address.*"): 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) @pytest.mark.django_db @@ -50,6 +52,8 @@ def test_private_ip_blocked(): [(AF_INET, SOCK_STREAM, 6, '', ('127.1.1.1', 443))], [(AF_INET, SOCK_STREAM, 6, '', ('192.168.5.3', 443))], [(AF_INET, SOCK_STREAM, 6, '', ('224.0.0.1', 443))], + [(AF_INET, SOCK_STREAM, 6, '', ('100.64.0.1', 443))], + [(AF_INET, SOCK_STREAM, 6, '', ('100.100.100.100', 443))], [(AF_INET6, SOCK_STREAM, 6, '', ('::1', 443, 0, 0))], [(AF_INET6, SOCK_STREAM, 6, '', ('fe80::1', 443, 0, 0))], [(AF_INET6, SOCK_STREAM, 6, '', ('ff00::1', 443, 0, 0))], @@ -58,9 +62,9 @@ def test_private_ip_blocked(): def test_dns_resolving_to_local_blocked(res): with mock.patch('socket.getaddrinfo') as mock_addr: mock_addr.return_value = res - with pytest.raises(HTTPError, match="Request to (multicast|private|local) address.*"): + with pytest.raises(HTTPError, match="Request to (multicast|private|local|RFC 6598) address.*"): requests.get("https://example.org", timeout=0.1) - with pytest.raises(HTTPError, match="Request to (multicast|private|local) address.*"): + with pytest.raises(HTTPError, match="Request to (multicast|private|local|RFC 6598) address.*"): requests.get("http://example.org", timeout=0.1)