diff --git a/prowler/changelog.d/openstack-auth-url-ssrf.security.md b/prowler/changelog.d/openstack-auth-url-ssrf.security.md index cd9907f43c..f50f7e0ec2 100644 --- a/prowler/changelog.d/openstack-auth-url-ssrf.security.md +++ b/prowler/changelog.d/openstack-auth-url-ssrf.security.md @@ -1 +1 @@ -OpenStack connection test rejects an `auth_url` with a non-HTTP scheme or a host that resolves to a loopback, link-local or private address, so a tenant-supplied clouds.yaml can no longer make the worker probe internal services +OpenStack auth_url resolving to loopback, private or otherwise non-public hosts rejected before the SDK connects, on both the connection test and the scan diff --git a/prowler/providers/openstack/openstack_provider.py b/prowler/providers/openstack/openstack_provider.py index e9aeb18362..0b9edbf57c 100644 --- a/prowler/providers/openstack/openstack_provider.py +++ b/prowler/providers/openstack/openstack_provider.py @@ -482,6 +482,7 @@ class OpenstackProvider(Provider): region: Optional region override — when given, the connection is scoped to this specific region instead of the session default. """ + OpenstackProvider._validate_auth_url(session.auth_url) try: # Don't load from clouds.yaml or environment variables, we configure this in setup_session() conn = connect( @@ -628,8 +629,6 @@ class OpenstackProvider(Provider): project_domain_name=project_domain_name, ) - OpenstackProvider._validate_auth_url(session.auth_url) - # Validate provider_id matches project_id from config if provider_id and session.project_id != provider_id: raise OpenStackInvalidProviderIdError( diff --git a/tests/lib/network/__init__.py b/tests/lib/network/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/providers/openstack/openstack_provider_test.py b/tests/providers/openstack/openstack_provider_test.py index 3b3a348890..b61c9ca2e6 100644 --- a/tests/providers/openstack/openstack_provider_test.py +++ b/tests/providers/openstack/openstack_provider_test.py @@ -1727,6 +1727,36 @@ clouds: raise_on_exception=True, ) + def test_scan_initialisation_rejects_a_non_public_auth_url(self): + with patch( + "prowler.providers.openstack.openstack_provider.connect" + ) as mock_connect: + with pytest.raises(OpenStackAuthUrlNotAllowedError): + OpenstackProvider( + auth_url="https://169.254.169.254:5000/v3", + username="test-user", + password="test-password", + project_id="test-project-id", + region_name="RegionOne", + ) + + mock_connect.assert_not_called() + + def test_scan_initialisation_rejects_shared_address_space(self): + with patch( + "prowler.providers.openstack.openstack_provider.connect" + ) as mock_connect: + with pytest.raises(OpenStackAuthUrlNotAllowedError): + OpenstackProvider( + auth_url="https://100.100.100.200:5000/v3", + username="test-user", + password="test-password", + project_id="test-project-id", + region_name="RegionOne", + ) + + mock_connect.assert_not_called() + def test_test_connection_allows_public_auth_url(self): result, mock_connect = self._test_connection( auth_url="https://openstack.example.com:5000/v3"