Low severityNVD Advisory· Published Jan 7, 2022· Updated Sep 16, 2024
ANSI escape characters in kubectl output are not being filtered
CVE-2021-25743
Description
kubectl does not neutralize escape, meta or control sequences contained in the raw data it outputs to a terminal. This includes but is not limited to the unstructured string fields in objects such as Events.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
k8s.io/kubernetesGo | < 1.26.0-alpha.3 | 1.26.0-alpha.3 |
Affected products
1- Range: unspecified
Patches
1dad0e937c0f7Escape terminal special characters in kubectl (#112553)
9 files changed · +139 −13
staging/src/k8s.io/cli-runtime/pkg/printers/tableprinter.go+7 −6 modified@@ -212,18 +212,19 @@ func printTable(table *metav1.Table, output io.Writer, options PrintOptions) err case string: print := val truncated := false - // truncate at newlines - newline := strings.Index(print, "\n") - if newline >= 0 { + // Truncate at the first newline, carriage return or formfeed + // (treated as a newline by tabwriter). + breakchar := strings.IndexAny(print, "\f\n\r") + if breakchar >= 0 { truncated = true - print = print[:newline] + print = print[:breakchar] } - fmt.Fprint(output, print) + WriteEscaped(output, print) if truncated { fmt.Fprint(output, "...") } default: - fmt.Fprint(output, val) + WriteEscaped(output, fmt.Sprint(val)) } } }
staging/src/k8s.io/cli-runtime/pkg/printers/tableprinter_test.go+12 −0 modified@@ -769,6 +769,18 @@ test1 20h This is first line which is long and goes for on and on and on an }, expected: `NAME AGE DESCRIPTION test1 20h This is first... +`, + }, + // terminal special character, should be escaped + { + columns: []metav1.TableColumnDefinition{ + {Name: "Name", Type: "string"}, + }, + rows: []metav1.TableRow{ + {Cells: []interface{}{"test1\x1b"}}, + }, + expected: `NAME +test1^[ `, }, }
staging/src/k8s.io/cli-runtime/pkg/printers/terminal.go+39 −0 added@@ -0,0 +1,39 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package printers + +import ( + "io" + "strings" +) + +// terminalEscaper replaces ANSI escape sequences and other terminal special +// characters to avoid terminal escape character attacks (issue #101695). +var terminalEscaper = strings.NewReplacer("\x1b", "^[", "\r", "\\r") + +// WriteEscaped replaces unsafe terminal characters with replacement strings +// and writes them to the given writer. +func WriteEscaped(writer io.Writer, output string) error { + _, err := terminalEscaper.WriteString(writer, output) + return err +} + +// EscapeTerminal escapes terminal special characters in a human readable (but +// non-reversible) format. +func EscapeTerminal(in string) string { + return terminalEscaper.Replace(in) +}
staging/src/k8s.io/kubectl/pkg/cmd/events/event_printer.go+6 −4 modified@@ -26,6 +26,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/duration" + "k8s.io/cli-runtime/pkg/printers" ) // EventPrinter stores required fields to be used for @@ -72,10 +73,11 @@ func (ep *EventPrinter) printOneEvent(w io.Writer, e corev1.Event) { } fmt.Fprintf(w, "%s\t%s\t%s\t%s/%s\t%v\n", interval, - e.Type, - e.Reason, - e.InvolvedObject.Kind, e.InvolvedObject.Name, - strings.TrimSpace(e.Message), + printers.EscapeTerminal(e.Type), + printers.EscapeTerminal(e.Reason), + printers.EscapeTerminal(e.InvolvedObject.Kind), + printers.EscapeTerminal(e.InvolvedObject.Name), + printers.EscapeTerminal(strings.TrimSpace(e.Message)), ) }
staging/src/k8s.io/kubectl/pkg/cmd/events/event_printer_test.go+34 −0 modified@@ -208,6 +208,40 @@ foo 12m (x3 over 20m) Normal ScalingReplicaSet Deployment/bar Scaled up replica }, }, expected: `foo 12m (x3 over 20m) Normal ScalingReplicaSet Deployment/bar Scaled up replica set bar-002 to 1 +`, + }, + { + printer: EventPrinter{ + NoHeaders: false, + AllNamespaces: false, + }, + obj: &corev1.EventList{ + Items: []corev1.Event{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "bar-000", + Namespace: "foo", + }, + InvolvedObject: corev1.ObjectReference{ + APIVersion: "apps/v1", + Kind: "Deployment", + Name: "bar\x1b", + Namespace: "foo", + }, + Type: "test\x1b", + Reason: "test\x1b", + Message: "\x1b", + ReportingController: "deployment-controller", + EventTime: metav1.NewMicroTime(time.Now().Add(-20 * time.Minute)), + Series: &corev1.EventSeries{ + Count: 3, + LastObservedTime: metav1.NewMicroTime(time.Now().Add(-1 * time.Minute)), + }, + }, + }, + }, + expected: `LAST SEEN TYPE REASON OBJECT MESSAGE +60s (x3 over 20m) test^[ test^[ Deployment/bar^[ ^[ `, }, }
staging/src/k8s.io/kubectl/pkg/cmd/get/customcolumn.go+1 −1 modified@@ -252,7 +252,7 @@ func (s *CustomColumnsPrinter) printOneObject(obj runtime.Object, parsers []*jso } for arrIx := range values { for valIx := range values[arrIx] { - valueStrings = append(valueStrings, fmt.Sprintf("%v", values[arrIx][valIx].Interface())) + valueStrings = append(valueStrings, printers.EscapeTerminal(fmt.Sprint(values[arrIx][valIx].Interface()))) } } columns[ix] = strings.Join(valueStrings, ",")
staging/src/k8s.io/kubectl/pkg/cmd/get/customcolumn_test.go+16 −0 modified@@ -311,6 +311,22 @@ foo baz obj: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}, TypeMeta: metav1.TypeMeta{APIVersion: "baz"}}, expectedOutput: `NAME API_VERSION NOT_FOUND foo baz <none> +`, + }, + { + columns: []Column{ + { + Header: "NAME", + FieldSpec: "{.metadata.name}", + }, + }, + obj: &corev1.PodList{ + Items: []corev1.Pod{ + {ObjectMeta: metav1.ObjectMeta{Name: "\x1b \r"}}, + }, + }, + expectedOutput: `NAME +^[ \r `, }, }
staging/src/k8s.io/kubectl/pkg/describe/describe.go+5 −2 modified@@ -65,6 +65,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/cli-runtime/pkg/genericclioptions" + "k8s.io/cli-runtime/pkg/printers" runtimeresource "k8s.io/cli-runtime/pkg/resource" "k8s.io/client-go/dynamic" clientset "k8s.io/client-go/kubernetes" @@ -148,11 +149,13 @@ func (pw *prefixWriter) Write(level int, format string, a ...interface{}) { for i := 0; i < level; i++ { prefix += levelSpace } - fmt.Fprintf(pw.out, prefix+format, a...) + output := fmt.Sprintf(prefix+format, a...) + printers.WriteEscaped(pw.out, output) } func (pw *prefixWriter) WriteLine(a ...interface{}) { - fmt.Fprintln(pw.out, a...) + output := fmt.Sprintln(a...) + printers.WriteEscaped(pw.out, output) } func (pw *prefixWriter) Flush() {
staging/src/k8s.io/kubectl/pkg/describe/describe_test.go+19 −0 modified@@ -5507,3 +5507,22 @@ func TestControllerRef(t *testing.T) { t.Errorf("unexpected out: %s", out) } } + +func TestDescribeTerminalEscape(t *testing.T) { + fake := fake.NewSimpleClientset(&corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "mycm", + Namespace: "foo", + Annotations: map[string]string{"annotation1": "terminal escape: \x1b"}, + }, + }) + c := &describeClient{T: t, Namespace: "foo", Interface: fake} + d := ConfigMapDescriber{c} + out, err := d.Describe("foo", "mycm", DescriberSettings{ShowEvents: true}) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if strings.Contains(out, "\x1b") || !strings.Contains(out, "^[") { + t.Errorf("unexpected out: %s", out) + } +}
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
7- github.com/advisories/GHSA-f9jg-8p32-2f55ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2021-25743ghsaADVISORY
- github.com/kubernetes/kubernetes/commit/dad0e937c0f76344363eb691b2668490ffef8537ghsaWEB
- github.com/kubernetes/kubernetes/issues/101695ghsax_refsource_MISCWEB
- github.com/kubernetes/kubernetes/pull/112553ghsaWEB
- security.netapp.com/advisory/ntap-20220217-0003ghsaWEB
- security.netapp.com/advisory/ntap-20220217-0003/mitrex_refsource_CONFIRM
News mentions
0No linked articles in our index yet.