Skip to content

Conversation

@ricardomaraschini
Copy link
Contributor

@ricardomaraschini ricardomaraschini commented Jan 6, 2026

This PR adds validation to block image imports from localhost, link-local addresses (169.254.0.0/16), and cluster service/pod CIDR ranges. The implementation fetches service and pod CIDRs from the cluster Network configuration, performs DNS resolution to validate hostnames, and fails closed if the network config is unavailable.

@openshift-ci openshift-ci bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jan 6, 2026
@coderabbitai
Copy link

coderabbitai bot commented Jan 6, 2026

Walkthrough

Adds DNS-resolution helpers and IP-prefix checks to image import validation and request transport: resolves registry hosts, blocks loopback/link-local and cluster/service/pod CIDRs, validates ImageStreamImport targets pre-contact, and enforces restrictions via a RestrictedTransport used during imports.

Changes

Cohort / File(s) Summary
Validation core
pkg/image/apis/image/validation/validation.go
Adds IPLookup/DefaultIPLookup, shouldContactRegistry, ShouldContactHost, and ValidateImageStreamImportDisallowedHosts to resolve hosts, filter loopback/link-local, and check extra netip.Prefix CIDRs; returns field.Forbidden for disallowed targets.
Validation tests
pkg/image/apis/image/validation/validation_test.go
Adds Test_shouldContactRegistry and TestValidateImageStreamImportDisallowedHosts with stubbed DNS lookups to exercise loopback/link-local, multi-IP resolution, CIDR blocking, and error assertions.
REST integration
pkg/image/apiserver/registry/imagestreamimport/rest.go
NewREST signature updated to accept configclientv1.ConfigV1Interface, wires a NetworksGetter (netCfgV1Client), adds getForbiddenCIDRs to extract cluster/service/pod CIDRs, validates ImageStreamImport against forbidden prefixes, and uses restricted transports for import operations.
REST tests
pkg/image/apiserver/registry/imagestreamimport/rest_test.go
Adds fake network client types and Test_getForbiddenCIDRs to validate extraction of forbidden CIDR prefixes and error handling.
Transport implementation
pkg/image/apiserver/registry/imagestreamimport/transport.go
New exported RestrictedTransport and NewRestrictedTransport wrap an http.RoundTripper, use a package IP lookup (overrideable for tests), and call validation.ShouldContactHost to block requests to forbidden IP ranges (handles redirects).
Transport tests
pkg/image/apiserver/registry/imagestreamimport/transport_test.go
New comprehensive TestRestrictedTransport with mocked roundtrippers and IP lookups covering DNS resolution, redirect chains, blocked/allowed destinations, and transport/DNS error propagation.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 78a758d and 0298033.

📒 Files selected for processing (5)
  • pkg/image/apis/image/validation/validation.go
  • pkg/image/apis/image/validation/validation_test.go
  • pkg/image/apiserver/registry/imagestreamimport/rest.go
  • pkg/image/apiserver/registry/imagestreamimport/transport.go
  • pkg/image/apiserver/registry/imagestreamimport/transport_test.go
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.

Files:

  • pkg/image/apiserver/registry/imagestreamimport/transport.go
  • pkg/image/apiserver/registry/imagestreamimport/rest.go
  • pkg/image/apis/image/validation/validation_test.go
  • pkg/image/apis/image/validation/validation.go
  • pkg/image/apiserver/registry/imagestreamimport/transport_test.go
🧬 Code graph analysis (4)
pkg/image/apiserver/registry/imagestreamimport/transport.go (1)
pkg/image/apis/image/validation/validation.go (3)
  • IPLookup (790-790)
  • DefaultIPLookup (794-794)
  • ShouldContactHost (818-859)
pkg/image/apiserver/registry/imagestreamimport/rest.go (3)
pkg/image/apis/image/validation/validation.go (1)
  • ValidateImageStreamImportDisallowedHosts (864-898)
pkg/image/apiserver/registry/imagestreamimport/transport.go (1)
  • NewRestrictedTransport (46-51)
pkg/image/apiserver/importer/staticcredentials.go (1)
  • NewStaticCredentialsContext (27-37)
pkg/image/apis/image/validation/validation.go (1)
pkg/image/apis/image/types.go (2)
  • DockerImageReference (518-518)
  • ImageStreamImport (574-584)
pkg/image/apiserver/registry/imagestreamimport/transport_test.go (2)
pkg/image/apis/image/validation/validation.go (1)
  • IPLookup (790-790)
pkg/image/apiserver/registry/imagestreamimport/transport.go (1)
  • NewRestrictedTransport (46-51)
🔇 Additional comments (11)
pkg/image/apis/image/validation/validation.go (3)

788-813: LGTM on the DNS lookup abstraction and registry contact check.

The IPLookup type and DefaultIPLookup variable provide good testability. The shouldContactRegistry function correctly handles the empty registry case (default registry) and properly extracts the host portion, ignoring the port for validation purposes.


815-859: Solid implementation with fail-closed security posture.

The function correctly:

  • Handles both IP literals and hostnames requiring DNS resolution
  • Blocks if any resolved IP is in a forbidden range (secure approach)
  • Uses Unmap() to correctly handle IPv4-mapped IPv6 addresses like ::ffff:127.0.0.1
  • Fails closed on DNS resolution errors

861-898: Well-structured validation with appropriate error handling.

The function correctly validates both repository and individual image imports, uses proper field paths for error reporting, and appropriately skips non-DockerImage kinds. The debug logging at V(4) provides good observability.

pkg/image/apis/image/validation/validation_test.go (2)

2058-2237: Comprehensive test coverage for shouldContactRegistry.

The test cases effectively cover:

  • Loopback addresses (IPv4, IPv6, IPv4-mapped IPv6)
  • Link-local addresses including metadata endpoint
  • Custom CIDR blocking with various configurations
  • DNS resolution scenarios with single and multiple IPs
  • Empty registry (allowed by default)

The use of a deferred restore for DefaultIPLookup ensures test isolation.


2239-2459: Good integration tests for ValidateImageStreamImportDisallowedHosts.

The tests cover the key scenarios including repository imports, image imports, mixed scenarios, non-DockerImage kinds (correctly ignored), and custom CIDR blocking. The error message verification approach is appropriate for this validation function.

pkg/image/apiserver/registry/imagestreamimport/transport.go (1)

1-51: Effective defense-in-depth at the transport layer.

This provides critical runtime protection against:

  • Redirects to blocked destinations (the validation layer only checks initial URLs)
  • DNS rebinding attacks where a hostname resolves to different IPs over time

The implementation is clean with appropriate nil checks and proper delegation to ShouldContactHost.

pkg/image/apiserver/registry/imagestreamimport/transport_test.go (2)

265-362: Excellent redirect security tests.

The redirect tests are crucial for validating the defense-in-depth strategy. They verify that:

  • Redirects from public to loopback are blocked
  • Redirects to service CIDRs are blocked
  • Multi-hop redirect chains terminating in blocked destinations are caught
  • Safe redirect chains are allowed

This ensures the transport-level protection catches SSRF attempts via redirects.


65-400: Well-structured transport tests with appropriate mocking.

The test setup correctly:

  • Uses http.Client which follows redirects, ensuring each redirect hop goes through RestrictedTransport.RoundTrip
  • Provides mock DNS resolution for controlled testing
  • Handles both success and error scenarios
pkg/image/apiserver/registry/imagestreamimport/rest.go (3)

201-230: Robust CIDR retrieval with appropriate error handling.

The getForbiddenCIDRs method correctly:

  • Fetches both service and pod network CIDRs
  • Fails closed if the network configuration is unavailable
  • Parses CIDRs with proper error handling

This ensures the security check cannot be bypassed due to configuration issues.


349-381: Well-integrated security controls in the Create flow.

The implementation provides layered security:

  1. Pre-flight validation (line 356) blocks obviously malicious requests early
  2. Runtime transport protection (lines 378-381) catches redirect-based attacks and DNS rebinding

The restricted transports are correctly applied to both secure and insecure transports, and importantly, the retry path (line 402) also uses the restricted transports.


87-104: Constructor refactoring is correct and fully updated.

The change from separate imageCfgV1Client parameter to a unified configV1Client (ConfigV1Interface) is properly implemented. The caller at pkg/image/apiserver/apiserver.go:271 correctly passes configV1Client.ConfigV1(), which provides the required interface. Both imageCfgV1Client and netCfgV1Client fields are now initialized from this single client, reducing parameter count while maintaining full functionality.


Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci openshift-ci bot requested review from QiWang19 and benluddy January 6, 2026 16:58
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jan 6, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: ricardomaraschini

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jan 6, 2026
@ricardomaraschini
Copy link
Contributor Author

/retest

@ricardomaraschini ricardomaraschini force-pushed the block-image-import-by-ips branch from a325b3c to dd7a0d8 Compare January 8, 2026 15:49
before accepting an image stream import object we need to validate it
does not point to the cluster itself (pod or service cidr) as well as
validate it does not try to reach localhost or link-local addresses.

this commit adds a validation to the api that resolves the registry
address and if it lands in one of these places a "forbidden" error is
returned to the client.
@ricardomaraschini ricardomaraschini force-pushed the block-image-import-by-ips branch from dd7a0d8 to 96d4e39 Compare January 8, 2026 15:56
@ricardomaraschini ricardomaraschini changed the title [WIP]: blocking image import from unauthorized network addresses OCPBUGS-72408: block image import from cluster IP addresses Jan 8, 2026
@openshift-ci-robot openshift-ci-robot added jira/severity-important Referenced Jira bug's severity is important for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. labels Jan 8, 2026
@openshift-ci-robot
Copy link

@ricardomaraschini: This pull request references Jira Issue OCPBUGS-72408, which is valid. The bug has been moved to the POST state.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (4.22.0) matches configured target version for branch (4.22.0)
  • bug is in the state New, which is one of the valid states (NEW, ASSIGNED, POST)

Requesting review from QA contact:
/cc @xiuwang

The bug has been updated to refer to the pull request using the external bug tracker.

Details

In response to this:

This PR adds validation to block image imports from localhost, link-local addresses (169.254.0.0/16), and cluster service/pod CIDR ranges. The implementation fetches service and pod CIDRs from the cluster Network configuration, performs DNS resolution to validate hostnames, and fails closed if the network config is unavailable.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot openshift-ci-robot added the jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. label Jan 8, 2026
@openshift-ci openshift-ci bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jan 8, 2026
@openshift-ci openshift-ci bot requested a review from xiuwang January 8, 2026 15:56
@ricardomaraschini
Copy link
Contributor Author

/assign @flavianmissi

@ricardomaraschini
Copy link
Contributor Author

@coderabbitai help

@coderabbitai
Copy link

coderabbitai bot commented Jan 8, 2026

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

CodeRabbit commands

These commands are invoked using PR/Issue comments.

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai evaluate custom pre-merge check --instructions <custom-checks-instructions> --name <custom-checks-title> [--mode <error|warning>] to validate the custom pre-merge checks instructions. Defaults to error when --mode is omitted.
    • @coderabbitai ignore pre-merge checks to override pre-merge checks and get an approval on PR.
    • @coderabbitai run pre-merge checks to run pre-merge checks on the pull request.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve to resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai generate configuration to create a PR that adds the current resolved configuration as .coderabbit.yaml (or show it if already present).
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit configuration file (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, support, documentation and community

  • Visit our status page to check the current availability of CodeRabbit.
  • Create a ticket on our support page for assistance with any issues or questions.
  • Visit our documentation site for detailed information on how to use CodeRabbit.
  • Join our Discord community to connect with other users and get help from the community.
  • Follow us on X/Twitter for updates and announcements.

@ricardomaraschini
Copy link
Contributor Author

@coderabbitai full review

@coderabbitai
Copy link

coderabbitai bot commented Jan 8, 2026

✅ Actions performed

Full review triggered.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
pkg/image/apis/image/validation/validation.go (1)

814-814: Fix typo in comment.

Line 814 has a typo: "otherwhise" should be "otherwise".

📝 Proposed fix
-	// either we have a name or an IP address here. if we manage to parse
-	// it as an IP then use it as so otherwhise we need to do a dns lookup.
+	// either we have a name or an IP address here. if we manage to parse
+	// it as an IP then use it as so otherwise we need to do a dns lookup.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 64dea07 and 96d4e39.

📒 Files selected for processing (4)
  • pkg/image/apis/image/validation/validation.go
  • pkg/image/apis/image/validation/validation_test.go
  • pkg/image/apiserver/registry/imagestreamimport/rest.go
  • pkg/image/apiserver/registry/imagestreamimport/rest_test.go
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.

Files:

  • pkg/image/apis/image/validation/validation.go
  • pkg/image/apiserver/registry/imagestreamimport/rest.go
  • pkg/image/apis/image/validation/validation_test.go
  • pkg/image/apiserver/registry/imagestreamimport/rest_test.go
🧬 Code graph analysis (4)
pkg/image/apis/image/validation/validation.go (1)
pkg/image/apis/image/types.go (2)
  • DockerImageReference (518-518)
  • ImageStreamImport (574-584)
pkg/image/apiserver/registry/imagestreamimport/rest.go (1)
pkg/image/apis/image/validation/validation.go (1)
  • ValidateImageStreamImportDisallowedHosts (858-892)
pkg/image/apis/image/validation/validation_test.go (2)
pkg/image/apis/image/types.go (5)
  • DockerImageReference (518-518)
  • ImageStreamImport (574-584)
  • ImageStreamImportSpec (587-596)
  • RepositoryImportSpec (609-616)
  • ImageImportSpec (630-637)
pkg/image/apis/image/validation/validation.go (1)
  • ValidateImageStreamImportDisallowedHosts (858-892)
pkg/image/apiserver/registry/imagestreamimport/rest_test.go (1)
pkg/image/apiserver/registry/imagestreamimport/rest.go (1)
  • REST (52-67)
🔇 Additional comments (7)
pkg/image/apiserver/registry/imagestreamimport/rest_test.go (2)

601-660: LGTM! Well-designed test fakes.

The fake implementations provide a focused test double for the Network config client. The approach of returning "not implemented" for unused methods while fully implementing only the Get method is appropriate for these unit tests.


661-802: LGTM! Comprehensive test coverage.

The test cases cover the essential scenarios for CIDR extraction:

  • Valid IPv4 and IPv6 service and pod CIDRs
  • Partial configurations (only service or only cluster CIDRs)
  • Empty configurations
  • Error handling when network config is unavailable
  • Invalid CIDR parsing
pkg/image/apis/image/validation/validation.go (1)

855-892: LGTM! Solid validation implementation.

The function correctly validates both repository and per-image imports, leveraging the shouldContactRegistry helper to enforce security policies. The error messages clearly indicate which imports are blocked and why.

pkg/image/apiserver/registry/imagestreamimport/rest.go (2)

201-230: LGTM! Secure fail-closed implementation.

The method correctly retrieves both service and pod CIDRs from the cluster Network configuration. The fail-closed behavior (returning an error when the Network config is unavailable) is the right security posture, as it prevents imports when the system can't determine which addresses should be blocked.


349-358: LGTM! Proper security validation integration.

The validation is correctly placed in the request flow after authorization checks but before the actual import operation. The fail-closed behavior ensures that imports are rejected if the security policy cannot be determined, which is the correct security posture.

pkg/image/apis/image/validation/validation_test.go (2)

2058-2232: LGTM! Excellent test coverage.

The test suite comprehensively validates the registry security checks:

  • Loopback addresses (IPv4, IPv6, IPv4-mapped IPv6)
  • Link-local addresses (including metadata endpoint)
  • Custom CIDR blocks
  • DNS resolution scenarios
  • Multiple IPs from a single hostname

The custom resolver ensures deterministic test behavior while exercising the DNS resolution code path.


2234-2454: LGTM! Thorough validation testing.

The tests comprehensively cover the ImageStreamImport validation scenarios:

  • Repository vs. individual image imports
  • Multiple images with mixed valid/invalid registries
  • Custom CIDR restrictions
  • Non-DockerImage kinds (correctly ignored)
  • IP addresses with and without ports
  • Both repository and image blocked simultaneously

The temporary override of defaultIPLookup with proper cleanup is a good testing pattern.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/image/apiserver/registry/imagestreamimport/rest.go (1)

349-409: Critical: auth-fallback retry bypasses restricted transports

The retry path (401 fallback) builds importCtx with r.transport / r.insecureTransport (unrestricted), so a request that passes initial validation can still reach blocked IP ranges during the retry, defeating the “transport-level” enforcement.

Proposed fix
 	transport := NewRestrictedTransport(r.transport, blockedCIDRs)
 	itransport := NewRestrictedTransport(r.insecureTransport, blockedCIDRs)
@@
 	if importFailed {
 		importCtx := importer.NewStaticCredentialsContext(
-			r.transport, r.insecureTransport, nil,
+			transport, itransport, nil,
 		)
 		imports := r.importFn(importCtx, v2regConf)
 		if err := imports.Import(ctx, isi, stream); err != nil {
 			return nil, kapierrors.NewInternalError(err)
 		}
 	}
🤖 Fix all issues with AI agents
In @pkg/image/apiserver/registry/imagestreamimport/transport.go:
- Around line 14-41: RoundTrip must guard against nil inputs to avoid panics: at
the start of RestrictedTransport.RoundTrip check for nil req and nil req.URL and
return a descriptive error (instead of panicking), and ensure r and r.wrapped
are non-nil before calling r.wrapped.RoundTrip (either return an error or fall
back to http.DefaultTransport); also update NewRestrictedTransport to
document/handle a nil wrapped (e.g., set wrapped to http.DefaultTransport when
nil) so RestrictedTransport.wrapped is never nil.
🧹 Nitpick comments (3)
pkg/image/apiserver/registry/imagestreamimport/transport_test.go (1)

16-44: Make mockRoundTripper responses more HTTP-client compatible (set Response.Request)

For configured responses (especially redirects), setting resp.Request = req makes the mock closer to real transports and reduces brittleness if the stdlib behavior changes.

Proposed tweak
 func (m *mockRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
@@
 		resp := m.responses[m.callCount]
 		m.callCount++
+		if resp.Request == nil {
+			resp.Request = req
+		}
+		if resp.Body == nil {
+			resp.Body = http.NoBody
+		}
 		return resp, nil
 	}

Also applies to: 65-68, 365-399

pkg/image/apis/image/validation/validation_test.go (1)

2058-2459: Global DefaultIPLookup overrides are not parallel-safe; consider t.Cleanup and order-insensitive assertions

If any future tests in this package call t.Parallel(), these global overrides can race. Also, TestValidateImageStreamImportDisallowedHosts currently assumes a stable error order.

pkg/image/apis/image/validation/validation.go (1)

818-858: Optional: include resolved IP/host in “not allowed” error to aid debugging

Right now the extra-CIDR block returns import from <cidr> not allowed; including the resolved IP (and/or host) would make support cases easier without changing behavior.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 96d4e39 and d487af1.

📒 Files selected for processing (5)
  • pkg/image/apis/image/validation/validation.go
  • pkg/image/apis/image/validation/validation_test.go
  • pkg/image/apiserver/registry/imagestreamimport/rest.go
  • pkg/image/apiserver/registry/imagestreamimport/transport.go
  • pkg/image/apiserver/registry/imagestreamimport/transport_test.go
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.

Files:

  • pkg/image/apiserver/registry/imagestreamimport/rest.go
  • pkg/image/apis/image/validation/validation.go
  • pkg/image/apis/image/validation/validation_test.go
  • pkg/image/apiserver/registry/imagestreamimport/transport_test.go
  • pkg/image/apiserver/registry/imagestreamimport/transport.go
🧬 Code graph analysis (2)
pkg/image/apis/image/validation/validation.go (1)
pkg/image/apis/image/types.go (2)
  • DockerImageReference (518-518)
  • ImageStreamImport (574-584)
pkg/image/apiserver/registry/imagestreamimport/transport_test.go (2)
pkg/image/apis/image/validation/validation.go (1)
  • IPLookup (790-790)
pkg/image/apiserver/registry/imagestreamimport/transport.go (1)
  • NewRestrictedTransport (36-41)
🔇 Additional comments (2)
pkg/image/apis/image/validation/validation.go (1)

788-898: Core disallowed-host validation + fail-closed DNS behavior looks correct

The split between (1) validating registry hosts and (2) enforcing again at transport level aligns well with the TOCTOU risk described in the PR.

pkg/image/apiserver/registry/imagestreamimport/rest.go (1)

78-105: Signature change is properly wired through call sites

The sole call site at ./pkg/image/apiserver/apiserver.go:271 has been updated to pass all 13 parameters including the new configV1Client parameter (passed as configV1Client.ConfigV1()). The parameter ordering matches the new function signature.

@ricardomaraschini ricardomaraschini force-pushed the block-image-import-by-ips branch from d487af1 to 78a758d Compare January 9, 2026 16:22
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
pkg/image/apiserver/registry/imagestreamimport/transport_test.go (1)

16-43: LGTM! Consider enhancing the error message for better debugging.

The mock implementation is correct and follows standard testing patterns. The logic properly handles configured responses, errors, and default cases.

💡 Optional: Make the error message more informative

Consider including the call count in the error message to help with debugging:

     if len(m.responses) > 0 {
         if m.callCount >= len(m.responses) {
-            return nil, errors.New("mock: unexpected call to RoundTrip")
+            return nil, fmt.Errorf("mock: unexpected call to RoundTrip (call %d, but only %d responses configured)", m.callCount+1, len(m.responses))
         }
         resp := m.responses[m.callCount]
         m.callCount++
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between d487af1 and 78a758d.

📒 Files selected for processing (5)
  • pkg/image/apis/image/validation/validation.go
  • pkg/image/apis/image/validation/validation_test.go
  • pkg/image/apiserver/registry/imagestreamimport/rest.go
  • pkg/image/apiserver/registry/imagestreamimport/transport.go
  • pkg/image/apiserver/registry/imagestreamimport/transport_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/image/apiserver/registry/imagestreamimport/transport.go
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.

Files:

  • pkg/image/apiserver/registry/imagestreamimport/transport_test.go
  • pkg/image/apis/image/validation/validation_test.go
  • pkg/image/apis/image/validation/validation.go
  • pkg/image/apiserver/registry/imagestreamimport/rest.go
🧬 Code graph analysis (3)
pkg/image/apiserver/registry/imagestreamimport/transport_test.go (2)
pkg/image/apis/image/validation/validation.go (1)
  • IPLookup (790-790)
pkg/image/apiserver/registry/imagestreamimport/transport.go (1)
  • NewRestrictedTransport (46-51)
pkg/image/apis/image/validation/validation_test.go (2)
pkg/image/apis/image/validation/validation.go (1)
  • ValidateImageStreamImportDisallowedHosts (864-898)
pkg/image/apis/image/types.go (5)
  • DockerImageReference (518-518)
  • ImageStreamImport (574-584)
  • ImageStreamImportSpec (587-596)
  • RepositoryImportSpec (609-616)
  • ImageImportSpec (630-637)
pkg/image/apis/image/validation/validation.go (1)
pkg/image/apis/image/types.go (2)
  • DockerImageReference (518-518)
  • ImageStreamImport (574-584)
🔇 Additional comments (16)
pkg/image/apiserver/registry/imagestreamimport/transport_test.go (3)

45-63: LGTM!

The mock DNS resolver implementation is clean and appropriate for testing. It properly validates test data and returns meaningful errors for unknown hosts.


65-81: LGTM!

Good test setup with proper cleanup of global state. The use of defer to restore the original defaultIPLookup ensures test isolation.


82-400: Excellent test coverage!

The test cases are comprehensive and cover a wide range of scenarios including:

  • Loopback addresses (IPv4, IPv6, IPv4-mapped)
  • Link-local addresses
  • Custom CIDR blocking
  • Multiple IP resolution
  • DNS errors
  • Redirect chains
  • Error propagation

The test structure is clean and maintainable with good use of table-driven testing.

pkg/image/apis/image/validation/validation_test.go (3)

7-7: LGTM!

The new imports are necessary and appropriate for the added functionality:

  • net/netip for CIDR prefix handling
  • imageref for parsing Docker image references

Also applies to: 19-19


2058-2237: LGTM!

The test function is well-structured with:

  • Proper cleanup of global state via defer
  • Comprehensive mock DNS setup with different hostnames
  • Good coverage of edge cases (loopback, link-local, CIDRs)
  • Clear test case naming and organization
  • Appropriate error message validation

The test effectively validates the shouldContactRegistry function's behavior across various scenarios.


2239-2459: LGTM!

The test provides comprehensive coverage of ValidateImageStreamImportDisallowedHosts:

  • Both repository and image imports are tested
  • Multiple images with mixed safe/unsafe hosts
  • Custom CIDR restrictions
  • Non-DockerImage kinds (correctly ignored)
  • IP addresses with and without ports

The error validation properly checks both the error count and message content, ensuring the validation function works correctly.

pkg/image/apiserver/registry/imagestreamimport/rest.go (5)

7-7: LGTM!

The addition of net/netip import and netCfgV1Client field are necessary for the new CIDR-based blocking functionality.

Also applies to: 66-66


349-359: LGTM! Excellent fail-closed security posture.

The code correctly retrieves blocked CIDRs and validates the import request before proceeding. The fail-closed behavior (returning an error if network configuration cannot be retrieved) is the right security choice, preventing imports when the system cannot determine what should be blocked.


378-382: LGTM!

The restricted transports are correctly created and used for both secure and insecure connections. This ensures that all image import HTTP requests respect the CIDR blocking rules.


201-230: The review comment suggests adding error handling when both ServiceNetwork and ClusterNetwork are empty. However, the existing test suite includes an explicit test case titled "empty network config" that expects this scenario to succeed without error, returning an empty prefix list. This behavior is intentional and correct—empty network configurations are valid in OpenShift clusters. The suggestion to return an error when both slices are empty would contradict the tested and designed behavior.

Likely an incorrect or invalid review comment.


87-87: No action needed. The NewREST function signature already uses configV1Client configclientv1.ConfigV1Interface (line 87), and the single caller in pkg/image/apiserver/apiserver.go (line 284) correctly passes configV1Client.ConfigV1(). Both imageCfgV1Client and netCfgV1Client fields are properly initialized from the same parameter. The design is sound and all callers are updated.

Likely an incorrect or invalid review comment.

pkg/image/apis/image/validation/validation.go (5)

6-6: LGTM!

The new imports are necessary for the added validation functionality:

  • errors for error creation
  • net/netip for IP prefix/CIDR handling

Also applies to: 9-9


788-794: LGTM!

Excellent design pattern for testability. The IPLookup type and DefaultIPLookup variable allow tests to inject mock DNS resolvers while production code uses the real resolver.


796-813: LGTM!

The function correctly handles registry validation:

  • Allows empty registry (uses default)
  • Properly extracts host from "host:port" format
  • Falls back to the whole string if no port is present
  • Delegates to ShouldContactHost for the actual validation

815-859: LGTM! Robust IP validation with proper IPv4-mapped IPv6 handling.

The function correctly:

  • Parses direct IP addresses or resolves hostnames via DNS
  • Blocks loopback addresses
  • Blocks link-local addresses
  • Checks against custom CIDR blocks
  • Unmaps IPv4-mapped IPv6 addresses (line 850) before CIDR checks, which is crucial for correct comparison

The error messages are clear and indicate the reason for blocking.


861-898: LGTM!

The validation function is well-implemented:

  • Validates both repository and individual image imports
  • Only processes DockerImage kinds (correctly ignoring ImageStreamTag, etc.)
  • Provides clear error messages indicating which import was blocked and why
  • Uses appropriate field error types (Forbidden for blocked imports)
  • Logs blocked imports at debug level for troubleshooting

The function integrates cleanly with the Kubernetes validation framework.

more than blocking image stream import creations when they point to ips
we know shouldn't be contacted we also need to block at the registry
client level. this adds an extra layer of security on the unlikely case
the dns entries change between the api validation and the actual import.
@ricardomaraschini ricardomaraschini force-pushed the block-image-import-by-ips branch from 78a758d to 0298033 Compare January 9, 2026 17:18
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jan 9, 2026

@ricardomaraschini: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-aws-ovn 0298033 link true /test e2e-aws-ovn

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/severity-important Referenced Jira bug's severity is important for the branch this PR is targeting. jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants