summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/go/go-1.14/CVE-2024-24785.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/go/go-1.14/CVE-2024-24785.patch')
-rw-r--r--meta/recipes-devtools/go/go-1.14/CVE-2024-24785.patch197
1 files changed, 197 insertions, 0 deletions
diff --git a/meta/recipes-devtools/go/go-1.14/CVE-2024-24785.patch b/meta/recipes-devtools/go/go-1.14/CVE-2024-24785.patch
new file mode 100644
index 0000000000..1398a2ca48
--- /dev/null
+++ b/meta/recipes-devtools/go/go-1.14/CVE-2024-24785.patch
@@ -0,0 +1,197 @@
1From 3643147a29352ca2894fd5d0d2069bc4b4335a7e Mon Sep 17 00:00:00 2001
2From: Roland Shoemaker <roland@golang.org>
3Date: Wed, 14 Feb 2024 17:18:36 -0800
4Subject: [PATCH] [release-branch.go1.21] html/template: escape additional
5 tokens in MarshalJSON errors
6
7Escape "</script" and "<!--" in errors returned from MarshalJSON errors
8when attempting to marshal types in script blocks. This prevents any
9user controlled content from prematurely terminating the script block.
10
11Updates #65697
12Fixes #65968
13
14Change-Id: Icf0e26c54ea7d9c1deed0bff11b6506c99ddef1b
15Reviewed-on: https://go-review.googlesource.com/c/go/+/564196
16LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
17Reviewed-by: Damien Neil <dneil@google.com>
18(cherry picked from commit ccbc725f2d678255df1bd326fa511a492aa3a0aa)
19Reviewed-on: https://go-review.googlesource.com/c/go/+/567515
20Reviewed-by: Carlos Amedee <carlos@golang.org>
21
22Upstream-Status: Backport [https://github.com/golang/go/commit/3643147a29352ca2894fd5d0d2069bc4b4335a7e]
23CVE: CVE-2024-24785
24Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
25---
26 src/html/template/js.go | 22 ++++++++-
27 src/html/template/js_test.go | 96 ++++++++++++++++++++----------------
28 2 files changed, 74 insertions(+), 44 deletions(-)
29
30diff --git a/src/html/template/js.go b/src/html/template/js.go
31index 35994f0..4d3b25d 100644
32--- a/src/html/template/js.go
33+++ b/src/html/template/js.go
34@@ -171,13 +171,31 @@ func jsValEscaper(args ...interface{}) string {
35 // cyclic data. This may be an unacceptable DoS risk.
36 b, err := json.Marshal(a)
37 if err != nil {
38- // Put a space before comment so that if it is flush against
39+ // While the standard JSON marshaller does not include user controlled
40+ // information in the error message, if a type has a MarshalJSON method,
41+ // the content of the error message is not guaranteed. Since we insert
42+ // the error into the template, as part of a comment, we attempt to
43+ // prevent the error from either terminating the comment, or the script
44+ // block itself.
45+ //
46+ // In particular we:
47+ // * replace "*/" comment end tokens with "* /", which does not
48+ // terminate the comment
49+ // * replace "</script" with "\x3C/script", and "<!--" with
50+ // "\x3C!--", which prevents confusing script block termination
51+ // semantics
52+ //
53+ // We also put a space before the comment so that if it is flush against
54 // a division operator it is not turned into a line comment:
55 // x/{{y}}
56 // turning into
57 // x//* error marshaling y:
58 // second line of error message */null
59- return fmt.Sprintf(" /* %s */null ", strings.ReplaceAll(err.Error(), "*/", "* /"))
60+ errStr := err.Error()
61+ errStr = strings.ReplaceAll(errStr, "*/", "* /")
62+ errStr = strings.ReplaceAll(errStr, "</script", `\x3C/script`)
63+ errStr = strings.ReplaceAll(errStr, "<!--", `\x3C!--`)
64+ return fmt.Sprintf(" /* %s */null ", errStr)
65 }
66
67 // TODO: maybe post-process output to prevent it from containing
68diff --git a/src/html/template/js_test.go b/src/html/template/js_test.go
69index de9ef28..3fc3baf 100644
70--- a/src/html/template/js_test.go
71+++ b/src/html/template/js_test.go
72@@ -5,6 +5,7 @@
73 package template
74
75 import (
76+ "errors"
77 "bytes"
78 "math"
79 "strings"
80@@ -104,61 +105,72 @@ func TestNextJsCtx(t *testing.T) {
81 }
82 }
83
84+type jsonErrType struct{}
85+
86+func (e *jsonErrType) MarshalJSON() ([]byte, error) {
87+ return nil, errors.New("beep */ boop </script blip <!--")
88+}
89+
90 func TestJSValEscaper(t *testing.T) {
91 tests := []struct {
92- x interface{}
93- js string
94+ x interface{}
95+ js string
96+ skipNest bool
97 }{
98- {int(42), " 42 "},
99- {uint(42), " 42 "},
100- {int16(42), " 42 "},
101- {uint16(42), " 42 "},
102- {int32(-42), " -42 "},
103- {uint32(42), " 42 "},
104- {int16(-42), " -42 "},
105- {uint16(42), " 42 "},
106- {int64(-42), " -42 "},
107- {uint64(42), " 42 "},
108- {uint64(1) << 53, " 9007199254740992 "},
109+ {int(42), " 42 ", false},
110+ {uint(42), " 42 ", false},
111+ {int16(42), " 42 ", false},
112+ {uint16(42), " 42 ", false},
113+ {int32(-42), " -42 ", false},
114+ {uint32(42), " 42 ", false},
115+ {int16(-42), " -42 ", false},
116+ {uint16(42), " 42 ", false},
117+ {int64(-42), " -42 ", false},
118+ {uint64(42), " 42 ", false},
119+ {uint64(1) << 53, " 9007199254740992 ", false},
120 // ulp(1 << 53) > 1 so this loses precision in JS
121 // but it is still a representable integer literal.
122- {uint64(1)<<53 + 1, " 9007199254740993 "},
123- {float32(1.0), " 1 "},
124- {float32(-1.0), " -1 "},
125- {float32(0.5), " 0.5 "},
126- {float32(-0.5), " -0.5 "},
127- {float32(1.0) / float32(256), " 0.00390625 "},
128- {float32(0), " 0 "},
129- {math.Copysign(0, -1), " -0 "},
130- {float64(1.0), " 1 "},
131- {float64(-1.0), " -1 "},
132- {float64(0.5), " 0.5 "},
133- {float64(-0.5), " -0.5 "},
134- {float64(0), " 0 "},
135- {math.Copysign(0, -1), " -0 "},
136- {"", `""`},
137- {"foo", `"foo"`},
138+ {uint64(1)<<53 + 1, " 9007199254740993 ", false},
139+ {float32(1.0), " 1 ", false},
140+ {float32(-1.0), " -1 ", false},
141+ {float32(0.5), " 0.5 ", false},
142+ {float32(-0.5), " -0.5 ", false},
143+ {float32(1.0) / float32(256), " 0.00390625 ", false},
144+ {float32(0), " 0 ", false},
145+ {math.Copysign(0, -1), " -0 ", false},
146+ {float64(1.0), " 1 ", false},
147+ {float64(-1.0), " -1 ", false},
148+ {float64(0.5), " 0.5 ", false},
149+ {float64(-0.5), " -0.5 ", false},
150+ {float64(0), " 0 ", false},
151+ {math.Copysign(0, -1), " -0 ", false},
152+ {"", `""`, false},
153+ {"foo", `"foo"`, false},
154 // Newlines.
155- {"\r\n\u2028\u2029", `"\r\n\u2028\u2029"`},
156+ {"\r\n\u2028\u2029", `"\r\n\u2028\u2029"`, false},
157 // "\v" == "v" on IE 6 so use "\u000b" instead.
158- {"\t\x0b", `"\t\u000b"`},
159- {struct{ X, Y int }{1, 2}, `{"X":1,"Y":2}`},
160- {[]interface{}{}, "[]"},
161- {[]interface{}{42, "foo", nil}, `[42,"foo",null]`},
162- {[]string{"<!--", "</script>", "-->"}, `["\u003c!--","\u003c/script\u003e","--\u003e"]`},
163- {"<!--", `"\u003c!--"`},
164- {"-->", `"--\u003e"`},
165- {"<![CDATA[", `"\u003c![CDATA["`},
166- {"]]>", `"]]\u003e"`},
167- {"</script", `"\u003c/script"`},
168- {"\U0001D11E", "\"\U0001D11E\""}, // or "\uD834\uDD1E"
169- {nil, " null "},
170+ {"\t\x0b", `"\t\u000b"`, false},
171+ {struct{ X, Y int }{1, 2}, `{"X":1,"Y":2}`, false},
172+ {[]interface{}{}, "[]", false},
173+ {[]interface{}{42, "foo", nil}, `[42,"foo",null]`, false},
174+ {[]string{"<!--", "</script>", "-->"}, `["\u003c!--","\u003c/script\u003e","--\u003e"]`, false},
175+ {"<!--", `"\u003c!--"`, false},
176+ {"-->", `"--\u003e"`, false},
177+ {"<![CDATA[", `"\u003c![CDATA["`, false},
178+ {"]]>", `"]]\u003e"`, false},
179+ {"</script", `"\u003c/script"`, false},
180+ {"\U0001D11E", "\"\U0001D11E\"", false}, // or "\uD834\uDD1E"
181+ {nil, " null ", false},
182+ {&jsonErrType{}, " /* json: error calling MarshalJSON for type *template.jsonErrType: beep * / boop \\x3C/script blip \\x3C!-- */null ", true},
183 }
184
185 for _, test := range tests {
186 if js := jsValEscaper(test.x); js != test.js {
187 t.Errorf("%+v: want\n\t%q\ngot\n\t%q", test.x, test.js, js)
188 }
189+ if test.skipNest {
190+ continue
191+ }
192 // Make sure that escaping corner cases are not broken
193 // by nesting.
194 a := []interface{}{test.x}
195--
1962.25.1
197