From 2e648d9488aacb17060e3298ed05c6ed8c96c71d Mon Sep 17 00:00:00 2001 From: Wout Feys Date: Fri, 30 Aug 2024 10:06:50 +0200 Subject: [PATCH] Remove the contains_private_ip function --- .../ssrf/contains_private_ip_address.py | 25 --- .../ssrf/contains_private_ip_address_test.py | 182 ------------------ .../ssrf/is_redirect_to_private_ip.py | 3 +- .../ssrf/is_redirect_to_private_ip_test.py | 26 +-- 4 files changed, 5 insertions(+), 231 deletions(-) delete mode 100644 aikido_firewall/vulnerabilities/ssrf/contains_private_ip_address.py delete mode 100644 aikido_firewall/vulnerabilities/ssrf/contains_private_ip_address_test.py diff --git a/aikido_firewall/vulnerabilities/ssrf/contains_private_ip_address.py b/aikido_firewall/vulnerabilities/ssrf/contains_private_ip_address.py deleted file mode 100644 index a62caf01..00000000 --- a/aikido_firewall/vulnerabilities/ssrf/contains_private_ip_address.py +++ /dev/null @@ -1,25 +0,0 @@ -"""exports contains_private_ip_address""" - -from aikido_firewall.helpers.try_parse_url import try_parse_url -from .is_private_ip import is_private_ip - - -def contains_private_ip_address(hostname): - """ - Checks if the hostname contains an IP that's private - """ - if hostname == "localhost": - return True - - # Attempt to parse the URL - url = try_parse_url(f"http://{hostname}") - if url is None: - return False - - # Check for IPv6 addresses enclosed in square brackets - if url.hostname.startswith("[") and url.hostname.endswith("]"): - ipv6 = url.hostname[1:-1] # Extract the IPv6 address - if is_private_ip(ipv6): - return True - - return is_private_ip(url.hostname) diff --git a/aikido_firewall/vulnerabilities/ssrf/contains_private_ip_address_test.py b/aikido_firewall/vulnerabilities/ssrf/contains_private_ip_address_test.py deleted file mode 100644 index ca4fb197..00000000 --- a/aikido_firewall/vulnerabilities/ssrf/contains_private_ip_address_test.py +++ /dev/null @@ -1,182 +0,0 @@ -import pytest -from .contains_private_ip_address import contains_private_ip_address - - -public_ips = [ - "44.37.112.180", - "46.192.247.73", - "71.12.102.112", - "101.0.26.90", - "111.211.73.40", - "156.238.194.84", - "164.101.185.82", - "223.231.138.242", - "::1fff:0.0.0.0", - "::1fff:10.0.0.0", - "::1fff:0:0.0.0.0", - "::1fff:0:10.0.0.0", - "2001:2:ffff:ffff:ffff:ffff:ffff:ffff", - "64:ff9a::0.0.0.0", - "64:ff9a::255.255.255.255", - "99::", - "99::ffff:ffff:ffff:ffff", - "101::", - "101::ffff:ffff:ffff:ffff", - "2000::", - "2000::ffff:ffff:ffff:ffff:ffff:ffff", - "2001:10::", - "2001:1f:ffff:ffff:ffff:ffff:ffff:ffff", - "2001:db7::", - "2001:db7:ffff:ffff:ffff:ffff:ffff:ffff", - "2001:db9::", - "fb00::", - "fbff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", - "fec0::", -] - -private_ips = [ - "0.0.0.0", - "0000.0000.0000.0000", - "0.0.0.1", - "0.0.0.7", - "0.0.0.255", - "0.0.255.255", - "0.1.255.255", - "0.15.255.255", - "0.63.255.255", - "0.255.255.254", - "0.255.255.255", - "10.0.0.0", - "10.0.0.1", - "10.0.0.01", - "10.0.0.001", - "10.255.255.254", - "10.255.255.255", - "100.64.0.0", - "100.64.0.1", - "100.127.255.254", - "100.127.255.255", - "127.0.0.0", - "127.0.0.1", - "127.0.0.01", - "127.000.000.1", - "127.255.255.254", - "127.255.255.255", - "169.254.0.0", - "169.254.0.1", - "169.254.255.254", - "169.254.255.255", - "172.16.0.0", - "172.16.0.1", - "172.16.0.001", - "172.31.255.254", - "172.31.255.255", - "192.0.0.0", - "192.0.0.1", - "192.0.0.6", - "192.0.0.7", - "192.0.0.8", - "192.0.0.9", - "192.0.0.10", - "192.0.0.11", - "192.0.0.170", - "192.0.0.171", - "192.0.0.254", - "192.0.0.255", - "192.0.2.0", - "192.0.2.1", - "192.0.2.254", - "192.0.2.255", - "192.31.196.0", - "192.31.196.1", - "192.31.196.254", - "192.31.196.255", - "192.52.193.0", - "192.52.193.1", - "192.52.193.254", - "192.52.193.255", - "192.88.99.0", - "192.88.99.1", - "192.88.99.254", - "192.88.99.255", - "192.168.0.0", - "192.168.0.1", - "192.168.255.254", - "192.168.255.255", - "192.175.48.0", - "192.175.48.1", - "192.175.48.254", - "192.175.48.255", - "198.18.0.0", - "198.18.0.1", - "198.19.255.254", - "198.19.255.255", - "198.51.100.0", - "198.51.100.1", - "198.51.100.254", - "198.51.100.255", - "203.0.113.0", - "203.0.113.1", - "203.0.113.254", - "203.0.113.255", - "240.0.0.0", - "240.0.0.1", - "224.0.0.0", - "224.0.0.1", - "255.0.0.0", - "255.192.0.0", - "255.240.0.0", - "255.254.0.0", - "255.255.0.0", - "255.255.255.0", - "255.255.255.248", - "255.255.255.254", - "255.255.255.255", - "0000:0000:0000:0000:0000:0000:0000:0000", - "::", - "::1", - "::ffff:0.0.0.0", - "::ffff:127.0.0.1", - "fe80::", - "fe80::1", - "fe80::abc:1", - "febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff", - "fc00::", - "fc00::1", - "fc00::abc:1", - "fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", - "fd00:ec2::254", - "169.254.169.254", -] - -invalid_ips = [ - "100::ffff::", - "::ffff:0.0.255.255.255", - "::ffff:0.255.255.255.255", - "0000.0000", - "127.1", - "127.0.1", - "2130706433", - "0x7f000001", -] - - -def test_public_ips(): - for ip in public_ips: - if ":" in ip: - ip = f"[{ip}]" # IPv6 are enclosed in brackets - assert not contains_private_ip_address(ip), f"Expected {ip} to be public" - - -def test_private_ips(): - for ip in private_ips: - if ":" in ip: - ip = f"[{ip}]" # IPv6 are enclosed in brackets - assert contains_private_ip_address(ip), f"Expected {ip} to be private" - - -def test_invalid_ips(): - for ip in invalid_ips: - if ":" in ip: - ip = f"[{ip}]" # IPv6 are enclosed in brackets - assert not contains_private_ip_address(ip), f"Expected {ip} to be invalid" diff --git a/aikido_firewall/vulnerabilities/ssrf/is_redirect_to_private_ip.py b/aikido_firewall/vulnerabilities/ssrf/is_redirect_to_private_ip.py index 5246426a..3124f47e 100644 --- a/aikido_firewall/vulnerabilities/ssrf/is_redirect_to_private_ip.py +++ b/aikido_firewall/vulnerabilities/ssrf/is_redirect_to_private_ip.py @@ -1,7 +1,6 @@ """Exports is_redirect_to_private_ip""" from aikido_firewall.helpers.get_port_from_url import get_port_from_url -from .contains_private_ip_address import contains_private_ip_address from .get_redirect_origin import get_redirect_origin from .find_hostname_in_context import find_hostname_in_context @@ -18,7 +17,7 @@ def is_redirect_to_private_ip(hostname, context, port): - The redirect origin, so the user-supplied hostname and port that caused the first redirect, is found in the context of the incoming request """ - if context.outgoing_req_redirects and contains_private_ip_address(hostname): + if context.outgoing_req_redirects: redirect_origin = get_redirect_origin( context.outgoing_req_redirects, hostname, port ) diff --git a/aikido_firewall/vulnerabilities/ssrf/is_redirect_to_private_ip_test.py b/aikido_firewall/vulnerabilities/ssrf/is_redirect_to_private_ip_test.py index 4b930baf..936b00e0 100644 --- a/aikido_firewall/vulnerabilities/ssrf/is_redirect_to_private_ip_test.py +++ b/aikido_firewall/vulnerabilities/ssrf/is_redirect_to_private_ip_test.py @@ -45,16 +45,8 @@ def test_is_redirect_to_private_ip_not_private_ip(): }, ] - with MagicMock() as mock_contains_private_ip_address: - mock_contains_private_ip_address.return_value = False - with pytest.MonkeyPatch.context() as mp: - mp.setattr( - "aikido_firewall.vulnerabilities.ssrf.contains_private_ip_address", - mock_contains_private_ip_address, - ) - - result = is_redirect_to_private_ip("example.com", context, 443) - assert result is None + result = is_redirect_to_private_ip("example.com", context, 443) + assert result is None def test_is_redirect_to_private_ip_redirect_origin_not_found(): @@ -66,16 +58,11 @@ def test_is_redirect_to_private_ip_redirect_origin_not_found(): }, ] - with MagicMock() as mock_contains_private_ip_address, MagicMock() as mock_get_redirect_origin: + with MagicMock() as mock_get_redirect_origin: - mock_contains_private_ip_address.return_value = True mock_get_redirect_origin.return_value = None with pytest.MonkeyPatch.context() as mp: - mp.setattr( - "aikido_firewall.vulnerabilities.ssrf.contains_private_ip_address", - mock_contains_private_ip_address, - ) mp.setattr( "aikido_firewall.vulnerabilities.ssrf.get_redirect_origin", mock_get_redirect_origin, @@ -94,19 +81,14 @@ def test_is_redirect_to_private_ip_hostname_not_found_in_context(): }, ] - with MagicMock() as mock_contains_private_ip_address, MagicMock() as mock_get_redirect_origin, MagicMock() as mock_find_hostname_in_context: + with MagicMock() as mock_get_redirect_origin, MagicMock() as mock_find_hostname_in_context: - mock_contains_private_ip_address.return_value = True mock_get_redirect_origin.return_value = MagicMock( hostname="example.com", port=80 ) mock_find_hostname_in_context.return_value = False with pytest.MonkeyPatch.context() as mp: - mp.setattr( - "aikido_firewall.vulnerabilities.ssrf.contains_private_ip_address", - mock_contains_private_ip_address, - ) mp.setattr( "aikido_firewall.vulnerabilities.ssrf.get_redirect_origin", mock_get_redirect_origin,