-
Notifications
You must be signed in to change notification settings - Fork 98
Description
Describe the bug
Container image parsing is broken when the registry URL has a port number. The code splits on ALL colons with strings.Split(image, ":"), so it can't tell the difference between a registry port and an image tag.
This is the same bug as #825, which got auto-closed by the stale bot without being fixed.
How to reproduce it
-
Run a container with an image from a registry that has a port:
docker run registry.example.com:5000/foo/bar:latest
-
Check Falco output for
container.image.repositoryandcontainer.image.tagfields -
The values will be incorrect:
- For
registry.example.com:5000/foo/bar:latest:- Splits into 3 parts, fails
len == 2check, leaves repo and tag empty
- Splits into 3 parts, fails
- For
registry.example.com:5000/foo/bar:container.image.repository = "registry.example.com"(wrong - missing port and path)container.image.tag = "5000/foo/bar"(wrong - port and path parsed as tag)
- For
Expected behaviour
For registry.example.com:5000/foo/bar:latest:
container.image.repository = "registry.example.com:5000/foo/bar"container.image.tag = "latest"
For registry.example.com:5000/foo/bar:
container.image.repository = "registry.example.com:5000/foo/bar"container.image.tag = ""or"latest"
Screenshots
N/A
Environment
- Falco version: 0.42.1(plugins/container 0.4.1)
- System info: Ubuntu 22.04.5 LTS / containerd://2.1.5
- Cloud provider or hardware configuration:
- OS: Ubuntu
- Kernel: 5.15.0-157-generic
- Installation method: kubernetes with Falco helm chart
Additional context
Affected code locations:
The bug exists in 4 files in the plugins repository:
plugins/container/go-worker/pkg/container/podman.go:109-112plugins/container/go-worker/pkg/container/containerd.go:150-153plugins/container/go-worker/pkg/container/cri.go:325-328plugins/container/go-worker/pkg/container/docker.go:203-213
All using the same broken pattern:
imageRepoTag := strings.Split(image, ":")
if len(imageRepoTag) == 2 {
imageRepo = imageRepoTag[0]
imageTag = imageRepoTag[1]
}Verified in latest code:
Static analysis confirms this bug still exists in the latest main branch of the plugins repository (as of 2025-12-18, commit 419e315).
Impact:
This breaks for anyone using:
- Private registries with ports (
registry.company.com:5000/...) - Corporate registry setups
- Digest-based images
Wrong image/tag data can break security policies, audit logs, and allowlists.
Proposed fix:
Split on the LAST colon, not all colons:
func splitImageAndTag(image string) (repo, tag string) {
// Strip digest if present
if idx := strings.Index(image, "@"); idx > 0 {
image = image[:idx]
}
lastSlash := strings.LastIndex(image, "/")
colonIdx := strings.LastIndex(image, ":")
// Colon after last slash = tag separator
if colonIdx > 0 && colonIdx > lastSlash {
return image[:colonIdx], image[colonIdx+1:]
}
return image, ""
}Or use an existing image reference parser like github.com/distribution/reference.
Test cases that should pass:
registry.example.com:5000/foo/bar:latest→ repo:registry.example.com:5000/foo/bar, tag:latestregistry.example.com:5000/foo/bar→ repo:registry.example.com:5000/foo/bar, tag:""docker.io/library/alpine:3.20.3→ repo:docker.io/library/alpine, tag:3.20.3alpine:3.20.3→ repo:alpine, tag:3.20.3alpine→ repo:alpine, tag:""