fix(iac): validate repository URL before the scan clone

This commit is contained in:
pedrooot committed 2026-10-07 15:53:41 +02:00
1 parent 7411679442
commit fe6b24f0ba
4 files changed
+39 -1

No files matched your search

@@ -1 +1 @@
IaC connection test rejects repository URLs resolving to loopback, private or link-local hosts and stops echoing raw errors to the caller
IaC repository URLs resolving to loopback, private or otherwise non-public hosts rejected before both the connection test and the scan clone, with raw errors no longer echoed to the caller
+3
View File
@@ -330,6 +330,9 @@ class IacProvider(Provider):
Returns:
tuple[str, str]: (temporary_directory, branch_name)
"""
validate_outbound_url(
repository_url, allowed_schemes=("http", "https", "ssh", "git")
)
try:
original_url = repository_url
View File
Whitespace-only changes.
+35
View File
@@ -7,6 +7,7 @@ from unittest.mock import MagicMock, patch
import pytest
from prowler.lib.check.models import CheckReportIAC
from prowler.lib.network.ssrf import OutboundURLNotAllowedError
from prowler.providers.iac.exceptions.exceptions import (
IacRepositoryCloneError,
IacScanError,
@@ -903,6 +904,40 @@ class TestIacProvider:
assert connection.error == "Repository URL is not an allowed destination."
mock_ls_remote.assert_not_called()
def test_clone_repository_rejects_a_non_public_url(self):
provider = IacProvider.__new__(IacProvider)
with patch("prowler.providers.iac.iac_provider.porcelain.clone") as mock_clone:
with pytest.raises(OutboundURLNotAllowedError):
provider._clone_repository("https://169.254.169.254/org/repo.git")
mock_clone.assert_not_called()
def test_clone_repository_rejects_shared_address_space(self):
provider = IacProvider.__new__(IacProvider)
with patch("prowler.providers.iac.iac_provider.porcelain.clone") as mock_clone:
with pytest.raises(OutboundURLNotAllowedError):
provider._clone_repository("https://100.100.100.200/org/repo.git")
mock_clone.assert_not_called()
def test_clone_repository_does_not_validate_the_token_bearing_url(self):
provider = IacProvider.__new__(IacProvider)
with patch(
"prowler.lib.network.ssrf.socket.getaddrinfo",
return_value=[(None, None, None, None, ("140.82.121.4", 0))],
) as mock_getaddrinfo:
with patch("prowler.providers.iac.iac_provider.porcelain.clone"):
with patch.object(
IacProvider, "_detect_branch_name", return_value="main"
):
provider._clone_repository(
"https://github.com/org/repo.git",
github_username="user",
personal_access_token="token",
)
assert mock_getaddrinfo.call_args[0][0] == "github.com"
def test_test_connection_allows_public_url(self):
with (
patch(