From a16ad6fe0fbd551b853f2585484de2d0b1f04e7d Mon Sep 17 00:00:00 2001 From: David Symonds Date: Thu, 14 Jul 2011 12:02:58 +1000 Subject: [PATCH] exp/template: escape < and > in JS escaper. Angle brackets can trigger some browser sniffers, causing some output to be interpreted as HTML. Escaping angle brackets closes that security hole. R=r CC=golang-dev https://golang.org/cl/4714044 --- src/pkg/exp/template/exec_test.go | 1 + src/pkg/exp/template/funcs.go | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/pkg/exp/template/exec_test.go b/src/pkg/exp/template/exec_test.go index 112adbf246..97ec952493 100644 --- a/src/pkg/exp/template/exec_test.go +++ b/src/pkg/exp/template/exec_test.go @@ -411,6 +411,7 @@ func TestJSEscaping(t *testing.T) { {`Go "jump" \`, `Go \"jump\" \\`}, {`Yukihiro says "今日は世界"`, `Yukihiro says \"今日は世界\"`}, {"unprintable \uFDFF", `unprintable \uFDFF`}, + {``, `\x3Chtml\x3E`}, } for _, tc := range testCases { s := JSEscapeString(tc.in) diff --git a/src/pkg/exp/template/funcs.go b/src/pkg/exp/template/funcs.go index 3bf2bdd636..fd66a1f415 100644 --- a/src/pkg/exp/template/funcs.go +++ b/src/pkg/exp/template/funcs.go @@ -233,6 +233,8 @@ var ( jsBackslash = []byte(`\\`) jsApos = []byte(`\'`) jsQuot = []byte(`\"`) + jsLt = []byte(`\x3C`) + jsGt = []byte(`\x3E`) ) @@ -242,14 +244,14 @@ func JSEscape(w io.Writer, b []byte) { for i := 0; i < len(b); i++ { c := b[i] - if ' ' <= c && c < utf8.RuneSelf && c != '\\' && c != '"' && c != '\'' { + if !jsIsSpecial(int(c)) { // fast path: nothing to do continue } w.Write(b[last:i]) if c < utf8.RuneSelf { - // Quotes and slashes get quoted. + // Quotes, slashes and angle brackets get quoted. // Control characters get written as \u00XX. switch c { case '\\': @@ -258,6 +260,10 @@ func JSEscape(w io.Writer, b []byte) { w.Write(jsApos) case '"': w.Write(jsQuot) + case '<': + w.Write(jsLt) + case '>': + w.Write(jsGt) default: w.Write(jsLowUni) t, b := c>>4, c&0x0f @@ -293,7 +299,7 @@ func JSEscapeString(s string) string { func jsIsSpecial(rune int) bool { switch rune { - case '\\', '\'', '"': + case '\\', '\'', '"', '<', '>': return true } return rune < ' ' || utf8.RuneSelf <= rune -- 2.50.0