summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland Shoemaker <bracewell@google.com>2023-04-13 14:01:50 -0700
committerCarlos Amedee <carlos@golang.org>2023-05-02 16:36:15 +0000
commit337dd75343145b74ed2073d793322eb4103b56ad (patch)
tree25b697b74ad7a1f971535e5002b246563edac8a9
parent4a28cad66655ee01c6e944271e23c33cab021765 (diff)
downloadgo-git-337dd75343145b74ed2073d793322eb4103b56ad.tar.gz
[release-branch.go1.20] 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. For #59722 Fixes #59816 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://team-review.git.corp.google.com/c/golang/go-private/+/1851494 Run-TryBot: Damien Neil <dneil@google.com> Reviewed-by: Roland Shoemaker <bracewell@google.com> TryBot-Result: Security TryBots <security-trybots@go-security-trybots.iam.gserviceaccount.com> Reviewed-on: https://go-review.googlesource.com/c/go/+/491358 Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Run-TryBot: Carlos Amedee <carlos@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
-rw-r--r--src/html/template/escape.go5
-rw-r--r--src/html/template/escape_test.go15
-rw-r--r--src/html/template/html.go3
3 files changed, 20 insertions, 3 deletions
diff --git a/src/html/template/escape.go b/src/html/template/escape.go
index 23ece7a72f..c262d1698d 100644
--- a/src/html/template/escape.go
+++ b/src/html/template/escape.go
@@ -381,9 +381,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)
}