From 7828008ff9a0326300c61c3802bb6826e8d31481 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 7 Dec 2023 09:13:56 -0500 Subject: [PATCH] Employ urlparse() to strip port numbers from IPs --- netbox/utilities/request.py | 19 +++++++++++-------- netbox/utilities/tests/test_request.py | 5 ++++- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/netbox/utilities/request.py b/netbox/utilities/request.py index 63ba788f8..a5ca145e9 100644 --- a/netbox/utilities/request.py +++ b/netbox/utilities/request.py @@ -1,4 +1,5 @@ from netaddr import AddrFormatError, IPAddress +from urllib.parse import urlparse __all__ = ( 'get_client_ip', @@ -18,15 +19,17 @@ def get_client_ip(request, additional_headers=()): for header in HTTP_HEADERS: if header in request.META: ip = request.META[header].split(',')[0].strip() - # Check if the IP address is v6 or v4 - if ip.count(':') > 1: - client_ip = ip - else: - client_ip = ip.partition(':')[0] try: - return IPAddress(client_ip) - except (AddrFormatError, ValueError): - raise ValueError(f"Invalid IP address set for {header}: {client_ip}") + return IPAddress(ip) + except AddrFormatError: + # Parse the string with urlparse() to remove port number or any other cruft + ip = urlparse(f'//{ip}').hostname + + try: + return IPAddress(ip) + except AddrFormatError: + # We did our best + raise ValueError(f"Invalid IP address set for {header}: {ip}") # Could not determine the client IP address from request headers return None diff --git a/netbox/utilities/tests/test_request.py b/netbox/utilities/tests/test_request.py index 37b1e77f5..69f677323 100644 --- a/netbox/utilities/tests/test_request.py +++ b/netbox/utilities/tests/test_request.py @@ -11,13 +11,16 @@ class GetClientIPTests(TestCase): def test_ipv4_address(self): request = self.factory.get('/', HTTP_X_FORWARDED_FOR='192.168.1.1') self.assertEqual(get_client_ip(request), IPAddress('192.168.1.1')) - request = self.factory.get('/', HTTP_X_FORWARDED_FOR='192.168.1.1:8080') self.assertEqual(get_client_ip(request), IPAddress('192.168.1.1')) def test_ipv6_address(self): request = self.factory.get('/', HTTP_X_FORWARDED_FOR='2001:db8::8a2e:370:7334') self.assertEqual(get_client_ip(request), IPAddress('2001:db8::8a2e:370:7334')) + request = self.factory.get('/', HTTP_X_FORWARDED_FOR='[2001:db8::8a2e:370:7334]') + self.assertEqual(get_client_ip(request), IPAddress('2001:db8::8a2e:370:7334')) + request = self.factory.get('/', HTTP_X_FORWARDED_FOR='[2001:db8::8a2e:370:7334]:8080') + self.assertEqual(get_client_ip(request), IPAddress('2001:db8::8a2e:370:7334')) def test_invalid_ip_address(self): request = self.factory.get('/', HTTP_X_FORWARDED_FOR='invalid_ip')