From 9db0e74f606b8afb28cc71d4b1c8b4ed24cabbf5 Mon Sep 17 00:00:00 2001
From: Roland Shoemaker <bracewell@google.com>
Date: Thu, 13 Apr 2023 14:01:50 -0700
Subject: [PATCH] [release-branch.go1.19] 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 #59815
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/+/1851498
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/491357
Run-TryBot: Carlos Amedee <carlos@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>

Upstream-Status: Backport [https://github.com/golang/go/commit/9db0e74f606b8afb28cc71d4b1c8b4ed24cabbf5]
CVE: CVE-2023-29400
Signed-off-by: Vivek Kumbhar <vkumbhar@mvista.com>
---
 src/html/template/escape.go      |  5 ++---
 src/html/template/escape_test.go | 15 +++++++++++++++
 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 ca078f4..bdccc65 100644
--- a/src/html/template/escape.go
+++ b/src/html/template/escape.go
@@ -362,9 +362,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 fbc84a7..4f48afe 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 356b829..636bc21 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 ...interface{}) string {
 	s, t := stringify(args...)
+	if s == "" {
+		return filterFailsafe
+	}
 	if t == contentTypeHTML {
 		return htmlReplacer(stripTags(s), htmlNospaceNormReplacementTable, false)
 	}
-- 
2.25.1

