Commit a16ad6fe authored by David Symonds's avatar David Symonds

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
parent dfffc7a5
...@@ -411,6 +411,7 @@ func TestJSEscaping(t *testing.T) { ...@@ -411,6 +411,7 @@ func TestJSEscaping(t *testing.T) {
{`Go "jump" \`, `Go \"jump\" \\`}, {`Go "jump" \`, `Go \"jump\" \\`},
{`Yukihiro says "今日は世界"`, `Yukihiro says \"今日は世界\"`}, {`Yukihiro says "今日は世界"`, `Yukihiro says \"今日は世界\"`},
{"unprintable \uFDFF", `unprintable \uFDFF`}, {"unprintable \uFDFF", `unprintable \uFDFF`},
{`<html>`, `\x3Chtml\x3E`},
} }
for _, tc := range testCases { for _, tc := range testCases {
s := JSEscapeString(tc.in) s := JSEscapeString(tc.in)
......
...@@ -233,6 +233,8 @@ var ( ...@@ -233,6 +233,8 @@ var (
jsBackslash = []byte(`\\`) jsBackslash = []byte(`\\`)
jsApos = []byte(`\'`) jsApos = []byte(`\'`)
jsQuot = []byte(`\"`) jsQuot = []byte(`\"`)
jsLt = []byte(`\x3C`)
jsGt = []byte(`\x3E`)
) )
...@@ -242,14 +244,14 @@ func JSEscape(w io.Writer, b []byte) { ...@@ -242,14 +244,14 @@ func JSEscape(w io.Writer, b []byte) {
for i := 0; i < len(b); i++ { for i := 0; i < len(b); i++ {
c := b[i] c := b[i]
if ' ' <= c && c < utf8.RuneSelf && c != '\\' && c != '"' && c != '\'' { if !jsIsSpecial(int(c)) {
// fast path: nothing to do // fast path: nothing to do
continue continue
} }
w.Write(b[last:i]) w.Write(b[last:i])
if c < utf8.RuneSelf { if c < utf8.RuneSelf {
// Quotes and slashes get quoted. // Quotes, slashes and angle brackets get quoted.
// Control characters get written as \u00XX. // Control characters get written as \u00XX.
switch c { switch c {
case '\\': case '\\':
...@@ -258,6 +260,10 @@ func JSEscape(w io.Writer, b []byte) { ...@@ -258,6 +260,10 @@ func JSEscape(w io.Writer, b []byte) {
w.Write(jsApos) w.Write(jsApos)
case '"': case '"':
w.Write(jsQuot) w.Write(jsQuot)
case '<':
w.Write(jsLt)
case '>':
w.Write(jsGt)
default: default:
w.Write(jsLowUni) w.Write(jsLowUni)
t, b := c>>4, c&0x0f t, b := c>>4, c&0x0f
...@@ -293,7 +299,7 @@ func JSEscapeString(s string) string { ...@@ -293,7 +299,7 @@ func JSEscapeString(s string) string {
func jsIsSpecial(rune int) bool { func jsIsSpecial(rune int) bool {
switch rune { switch rune {
case '\\', '\'', '"': case '\\', '\'', '"', '<', '>':
return true return true
} }
return rune < ' ' || utf8.RuneSelf <= rune return rune < ' ' || utf8.RuneSelf <= rune
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment