Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ require (
github.com/aquasecurity/table v1.10.0
github.com/aquasecurity/testdocker v0.0.0-20240730042311-4642e94c7fc8
github.com/aquasecurity/tml v0.6.1
github.com/aquasecurity/trivy-checks v1.11.2-0.20250529074512-7afea1b738c4
github.com/aquasecurity/trivy-checks v1.11.3-0.20250604022615-9a7efa7c9169
github.com/aquasecurity/trivy-db v0.0.0-20250529093513-a12dfc204b6e
github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48
github.com/aquasecurity/trivy-kubernetes v0.9.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -800,8 +800,8 @@ github.com/aquasecurity/testdocker v0.0.0-20240730042311-4642e94c7fc8 h1:b43UVqY
github.com/aquasecurity/testdocker v0.0.0-20240730042311-4642e94c7fc8/go.mod h1:wXA9k3uuaxY3yu7gxrxZDPo/04FEMJtwyecdAlYrEIo=
github.com/aquasecurity/tml v0.6.1 h1:y2ZlGSfrhnn7t4ZJ/0rotuH+v5Jgv6BDDO5jB6A9gwo=
github.com/aquasecurity/tml v0.6.1/go.mod h1:OnYMWY5lvI9ejU7yH9LCberWaaTBW7hBFsITiIMY2yY=
github.com/aquasecurity/trivy-checks v1.11.2-0.20250529074512-7afea1b738c4 h1:Njp9YEU+4vqmtcb21lWfivrbiLsdYreohmWQX3+KHiU=
github.com/aquasecurity/trivy-checks v1.11.2-0.20250529074512-7afea1b738c4/go.mod h1:nT69xgRcBD4NlHwTBpWMYirpK5/Zpl8M+XDOgmjMn2k=
github.com/aquasecurity/trivy-checks v1.11.3-0.20250604022615-9a7efa7c9169 h1:TckzIxUX7lZaU9f2lNxCN0noYYP8fzmSQf6a4JdV83w=
github.com/aquasecurity/trivy-checks v1.11.3-0.20250604022615-9a7efa7c9169/go.mod h1:nT69xgRcBD4NlHwTBpWMYirpK5/Zpl8M+XDOgmjMn2k=
github.com/aquasecurity/trivy-db v0.0.0-20250529093513-a12dfc204b6e h1:+B/in1DQDGwQbKhW5pWL8XxBgnZKxXhUznylJ2NCyvs=
github.com/aquasecurity/trivy-db v0.0.0-20250529093513-a12dfc204b6e/go.mod h1:4zd4qZcjhNAHASz5I0O7qapv5h5gSJzSEaZXv/IPOGc=
github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48 h1:JVgBIuIYbwG+ekC5lUHUpGJboPYiCcxiz06RCtz8neI=
Expand Down
13 changes: 13 additions & 0 deletions pkg/fanal/analyzer/imgconf/dockerfile/dockerfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"context"
"fmt"
"regexp"
"strings"

v1 "github.com/google/go-containerregistry/pkg/v1"
Expand Down Expand Up @@ -87,6 +88,9 @@ func imageConfigToDockerfile(cfg *v1.ConfigFile) []byte {
case strings.HasPrefix(h.CreatedBy, "/bin/sh -c #(nop)"):
// Instruction other than RUN
createdBy = strings.TrimPrefix(h.CreatedBy, "/bin/sh -c #(nop)")
if strings.HasPrefix(createdBy, " COPY") || strings.HasPrefix(createdBy, " ADD") {
createdBy = normalizeCopyCreatedBy(createdBy)
}
case strings.HasPrefix(h.CreatedBy, "/bin/sh -c"):
// RUN instruction
createdBy = buildRunInstruction(createdBy)
Expand All @@ -112,6 +116,9 @@ func imageConfigToDockerfile(cfg *v1.ConfigFile) []byte {
}
}
}
// Remove Buildah-specific suffix (currently only `|inherit Labels=false`)
// cf. https://github.com/containers/buildah/blob/5a02e74b5d0f01e4d68ea0dcdbf5f5f444baa68f/imagebuildah/stage_executor.go#L1885
createdBy = strings.TrimSuffix(createdBy, "|inheritLabels=false")
dockerfile.WriteString(strings.TrimSpace(createdBy) + "\n")
}

Expand Down Expand Up @@ -150,6 +157,12 @@ func buildHealthcheckInstruction(health *v1.HealthConfig) string {
return fmt.Sprintf("HEALTHCHECK %s%s%s%s%s", interval, timeout, startPeriod, retries, command)
}

var copyInRe = regexp.MustCompile(`\b((?:file|dir):\S+) in `)

func normalizeCopyCreatedBy(input string) string {
return copyInRe.ReplaceAllString(input, `$1 `)
}

func (a *historyAnalyzer) Required(_ types.OS) bool {
return true
}
Expand Down
28 changes: 24 additions & 4 deletions pkg/fanal/analyzer/imgconf/dockerfile/dockerfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func Test_historyAnalyzer_Analyze(t *testing.T) {
},
History: []v1.History{
{
CreatedBy: "/bin/sh -c #(nop) ADD file:e4d600fc4c9c293efe360be7b30ee96579925d1b4634c94332e2ec73f7d8eca1 /",
CreatedBy: "/bin/sh -c #(nop) ADD foo.txt /",
EmptyLayer: false,
},
{
Expand All @@ -99,7 +99,7 @@ func Test_historyAnalyzer_Analyze(t *testing.T) {
types.MisconfResult{
Namespace: "builtin.dockerfile.DS005",
Query: "data.builtin.dockerfile.DS005.deny",
Message: "Consider using 'COPY file:e4d600fc4c9c293efe360be7b30ee96579925d1b4634c94332e2ec73f7d8eca1 /' command instead of 'ADD file:e4d600fc4c9c293efe360be7b30ee96579925d1b4634c94332e2ec73f7d8eca1 /'",
Message: "Consider using 'COPY foo.txt /' command instead of 'ADD foo.txt /'",
PolicyMetadata: types.PolicyMetadata{
ID: "DS005",
AVDID: "AVD-DS-0005",
Expand All @@ -119,10 +119,10 @@ func Test_historyAnalyzer_Analyze(t *testing.T) {
Lines: []types.Line{
{
Number: 1,
Content: "ADD file:e4d600fc4c9c293efe360be7b30ee96579925d1b4634c94332e2ec73f7d8eca1 /",
Content: "ADD foo.txt /",
IsCause: true,
Truncated: false,
Highlighted: "\x1b[38;5;64mADD\x1b[0m file:e4d600fc4c9c293efe360be7b30ee96579925d1b4634c94332e2ec73f7d8eca1 /",
Highlighted: "\x1b[38;5;64mADD\x1b[0m foo.txt /",
FirstCause: true,
LastCause: true,
},
Expand Down Expand Up @@ -428,6 +428,26 @@ func Test_ImageConfigToDockerfile(t *testing.T) {
expected: `ARG TAG=latest
ENV TAG=latest
ENTRYPOINT ["/bin/sh" "-c" "echo test"]
`,
},
{
name: "buildah backend or docker legacy builder (DOCKER_BUILDKIT=0)",
input: &v1.ConfigFile{
History: []v1.History{
{
CreatedBy: "/bin/sh -c #(nop) COPY dir:3a024d8085bc39741a0a094a8e287a00a760975c7c2e6b5dc6c7d3174b7d1ab6 in ./files |inheritLabels=false",
},
{
CreatedBy: "/bin/sh -c #(nop) ADD file:24d346633efc860b5011cefa5c0af73006e74e5dfb3c5c0e9cb0e90a927931e1 in readme |inheritLabels=false",
},
{
CreatedBy: `/bin/sh -c #(nop) ENTRYPOINT ["/bin/sh"]|inheritLabels=false`,
},
},
},
expected: `COPY dir:3a024d8085bc39741a0a094a8e287a00a760975c7c2e6b5dc6c7d3174b7d1ab6 ./files
ADD file:24d346633efc860b5011cefa5c0af73006e74e5dfb3c5c0e9cb0e90a927931e1 readme
ENTRYPOINT ["/bin/sh"]
`,
},
}
Expand Down