@@ -62,15 +62,25 @@ string :: T.Text -> Builder
6262string s = {-# SCC "string" #-} singleton '"' <> quote s <> singleton '"'
6363 where
6464 quote q = case T.uncons t of
65− Nothing -> fromText h
65+ Nothing -> fromText h
6666 Just (!c,t') -> fromText h <> escape c <> quote t'
6767 where (h,t) = {-# SCC "break" #-} T.break isEscape q
68− isEscape c = c == '\"' || c == '\\' || c < '\x20'
68+ isEscape c = c == '\"' ||
69+ c == '\\' ||
70+ c == '<' ||
71+ c == '>' ||
72+ c < '\x20'
6973 escape '\"' = "\\\""
7074 escape '\\' = "\\\\"
7175 escape '\n' = "\\n"
7276 escape '\r' = "\\r"
7377 escape '\t' = "\\t"
78+
79+ -- The following prevents untrusted JSON strings containing </script> or -->
80+ -- from causing an XSS vulnerability:
81+ escape '<' = "\\u003c"
82+ escape '>' = "\\u003e"
83+
7484 escape c
7585 | c < '\x20' = fromString $ "\\u" ++ replicate (4 - length h) '0' ++ h
7686 | otherwise = singleton c