VYPR
Medium severityNVD Advisory· Published Mar 17, 2025· Updated Apr 15, 2026

CVE-2025-0495

CVE-2025-0495

Description

Buildx is a Docker CLI plugin that extends build capabilities using BuildKit.

Cache backends support credentials by setting secrets directly as attribute values in cache-to/cache-from configuration. When supplied as user input, these secure values may be inadvertently captured in OpenTelemetry traces as part of the arguments and flags for the traced CLI command. OpenTelemetry traces are also saved in BuildKit daemon's history records.

This vulnerability does not impact secrets passed to the Github cache backend via environment variables or registry authentication.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/docker/buildxGo
< 0.21.30.21.3

Patches

1
18ccba072076

Merge pull request #3068 from crazy-max/GHSA-m4gq-fm9h-8q75

https://github.com/docker/buildxTõnis TiigiMar 17, 2025via ghsa
6 files changed · +105 33
  • commands/bake.go+17 15 modified
    @@ -66,7 +66,11 @@ type bakeOptions struct {
     func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in bakeOptions, cFlags commonFlags) (err error) {
     	mp := dockerCli.MeterProvider()
     
    -	ctx, end, err := tracing.TraceCurrentCommand(ctx, "bake")
    +	ctx, end, err := tracing.TraceCurrentCommand(ctx, append([]string{"bake"}, targets...),
    +		attribute.String("builder", in.builder),
    +		attribute.StringSlice("targets", targets),
    +		attribute.StringSlice("files", in.files),
    +	)
     	if err != nil {
     		return err
     	}
    @@ -283,7 +287,7 @@ func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in ba
     		}
     	}
     
    -	if err := saveLocalStateGroup(dockerCli, in, targets, bo, overrides, def); err != nil {
    +	if err := saveLocalStateGroup(dockerCli, in, targets, bo); err != nil {
     		return err
     	}
     
    @@ -488,7 +492,14 @@ func bakeCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
     	return cmd
     }
     
    -func saveLocalStateGroup(dockerCli command.Cli, in bakeOptions, targets []string, bo map[string]build.Options, overrides []string, def any) error {
    +func saveLocalStateGroup(dockerCli command.Cli, in bakeOptions, targets []string, bo map[string]build.Options) error {
    +	l, err := localstate.New(confutil.NewConfig(dockerCli))
    +	if err != nil {
    +		return err
    +	}
    +
    +	defer l.MigrateIfNeeded()
    +
     	prm := confutil.MetadataProvenance()
     	if len(in.metadataFile) == 0 {
     		prm = confutil.MetadataProvenanceModeDisabled
    @@ -508,19 +519,10 @@ func saveLocalStateGroup(dockerCli command.Cli, in bakeOptions, targets []string
     	if len(refs) == 0 {
     		return nil
     	}
    -	l, err := localstate.New(confutil.NewConfig(dockerCli))
    -	if err != nil {
    -		return err
    -	}
    -	dtdef, err := json.MarshalIndent(def, "", "  ")
    -	if err != nil {
    -		return err
    -	}
    +
     	return l.SaveGroup(groupRef, localstate.StateGroup{
    -		Definition: dtdef,
    -		Targets:    targets,
    -		Inputs:     overrides,
    -		Refs:       refs,
    +		Refs:    refs,
    +		Targets: targets,
     	})
     }
     
    
  • commands/build.go+5 1 modified
    @@ -286,7 +286,11 @@ func (o *buildOptionsHash) String() string {
     func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions) (err error) {
     	mp := dockerCli.MeterProvider()
     
    -	ctx, end, err := tracing.TraceCurrentCommand(ctx, "build")
    +	ctx, end, err := tracing.TraceCurrentCommand(ctx, []string{"build", options.contextPath},
    +		attribute.String("builder", options.builder),
    +		attribute.String("context", options.contextPath),
    +		attribute.String("dockerfile", options.dockerfileName),
    +	)
     	if err != nil {
     		return err
     	}
    
  • localstate/localstate.go+22 9 modified
    @@ -6,6 +6,7 @@ import (
     	"fmt"
     	"os"
     	"path/filepath"
    +	"strconv"
     	"sync"
     
     	"github.com/docker/buildx/util/confutil"
    @@ -14,6 +15,7 @@ import (
     )
     
     const (
    +	version  = 2
     	refsDir  = "refs"
     	groupDir = "__group__"
     )
    @@ -31,12 +33,8 @@ type State struct {
     }
     
     type StateGroup struct {
    -	// Definition is the raw representation of the group (bake definition)
    -	Definition []byte
     	// Targets are the targets invoked
     	Targets []string `json:",omitempty"`
    -	// Inputs are the user inputs (bake overrides)
    -	Inputs []string `json:",omitempty"`
     	// Refs are used to track all the refs that belong to the same group
     	Refs []string
     }
    @@ -52,9 +50,7 @@ func New(cfg *confutil.Config) (*LocalState, error) {
     	if err := cfg.MkdirAll(refsDir, 0700); err != nil {
     		return nil, err
     	}
    -	return &LocalState{
    -		cfg: cfg,
    -	}, nil
    +	return &LocalState{cfg: cfg}, nil
     }
     
     func (ls *LocalState) ReadRef(builderName, nodeName, id string) (*State, error) {
    @@ -87,8 +83,12 @@ func (ls *LocalState) SaveRef(builderName, nodeName, id string, st State) error
     	return ls.cfg.AtomicWriteFile(filepath.Join(refDir, id), dt, 0644)
     }
     
    +func (ls *LocalState) GroupDir() string {
    +	return filepath.Join(ls.cfg.Dir(), refsDir, groupDir)
    +}
    +
     func (ls *LocalState) ReadGroup(id string) (*StateGroup, error) {
    -	dt, err := os.ReadFile(filepath.Join(ls.cfg.Dir(), refsDir, groupDir, id))
    +	dt, err := os.ReadFile(filepath.Join(ls.GroupDir(), id))
     	if err != nil {
     		return nil, err
     	}
    @@ -208,7 +208,7 @@ func (ls *LocalState) removeGroup(id string) error {
     	if id == "" {
     		return errors.Errorf("group ref empty")
     	}
    -	f := filepath.Join(ls.cfg.Dir(), refsDir, groupDir, id)
    +	f := filepath.Join(ls.GroupDir(), id)
     	if _, err := os.Lstat(f); err != nil {
     		if !os.IsNotExist(err) {
     			return err
    @@ -230,3 +230,16 @@ func (ls *LocalState) validate(builderName, nodeName, id string) error {
     	}
     	return nil
     }
    +
    +func (ls *LocalState) readVersion() int {
    +	if vdt, err := os.ReadFile(filepath.Join(ls.cfg.Dir(), refsDir, "version")); err == nil {
    +		if v, err := strconv.Atoi(string(vdt)); err == nil {
    +			return v
    +		}
    +	}
    +	return 1
    +}
    +
    +func (ls *LocalState) writeVersion(version int) error {
    +	return ls.cfg.AtomicWriteFile(filepath.Join(refsDir, "version"), []byte(strconv.Itoa(version)), 0600)
    +}
    
  • localstate/localstate_test.go+2 4 modified
    @@ -68,10 +68,8 @@ var (
     
     	testStateGroupID = "kvqs0sgly2rmitz84r25u9qd0"
     	testStateGroup   = StateGroup{
    -		Definition: []byte(`{"group":{"default":{"targets":["pre-checkin"]},"pre-checkin":{"targets":["vendor-update","format","build"]}},"target":{"build":{"context":".","dockerfile":"dev.Dockerfile","target":"build-update","platforms":["linux/amd64"],"output":["."]},"format":{"context":".","dockerfile":"dev.Dockerfile","target":"format-update","platforms":["linux/amd64"],"output":["."]},"vendor-update":{"context":".","dockerfile":"dev.Dockerfile","target":"vendor-update","platforms":["linux/amd64"],"output":["."]}}}`),
    -		Targets:    []string{"pre-checkin"},
    -		Inputs:     []string{"*.platform=linux/amd64"},
    -		Refs:       []string{"builder/builder0/hx2qf1w11qvz1x3k471c5i8xw", "builder/builder0/968zj0g03jmlx0s8qslnvh6rl", "builder/builder0/naf44f9i1710lf7y12lv5hb1z"},
    +		Targets: []string{"pre-checkin"},
    +		Refs:    []string{"builder/builder0/hx2qf1w11qvz1x3k471c5i8xw", "builder/builder0/968zj0g03jmlx0s8qslnvh6rl", "builder/builder0/naf44f9i1710lf7y12lv5hb1z"},
     	}
     
     	testStateGroupRef1ID = "hx2qf1w11qvz1x3k471c5i8xw"
    
  • localstate/migrate.go+56 0 added
    @@ -0,0 +1,56 @@
    +package localstate
    +
    +import (
    +	"encoding/json"
    +	"os"
    +	"path/filepath"
    +
    +	"github.com/pkg/errors"
    +)
    +
    +func (ls *LocalState) MigrateIfNeeded() error {
    +	currentVersion := ls.readVersion()
    +	if currentVersion == version {
    +		return nil
    +	}
    +	migrations := map[int]func(*LocalState) error{
    +		2: (*LocalState).migration2,
    +	}
    +	for v := currentVersion + 1; v <= version; v++ {
    +		migration, found := migrations[v]
    +		if !found {
    +			return errors.Errorf("localstate migration v%d not found", v)
    +		}
    +		if err := migration(ls); err != nil {
    +			return errors.Wrapf(err, "localstate migration v%d failed", v)
    +		}
    +	}
    +	return ls.writeVersion(version)
    +}
    +
    +func (ls *LocalState) migration2() error {
    +	return filepath.Walk(ls.GroupDir(), func(path string, info os.FileInfo, err error) error {
    +		if err != nil {
    +			return err
    +		}
    +		if info.IsDir() {
    +			return nil
    +		}
    +		dt, err := os.ReadFile(path)
    +		if err != nil {
    +			return err
    +		}
    +		var stg StateGroup
    +		if err := json.Unmarshal(dt, &stg); err != nil {
    +			return err
    +		}
    +		mdt, err := json.Marshal(stg)
    +		if err != nil {
    +			return err
    +		}
    +		if err := os.WriteFile(path, mdt, 0600); err != nil {
    +			return err
    +		}
    +		return nil
    +	})
    +}
    
  • util/tracing/trace.go+3 4 modified
    @@ -2,7 +2,6 @@ package tracing
     
     import (
     	"context"
    -	"os"
     	"strings"
     
     	"github.com/moby/buildkit/util/tracing/delegated"
    @@ -13,7 +12,7 @@ import (
     	"go.opentelemetry.io/otel/trace"
     )
     
    -func TraceCurrentCommand(ctx context.Context, name string) (context.Context, func(error), error) {
    +func TraceCurrentCommand(ctx context.Context, args []string, attrs ...attribute.KeyValue) (context.Context, func(error), error) {
     	opts := []sdktrace.TracerProviderOption{
     		sdktrace.WithResource(detect.Resource()),
     		sdktrace.WithBatcher(delegated.DefaultExporter),
    @@ -25,8 +24,8 @@ func TraceCurrentCommand(ctx context.Context, name string) (context.Context, fun
     	}
     
     	tp := sdktrace.NewTracerProvider(opts...)
    -	ctx, span := tp.Tracer("").Start(ctx, name, trace.WithAttributes(
    -		attribute.String("command", strings.Join(os.Args, " ")),
    +	ctx, span := tp.Tracer("").Start(ctx, strings.Join(args, " "), trace.WithAttributes(
    +		attrs...,
     	))
     
     	return ctx, func(err error) {
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.