Skip to content

fix(container): correct image parsing with registry port#1186

Open
suzutan wants to merge 2 commits intofalcosecurity:mainfrom
suzutan:fix-container-port-parsing
Open

fix(container): correct image parsing with registry port#1186
suzutan wants to merge 2 commits intofalcosecurity:mainfrom
suzutan:fix-container-port-parsing

Conversation

@suzutan
Copy link

@suzutan suzutan commented Jan 30, 2026

What type of PR is this?

Uncomment one (or more) /kind <> lines:

/kind bug

/kind cleanup

/kind design

/kind documentation

/kind failing-test

/kind feature

Any specific area of the project related to this PR?

Uncomment one (or more) /area <> lines:

/area plugins

/area registry

/area build

/area documentation

What this PR does / why we need it:

Fixes container image parsing when the registry URL contains a port number.

Previously, the code used strings.Split(image, ":") which incorrectly split on ALL colons, making it unable to distinguish between registry ports and image tags. For example:

  • registry.example.com:5000/foo/bar:latest would fail parsing (3 parts, fails len==2 check)
  • registry.example.com:5000/foo/bar would incorrectly parse registry.example.com as repo and 5000/foo/bar as tag

This PR introduces a new parseImageRepoTag function that correctly parses image references by:

  • Only splitting on the last colon that appears after the last slash
  • Properly handling registry URLs with ports
  • Maintaining backward compatibility with simple image references

The fix has been applied to all container runtime engines: Docker, Podman, containerd, and CRI.

Which issue(s) this PR fixes:

Fixes #1139

Special notes for your reviewer:

  • This is the same bug as inconsistent splitting of container image information #825, which was auto-closed by the stale bot without being fixed
  • Added comprehensive unit tests covering various image reference formats including:
    • Registry with port and tag
    • Registry with port without tag
    • Multi-level paths with registry ports
    • Digest-based images
  • The parsing logic now correctly handles all edge cases mentioned in the issue

@poiana
Copy link
Contributor

poiana commented Jan 30, 2026

Welcome @suzutan! It looks like this is your first PR to falcosecurity/plugins 🎉

@poiana
Copy link
Contributor

poiana commented Jan 30, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: suzutan
Once this PR has been reviewed and has the lgtm label, please assign deepskyblue86 for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found 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

Container image name/tag parsing failed when the registry URL included
a port number (e.g., registry.example.com:5000/foo/bar:latest).

The previous implementation used strings.Split(image, ":") which split
on all colons, unable to distinguish between registry port (:5000) and
image tag (:latest).

Changes:
- Add parseImageRepoTag() helper function in engine.go that only splits
  on the last colon appearing after the last slash
- Update all engine implementations (docker, podman, containerd, cri) to
  use the new parser
- Add comprehensive test cases covering various image formats including
  registry with port, multi-level paths, and digest-based images

Fixes: falcosecurity#1139
Signed-off-by: suzutan <6679870+suzutan@users.noreply.github.com>
Copy link
Contributor

@irozzo-1A irozzo-1A left a comment

Choose a reason for hiding this comment

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

LGTM overall, just a nit

@github-actions
Copy link

github-actions bot commented Feb 3, 2026

Rules files suggestions

…arsing

Improve parseImageRepoTag to properly handle digest-based image references
by stripping the digest portion and returning an empty tag, preventing the
digest from being incorrectly parsed as a tag.

Signed-off-by: suzutan <6679870+suzutan@users.noreply.github.com>
@github-actions
Copy link

github-actions bot commented Feb 5, 2026

Rules files suggestions

Copy link
Contributor

@irozzo-1A irozzo-1A left a comment

Choose a reason for hiding this comment

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

Some minor changes and it's ready to go. Thanks!

expectedRepo: "registry.example.com:5000/foo/bar",
expectedTag: "",
},
"Multi-level path with registry port and tag": {
Copy link
Contributor

Choose a reason for hiding this comment

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

https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pulling-manifests

refers to the namespace of the repository. MUST be either (a) the digest of the manifest or (b) a tag. The MUST NOT be in any other format. Throughout this document, MUST match the following regular expression:

[a-z0-9]+((.||__|-+)[a-z0-9]+)*(/[a-z0-9]+((.||__|-+)[a-z0-9]+))

I think you can have both digest and tag, from my tests with docker at least. The OCI spec says or, but I think it's an inclusive or. I would add a test to cover this scenario e.g.

Suggested change
"Multi-level path with registry port and tag": {
"Both tag and digest": {
image: "registry.example.com:5000/foo/bar:latest@sha256:abc123",
expectedRepo: "registry.example.com:5000/foo/bar",
expectedTag: "latest",
},

Comment on lines +220 to +223
// Split at the last colon
if digestRef {
return image[:lastColon], ""
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Why don't we return the tag in case we have both tag and digest?

Suggested change
// Split at the last colon
if digestRef {
return image[:lastColon], ""
}

if at := strings.Index(image, "@"); at != -1 {
image = image[:at]
digestRef = true
}
Copy link
Contributor

Choose a reason for hiding this comment

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

See my previous comment:

Suggested change
}
if at := strings.Index(image, "@"); at != -1 {
image = image[:at]
}

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(container): image/tag parsing fails for registries with port numbers

3 participants