4.3 Medium
CVSS2
Access Vector
NETWORK
Access Complexity
MEDIUM
Authentication
NONE
Confidentiality Impact
NONE
Integrity Impact
PARTIAL
Availability Impact
NONE
AV:N/AC:M/Au:N/C:N/I:P/A:N
0.003 Low
EPSS
Percentile
63.0%
Rails does not escape hash keys properly in to_json
when generating json.
Values are escaped as expected
irb(main):001:0> {"a"=>"<>"}.to_json
=> "{\"a\":\"\\u003c\\u003e\"}"
However keys are not:
irb(main):002:0> {"<>"=>"a"}.to_json
=> "{\"<>\":\"a\"}"
This is because the json
gem calls .to_s
on the keys here which transforms the EscapedString
back into a simple String
so it doesn’t go through the escaping process that values go through here.
Security consideration: this issue is a vector for XSS when an arbitrary value is used as a key and reflected in a javascript tag. Consider this piece of code:
javascript_tag "var json=#{params.to_json}"
When params is something like {"</script><script>alert(1)//"=>"xss"}
then <>
are not escaped as they should and the javascript tag looks like this:
<script>
//<![CDATA[
var json={"</script><script>alert(1)//":"xss"}
//]]>
</script>
The </script>
inside the json object will terminate the opening script tag because it has precedence over everything else, and alert(1)
is executed.
I believe this issue also applies to 4.2-stable and master.
Note that I opened a PR for a related issue in the json gem (https://github.com/flori/json/pull/235) which occurs when ActiveSupport.escape_html_entities_in_json = false
because the forward slash is never escaped (neither in rails nor in the json gem). It might be worth fixing this in rails as well.