diff options
| author | Roland Shoemaker <bracewell@google.com> | 2023-04-13 14:01:50 -0700 |
|---|---|---|
| committer | Carlos Amedee <carlos@golang.org> | 2023-05-02 19:42:28 +0000 |
| commit | 0d347544cbca0f42b160424f6bc2458ebcc7b3fc (patch) | |
| tree | bc11f07a19ca44fe318fcebb1450e71fc20f3abe /src | |
| parent | a32232cb18ed07496ec77c1cf2dcefa1cb0ac057 (diff) | |
| download | go-0d347544cbca0f42b160424f6bc2458ebcc7b3fc.tar.xz | |
html/template: emit filterFailsafe for empty unquoted attr value
An unquoted action used as an attribute value can result in unsafe
behavior if it is empty, as HTML normalization will result in unexpected
attributes, and may allow attribute injection. If executing a template
results in a empty unquoted attribute value, emit filterFailsafe
instead.
Thanks to Juho Nurminen of Mattermost for reporting this issue.
Fixes #59722
Fixes CVE-2023-29400
Change-Id: Ia38d1b536ae2b4af5323a6c6d861e3c057c2570a
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1826631
Reviewed-by: Julie Qiu <julieqiu@google.com>
Run-TryBot: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/491617
Run-TryBot: Carlos Amedee <carlos@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src')
| -rw-r--r-- | src/html/template/escape.go | 5 | ||||
| -rw-r--r-- | src/html/template/escape_test.go | 15 | ||||
| -rw-r--r-- | src/html/template/html.go | 3 |
3 files changed, 20 insertions, 3 deletions
diff --git a/src/html/template/escape.go b/src/html/template/escape.go index 4ba1d6b318..a62ef159f0 100644 --- a/src/html/template/escape.go +++ b/src/html/template/escape.go @@ -382,9 +382,8 @@ func normalizeEscFn(e string) string { // for all x. var redundantFuncs = map[string]map[string]bool{ "_html_template_commentescaper": { - "_html_template_attrescaper": true, - "_html_template_nospaceescaper": true, - "_html_template_htmlescaper": true, + "_html_template_attrescaper": true, + "_html_template_htmlescaper": true, }, "_html_template_cssescaper": { "_html_template_attrescaper": true, diff --git a/src/html/template/escape_test.go b/src/html/template/escape_test.go index 3dd212bac9..f8b2b448f2 100644 --- a/src/html/template/escape_test.go +++ b/src/html/template/escape_test.go @@ -678,6 +678,21 @@ func TestEscape(t *testing.T) { `<img srcset={{",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"}}>`, `<img srcset=,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,>`, }, + { + "unquoted empty attribute value (plaintext)", + "<p name={{.U}}>", + "<p name=ZgotmplZ>", + }, + { + "unquoted empty attribute value (url)", + "<p href={{.U}}>", + "<p href=ZgotmplZ>", + }, + { + "quoted empty attribute value", + "<p name=\"{{.U}}\">", + "<p name=\"\">", + }, } for _, test := range tests { diff --git a/src/html/template/html.go b/src/html/template/html.go index bcca0b51a0..a181699a5b 100644 --- a/src/html/template/html.go +++ b/src/html/template/html.go @@ -14,6 +14,9 @@ import ( // htmlNospaceEscaper escapes for inclusion in unquoted attribute values. func htmlNospaceEscaper(args ...any) string { s, t := stringify(args...) + if s == "" { + return filterFailsafe + } if t == contentTypeHTML { return htmlReplacer(stripTags(s), htmlNospaceNormReplacementTable, false) } |
