Skip to content

Fix panic when reconstructing Dockerfile from malformed image history#191

Merged
kcq merged 1 commit into
mintoolkit:masterfrom
0xVijay:fix/reverse-history-panic
Jul 4, 2026
Merged

Fix panic when reconstructing Dockerfile from malformed image history#191
kcq merged 1 commit into
mintoolkit:masterfrom
0xVijay:fix/reverse-history-panic

Conversation

@0xVijay

@0xVijay 0xVijay commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

What

The code that rebuilds a Dockerfile from image history (reverse.go) indexes the result of strings.SplitN for HEALTHCHECK, ENTRYPOINT and CMD without checking the length. A malformed value in a layer's CreatedBy history makes it panic, for example:

HEALTHCHECK &{[                 -> index out of range [1] with length 1
HEALTHCHECK &{[CMD] 5s 10s 0s   -> index out of range [3] with length 3
ENTRYPOINT [   /   CMD [        -> slice bounds out of range [1:0]

There is no recover() around this, so one bad instruction aborts the whole xray, build or profile run.

Why

mint is often pointed at images it did not build (xray/build on pulled images, CI pipelines). A single image with malformed history metadata should not crash the tool. xray does not even run the target app, so the history alone is enough to trigger it.

How Tested

Added TestHealthCheckMalformed and TestDockerfileFromHistoryDataMalformed which feed the malformed values above and assert the parser returns an error instead of panicking. Existing TestHealthCheck still passes.

go test ./pkg/docker/dockerfile/reverse/
ok  github.com/mintoolkit/mint/pkg/docker/dockerfile/reverse

…tory

The HEALTHCHECK/ENTRYPOINT/CMD reverse-engineering code indexes the
results of strings.SplitN without checking their length, so a malformed
value in an image's layer history makes it panic. There is no recover()
around it, so a single bad instruction aborts the whole xray/build/profile
run.

Bounds-check the slice accesses in deserialiseHealtheckInstruction and
fixJSONArray, and return an error for malformed HEALTHCHECK values so the
caller skips the instruction instead of crashing.

Signed-off-by: 0xVijay <53905346+0xVijay@users.noreply.github.com>
@kcq

kcq commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

auggie review

@augmentcode

augmentcode Bot commented Jul 4, 2026

Copy link
Copy Markdown
🤖 Augment PR Summary

Summary: Prevents crashes when reconstructing a Dockerfile from images with malformed history entries.

Changes:

  • Hardened JSON-array reconstruction for CMD/ENTRYPOINT by guarding against short/empty strings.
  • Added defensive length checks in deserialiseHealtheckInstruction to avoid out-of-range panics when parsing malformed HEALTHCHECK encodings.
  • Adjusted retries parsing to avoid indexing into an empty retries value.
  • Added regression tests asserting malformed history strings do not panic during HEALTHCHECK parsing or full Dockerfile reconstruction.

Technical Notes: Malformed inputs now return errors instead of panicking, allowing callers to continue processing other history layers.

🤖 Was this summary useful? React with 👍 or 👎

@augmentcode augmentcode Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Review completed. 1 suggestion posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

//Splits the string into two parts - first part pointer to array of string and rest of the string with } in end.
instParts := strings.SplitN(cleanInst, "]", 2)
if len(instParts) < 2 {
return strTest, &config, fmt.Errorf("malformed HEALTHCHECK instruction: %q", data)

@augmentcode augmentcode Bot Jul 4, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

deserialiseHealtheckInstruction now returns an error here but still returns strTest (often empty) as the reconstructed instruction; upstream code currently assigns the returned string even when err != nil, which can silently drop the original HEALTHCHECK line and emit a blank/invalid Dockerfile line instead of “skipping”.

Severity: medium

Other Locations
  • pkg/docker/dockerfile/reverse/reverse.go:819

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

@kcq kcq merged commit 5a82a54 into mintoolkit:master Jul 4, 2026
@0xVijay 0xVijay deleted the fix/reverse-history-panic branch July 4, 2026 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants