Skip to content

fix: sanitize error before gRPC return to prevent credential leak in pod events#12801

Merged
mxpv merged 1 commit intocontainerd:mainfrom
aadhar-agarwal:aadagarwal/sanitize-grpc-error-5453
Jan 21, 2026
Merged

fix: sanitize error before gRPC return to prevent credential leak in pod events#12801
mxpv merged 1 commit intocontainerd:mainfrom
aadhar-agarwal:aadagarwal/sanitize-grpc-error-5453

Conversation

@aadhar-agarwal
Copy link
Copy Markdown
Contributor

@aadhar-agarwal aadhar-agarwal commented Jan 20, 2026

PR #12491 fixed credential leaks in containerd logs but the gRPC error returned to kubelet still contains sensitive information (e.g., SAS tokens). This is visible in Kubernetes pod events via kubectl describe pod.

Issue:
The SanitizeError call was placed inside the defer block:

defer func() {
    if err != nil {
        err = ctrdutil.SanitizeError(err)  // Runs AFTER return is evaluated
        log.G(ctx).WithError(err).Errorf(...)
    }
}()
res, err = in.c.PullImage(...)
return res, errgrpc.ToGRPC(err)  // Uses ORIGINAL unsanitized error

Go evaluates errgrpc.ToGRPC(err) before the defer runs, so the gRPC message contains the original unsanitized error with credentials.

Fix:
Move SantiizeError before the return statement:

res, err = in.c.PullImage(...)
if err != nil {
    err = ctrdutil.SanitizeError(err)
}
return res, errgrpc.ToGRPC(err)  // Now uses sanitized error

This ensures both the logged error and the gRPC error use the sanitized error.

Testing:

  • Tested on an AKS cluster
  • Blocked blob storage IPs via iptables to force image pull failure
  • Deployed pod with ACR image requiring SAS token authentication

When describing pod:
image

containerd log:

Jan 20 22:35:45 aks-nodepool1-35109453-vmss000000 containerd[38541]: time="2026-01-20T22:35:45.730403025Z" level=error msg="PullImage \"akscon
tainerhost.azurecr.io/newimage:v1\" failed" error="rpc error: code = Unknown desc = failed to pull and unpack image \"akscontainerhost.azurecr
.io/newimage:v1\": failed to copy: httpReadSeeker: failed open: failed to do request: Get \"https://eusmanaged213.blob.core.windows.net/d46180
728b794a35a39c3b22ed20f8a3-6k5n90bm44//docker/registry/v2/blobs/sha256/bc/bc717f9cc8f343d7e59d10bc7fc0c811530afa98d437c9f6bcd8fb3dfc2308da/dat
a?anon=%5BREDACTED%5D&regid=%5BREDACTED%5D&se=%5BREDACTED%5D&sig=%5BREDACTED%5D&ske=%5BREDACTED%5D&skoid=%5BREDACTED%5D&sks=%5BREDACTED%5D&skt
=%5BREDACTED%5D&sktid=%5BREDACTED%5D&skv=%5BREDACTED%5D&sp=%5BREDACTED%5D&spr=%5BREDACTED%5D&sr=%5BREDACTED%5D&sv=%5BREDACTED%5D\": dial tcp 2
0.60.63.193:443: connect: connection refused"
Jan 20 22:35:45 aks-nodepool1-35109453-vmss000000 containerd[38541]: time="2026-01-20T22:35:45.730424836Z" level=info msg="stop pulling image
akscontainerhost.azurecr.io/newimage:v1: active requests=0, bytes read=0"
root@aks-nodepool1-35109453-vmss000000 [ / ]#

…pod events

PR containerd#12491 fixed credential leaks in containerd logs but the gRPC error
returned to kubelet still contained sensitive information. This was
visible in Kubernetes pod events via `kubectl describe pod`.

The issue was that SanitizeError was called inside the defer block,
but errgrpc.ToGRPC(err) was evaluated before the defer ran, so the
gRPC message contained the original unsanitized error.

Move SanitizeError before the return statement so both the logged
error and the gRPC error are sanitized.

Ref: containerd#5453
Signed-off-by: Aadhar Agarwal <[email protected]>
Copy link
Copy Markdown
Member

@AkihiroSuda AkihiroSuda left a comment

Choose a reason for hiding this comment

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

@AkihiroSuda AkihiroSuda added cherry-pick/1.7.x Change to be cherry picked to release/1.7 branch cherry-pick/2.1.x Change to be cherry picked to release/2.1 branch cherry-pick/2.2.x Change to be cherry picked to release/2.2 branch labels Jan 21, 2026
@aadhar-agarwal
Copy link
Copy Markdown
Contributor Author

Thanks, but next time please follow https://github.com/containerd/containerd/security

Ah, thank you for pointing this out - Sounds good!

@github-project-automation github-project-automation Bot moved this from Needs Triage to Review In Progress in Pull Request Review Jan 21, 2026
@mxpv mxpv added this pull request to the merge queue Jan 21, 2026
Merged via the queue into containerd:main with commit 207bf2b Jan 21, 2026
52 checks passed
@github-project-automation github-project-automation Bot moved this from Review In Progress to Done in Pull Request Review Jan 21, 2026
@AkihiroSuda
Copy link
Copy Markdown
Member

/cherry-pick release/2.2
/cherry-pick release/2.1
/cherry-pick release/1.7

@k8s-infra-cherrypick-robot
Copy link
Copy Markdown

@AkihiroSuda: #12801 failed to apply on top of branch "release/1.7":

Applying: fix: sanitize error before gRPC return to prevent credential leak in pod events
Using index info to reconstruct a base tree...
A	internal/cri/instrument/instrumented_service.go
Falling back to patching base and 3-way merge...
CONFLICT (modify/delete): internal/cri/instrument/instrumented_service.go deleted in HEAD and modified in fix: sanitize error before gRPC return to prevent credential leak in pod events. Version fix: sanitize error before gRPC return to prevent credential leak in pod events of internal/cri/instrument/instrumented_service.go left in tree.
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0001 fix: sanitize error before gRPC return to prevent credential leak in pod events

Details

In response to this:

/cherry-pick release/2.2
/cherry-pick release/2.1
/cherry-pick release/1.7

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-infra-cherrypick-robot
Copy link
Copy Markdown

@AkihiroSuda: new pull request created: #12803

Details

In response to this:

/cherry-pick release/2.2
/cherry-pick release/2.1
/cherry-pick release/1.7

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-infra-cherrypick-robot
Copy link
Copy Markdown

@AkihiroSuda: new pull request created: #12804

Details

In response to this:

/cherry-pick release/2.2
/cherry-pick release/2.1
/cherry-pick release/1.7

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@AkihiroSuda AkihiroSuda removed cherry-pick/1.7.x Change to be cherry picked to release/1.7 branch cherry-pick/2.1.x Change to be cherry picked to release/2.1 branch labels Jan 21, 2026
@AkihiroSuda AkihiroSuda added cherry-picked/1.7.x PR commits are cherry-picked into release/1.7 branch cherry-picked/2.1.x PR commits are cherry picked into the release/2.1 branch cherry-picked/2.2.x PR commits are cherry-picked into release/2.2 branch and removed cherry-pick/2.2.x Change to be cherry picked to release/2.2 branch labels Jan 21, 2026
@chrishenzie
Copy link
Copy Markdown
Member

/cherry-pick release/2.0

@k8s-infra-cherrypick-robot
Copy link
Copy Markdown

@chrishenzie: new pull request created: #13180

Details

In response to this:

/cherry-pick release/2.0

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/cri Container Runtime Interface (CRI) cherry-pick/2.0.x Change to be cherry picked to release/2.0 branch cherry-picked/1.7.x PR commits are cherry-picked into release/1.7 branch cherry-picked/2.1.x PR commits are cherry picked into the release/2.1 branch cherry-picked/2.2.x PR commits are cherry-picked into release/2.2 branch kind/bug size/S

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

6 participants