Skip to content

Commit cf309f8

Browse files
dglk8s-publishing-bot
authored andcommitted
Escape terminal special characters in kubectl (#112553)
* Escape terminal special characters in kubectl * Add escaping for kubectl alpha events Kubernetes-commit: dad0e937c0f76344363eb691b2668490ffef8537
1 parent 76d40a0 commit cf309f8

File tree

5 files changed

+66
-14
lines changed

5 files changed

+66
-14
lines changed

go.mod

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ require (
1616
golang.org/x/text v0.4.0
1717
gopkg.in/yaml.v2 v2.4.0
1818
k8s.io/api v0.0.0-20221028075226-689257039cfb
19-
k8s.io/apimachinery v0.0.0-20221028075009-0524d6c61445
20-
k8s.io/client-go v0.0.0-20221028075543-f87d0472f2aa
19+
k8s.io/apimachinery v0.0.0-20221028155017-b03a432a2a6d
20+
k8s.io/client-go v0.0.0-20221028155554-0d5739633518
2121
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280
2222
k8s.io/utils v0.0.0-20220922133306-665eaaec4324
2323
sigs.k8s.io/kustomize/api v0.12.1
@@ -69,6 +69,6 @@ require (
6969

7070
replace (
7171
k8s.io/api => k8s.io/api v0.0.0-20221028075226-689257039cfb
72-
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20221028075009-0524d6c61445
73-
k8s.io/client-go => k8s.io/client-go v0.0.0-20221028075543-f87d0472f2aa
72+
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20221028155017-b03a432a2a6d
73+
k8s.io/client-go => k8s.io/client-go v0.0.0-20221028155554-0d5739633518
7474
)

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -491,10 +491,10 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
491491
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
492492
k8s.io/api v0.0.0-20221028075226-689257039cfb h1:QZsHf1k3xHSbYozSHt8DZOrH36F8MbdLP18n4ZkQ/1c=
493493
k8s.io/api v0.0.0-20221028075226-689257039cfb/go.mod h1:96woDPRgmgH0tVTXgsLdv0cwHXPUvZ97ghr8sMUtxx0=
494-
k8s.io/apimachinery v0.0.0-20221028075009-0524d6c61445 h1:hXu9HT0t7U8yoa+ag/YUgy2/7yj0NvlVHbHjqw1R3qs=
495-
k8s.io/apimachinery v0.0.0-20221028075009-0524d6c61445/go.mod h1:nG4gaqgN0dCXlF11Oh/vA7GosujtSKqnr19oq8ag6qA=
496-
k8s.io/client-go v0.0.0-20221028075543-f87d0472f2aa h1:9+11V9Ct7evjC9yl+E3qfBgJi21lzG9VHpwzCx0yrIw=
497-
k8s.io/client-go v0.0.0-20221028075543-f87d0472f2aa/go.mod h1:hg9A6iQF4ggK+BmrByy91yyQ/gkUlEPXQEfJYh4iWM8=
494+
k8s.io/apimachinery v0.0.0-20221028155017-b03a432a2a6d h1:fg/DbLqFKxFESf3AnU5iwCexZWOUnFFLb0JraG20wZo=
495+
k8s.io/apimachinery v0.0.0-20221028155017-b03a432a2a6d/go.mod h1:zSkBXgO5G/dSQOe256tx5Yo2OJytojpY3bsXu/4/ZJE=
496+
k8s.io/client-go v0.0.0-20221028155554-0d5739633518 h1:KlSjZkXeVyocbVpEU157nadMdQIfWXchaItVtjmMVUE=
497+
k8s.io/client-go v0.0.0-20221028155554-0d5739633518/go.mod h1:9OZTm80DH1AI7P4cpx8yehVlTU1xZQCsMtAtlJYLWDw=
498498
k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=
499499
k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
500500
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E=

pkg/printers/tableprinter.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -212,18 +212,19 @@ func printTable(table *metav1.Table, output io.Writer, options PrintOptions) err
212212
case string:
213213
print := val
214214
truncated := false
215-
// truncate at newlines
216-
newline := strings.Index(print, "\n")
217-
if newline >= 0 {
215+
// Truncate at the first newline, carriage return or formfeed
216+
// (treated as a newline by tabwriter).
217+
breakchar := strings.IndexAny(print, "\f\n\r")
218+
if breakchar >= 0 {
218219
truncated = true
219-
print = print[:newline]
220+
print = print[:breakchar]
220221
}
221-
fmt.Fprint(output, print)
222+
WriteEscaped(output, print)
222223
if truncated {
223224
fmt.Fprint(output, "...")
224225
}
225226
default:
226-
fmt.Fprint(output, val)
227+
WriteEscaped(output, fmt.Sprint(val))
227228
}
228229
}
229230
}

pkg/printers/tableprinter_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,18 @@ test1 20h This is first line which is long and goes for on and on and on an
769769
},
770770
expected: `NAME AGE DESCRIPTION
771771
test1 20h This is first...
772+
`,
773+
},
774+
// terminal special character, should be escaped
775+
{
776+
columns: []metav1.TableColumnDefinition{
777+
{Name: "Name", Type: "string"},
778+
},
779+
rows: []metav1.TableRow{
780+
{Cells: []interface{}{"test1\x1b"}},
781+
},
782+
expected: `NAME
783+
test1^[
772784
`,
773785
},
774786
}

pkg/printers/terminal.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
Copyright 2022 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package printers
18+
19+
import (
20+
"io"
21+
"strings"
22+
)
23+
24+
// terminalEscaper replaces ANSI escape sequences and other terminal special
25+
// characters to avoid terminal escape character attacks (issue #101695).
26+
var terminalEscaper = strings.NewReplacer("\x1b", "^[", "\r", "\\r")
27+
28+
// WriteEscaped replaces unsafe terminal characters with replacement strings
29+
// and writes them to the given writer.
30+
func WriteEscaped(writer io.Writer, output string) error {
31+
_, err := terminalEscaper.WriteString(writer, output)
32+
return err
33+
}
34+
35+
// EscapeTerminal escapes terminal special characters in a human readable (but
36+
// non-reversible) format.
37+
func EscapeTerminal(in string) string {
38+
return terminalEscaper.Replace(in)
39+
}

0 commit comments

Comments
 (0)