diff --git a/.changelog/24683.txt b/.changelog/24683.txt new file mode 100644 index 00000000000..af07d6a99da --- /dev/null +++ b/.changelog/24683.txt @@ -0,0 +1,3 @@ +```release-note:security +api: sanitize the SignedIdentities in allocations to prevent privilege escalation through unredacted workload identity token impersonation associated with ACL policies. +``` diff --git a/command/agent/node_endpoint.go b/command/agent/node_endpoint.go index dc91a235784..2f6838aa088 100644 --- a/command/agent/node_endpoint.go +++ b/command/agent/node_endpoint.go @@ -105,6 +105,7 @@ func (s *HTTPServer) nodeAllocations(resp http.ResponseWriter, req *http.Request out.Allocs = make([]*structs.Allocation, 0) } for _, alloc := range out.Allocs { + alloc = alloc.Sanitize() alloc.SetEventDisplayMessages() } return out.Allocs, nil diff --git a/nomad/alloc_endpoint.go b/nomad/alloc_endpoint.go index 0afbacb3228..9e8678eb174 100644 --- a/nomad/alloc_endpoint.go +++ b/nomad/alloc_endpoint.go @@ -172,8 +172,9 @@ func (a *Alloc) GetAlloc(args *structs.AllocSpecificRequest, } // Setup the output - reply.Alloc = out if out != nil { + out = out.Sanitize() + reply.Alloc = out // Re-check namespace in case it differs from request. if !aclObj.AllowClientOp() && !allowNsOp(aclObj, out.Namespace) { return structs.NewErrUnknownAllocation(args.AllocID) diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index c832fab0a82..b3f0e8e4ac2 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -11199,6 +11199,23 @@ func (a *Allocation) GetID() string { return a.ID } +// Sanitize returns a copy of the allocation with the SignedIdentities field +// removed. This is useful for returning allocations to clients where the +// SignedIdentities field is not needed. +func (a *Allocation) Sanitize() *Allocation { + if a == nil { + return nil + } + + if a.SignedIdentities == nil { + return a + } + + clean := a.Copy() + clean.SignedIdentities = nil + return clean +} + // GetNamespace implements the NamespaceGetter interface, required for // pagination and filtering namespaces in endpoints that support glob namespace // requests using tokens with limited access.