]> Cypherpunks repositories - gostls13.git/commitdiff
json: escape < and > in any JSON string.
authorDavid Symonds <dsymonds@golang.org>
Thu, 14 Jul 2011 03:30:08 +0000 (13:30 +1000)
committerDavid Symonds <dsymonds@golang.org>
Thu, 14 Jul 2011 03:30:08 +0000 (13:30 +1000)
Angle brackets can trigger some browser sniffers, causing
some forms of JSON output to be interpreted as HTML.
Escaping angle brackets closes that security hole.

R=rsc
CC=golang-dev
https://golang.org/cl/4701047

src/pkg/json/decode_test.go
src/pkg/json/encode.go

index 24c97e576f99ebbe8faeda67203a185c57f3205d..c0ef5bc3aa1854a983a08150c7e04a9bd3468375 100644 (file)
@@ -208,6 +208,18 @@ func TestUnmarshalPtrPtr(t *testing.T) {
        }
 }
 
+func TestEscape(t *testing.T) {
+       const input = `"foobar"<html>`
+       const expected = `"\"foobar\"\u003chtml\u003e"`
+       b, err := Marshal(input)
+       if err != nil {
+               t.Fatalf("Marshal error: %v", err)
+       }
+       if s := string(b); s != expected {
+               t.Errorf("Encoding of [%s] was [%s], want [%s]", input, s, expected)
+       }
+}
+
 func TestHTMLEscape(t *testing.T) {
        b, err := MarshalForHTML("foobarbaz<>&quux")
        if err != nil {
index fbc00355a6052e5c50f1ac2e1e51bd4c511c4dbc..a60de55efa8b228f634097327237cd609ce59f30 100644 (file)
@@ -337,7 +337,7 @@ func (e *encodeState) string(s string) {
        start := 0
        for i := 0; i < len(s); {
                if b := s[i]; b < utf8.RuneSelf {
-                       if 0x20 <= b && b != '\\' && b != '"' {
+                       if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' {
                                i++
                                continue
                        }
@@ -355,6 +355,10 @@ func (e *encodeState) string(s string) {
                                e.WriteByte('\\')
                                e.WriteByte('r')
                        default:
+                               // This encodes bytes < 0x20 except for \n and \r,
+                               // as well as < and >. The latter are escaped because they
+                               // can lead to security holes when user-controlled strings
+                               // are rendered into JSON and served to some browsers.
                                e.WriteString(`\u00`)
                                e.WriteByte(hex[b>>4])
                                e.WriteByte(hex[b&0xF])