fix(image): keep origin enforcement when skipping

This commit is contained in:
pedrooot committed 2026-10-07 17:45:29 +02:00
1 parent 23999ef7d9
commit 9e7b53db9f
2 files changed
+48 -25

No files matched your search

+26 -25
View File
@@ -246,37 +246,38 @@ class RegistryAdapter(ABC):
message=f"URL has no host: {canonical_url}",
)
if _outbound_check_skipped():
return canonical_url
try:
ipaddress.ip_address(host)
except ValueError:
# Only the address classification is skipped. The origin rule below still
# applies: a registry-supplied URL pointing at an unrelated host is a
# different problem from deliberately reaching a private network.
if not _outbound_check_skipped():
try:
infos = socket.getaddrinfo(host, None)
except socket.gaierror:
infos = []
for *_, sockaddr in infos:
resolved_ip = sockaddr[0]
if _ip_is_non_public(resolved_ip) and not self._ip_is_allowed(
resolved_ip
):
ipaddress.ip_address(host)
except ValueError:
try:
infos = socket.getaddrinfo(host, None)
except socket.gaierror:
infos = []
for *_, sockaddr in infos:
resolved_ip = sockaddr[0]
if _ip_is_non_public(resolved_ip) and not self._ip_is_allowed(
resolved_ip
):
raise ImageRegistryAuthError(
file=__file__,
message=(
f"Host {host!r} resolves to non-public address "
f"{resolved_ip}. {_ALLOWLIST_HINT}"
),
)
else:
if _ip_is_non_public(host) and not self._ip_is_allowed(host):
raise ImageRegistryAuthError(
file=__file__,
message=(
f"Host {host!r} resolves to non-public address "
f"{resolved_ip}. {_ALLOWLIST_HINT}"
f"URL targets a non-public address: {host}. "
f"{_ALLOWLIST_HINT}"
),
)
else:
if _ip_is_non_public(host) and not self._ip_is_allowed(host):
raise ImageRegistryAuthError(
file=__file__,
message=(
f"URL targets a non-public address: {host}. "
f"{_ALLOWLIST_HINT}"
),
)
if enforce_origin:
registry_host = urlparse(origin_url or self._origin_url()).hostname or ""
@@ -610,6 +610,28 @@ class TestOutboundCheckOptOut:
mock_request.assert_not_called()
@patch("prowler.providers.image.lib.registry.base.requests.request")
def test_the_origin_rule_still_applies_when_skipped(
self, mock_request, monkeypatch
):
"""Skipping the address check must not let a registry redirect us elsewhere."""
monkeypatch.setenv("PROWLER_SKIP_OUTBOUND_HOST_CHECK", "true")
adapter = OciRegistryAdapter(registry_url="https://registry.example.com")
with pytest.raises(ImageRegistryAuthError, match="unrelated to registry host"):
adapter._validate_outbound_url("https://attacker.example.net/token")
mock_request.assert_not_called()
@patch("prowler.providers.image.lib.registry.base.requests.request")
def test_a_same_origin_url_is_allowed_when_skipped(self, mock_request, monkeypatch):
monkeypatch.setenv("PROWLER_SKIP_OUTBOUND_HOST_CHECK", "true")
adapter = OciRegistryAdapter(registry_url="https://registry.example.com")
assert adapter._validate_outbound_url(
"https://registry.example.com/v2/token"
).startswith("https://registry.example.com/")
@patch("prowler.providers.image.lib.registry.base.requests.request")
def test_the_scheme_check_still_applies_when_skipped(
self, mock_request, monkeypatch