sonic-pi

https://github.com/sonic-pi-net/sonic-pi

C++

Code. Music. Live.

ERB::Util#json_escape

A utility method for escaping HTML entities in JSON strings. Specifically, the
&, > and < characters are replaced with their equivalent unicode escaped form -
\u0026, \u003e, and \u003c. The Unicode sequences \u2028 and \u2029 are also
escaped as they are treated as newline characters in some JavaScript engines.
These sequences have identical meaning as the original characters inside the
context of a JSON string, so assuming the input is a valid and well-formed
JSON value, the output will have equivalent meaning when parsed:

  json = JSON.generate({ name: "</script><script>alert('PWNED!!!')</script>"})
  # => "{\"name\":\"</script><script>alert('PWNED!!!')</script>\"}"

  json_escape(json)
  # => "{\"name\":\"\\u003C/script\\u003E\\u003Cscript\\u003Ealert('PWNED!!!')\\u003C/script\\u003E\"}"

  JSON.parse(json) == JSON.parse(json_escape(json))
  # => true

The intended use case for this method is to escape JSON strings before including
them inside a script tag to avoid XSS vulnerability:

  <script>
    var currentUser = <%= raw json_escape(current_user.to_json) %>;
  </script>

It is necessary to +raw+ the result of +json_escape+, so that quotation marks
don't get converted to <tt>&quot;</tt> entities. +json_escape+ doesn't
automatically flag the result as HTML safe, since the raw value is unsafe to
use inside HTML attributes.

If you need to output JSON elsewhere in your HTML, you can just do something
like this, as any unsafe characters (including quotation marks) will be
automatically escaped for you:

  <div data-user-info="<%= current_user.to_json %>">...</div>

WARNING: this helper only works with valid JSON. Using this on non-JSON values
will open up serious XSS vulnerabilities. For example, if you replace the
+current_user.to_json+ in the example above with user input instead, the browser
will happily eval() that string as JavaScript.

The escaping performed in this method is identical to those performed in the
Active Support JSON encoder when +ActiveSupport.escape_html_entities_in_json+ is
set to true. Because this transformation is idempotent, this helper can be
applied even if +ActiveSupport.escape_html_entities_in_json+ is already true.

Therefore, when you are unsure if +ActiveSupport.escape_html_entities_in_json+
is enabled, or if you are unsure where your JSON string originated from, it
is recommended that you always apply this helper (other libraries, such as the
JSON gem, do not provide this kind of protection by default; also some gems
might override +to_json+ to bypass Active Support's encoder).

Source | Google | Stack overflow

Edit

git clone [email protected]:sonic-pi-net/sonic-pi.git

cd sonic-pi

open app/server/ruby/vendor/activesupport-7.0.6/lib/active_support/core_ext/string/output_safety.rb

Contribute

# Make a new branch

git checkout -b -your-name--update-docs-ERB--Util-json_escape-for-pr


# Commit to git

git add app/server/ruby/vendor/activesupport-7.0.6/lib/active_support/core_ext/string/output_safety.rbgit commit -m "better docs for ERB::Util#json_escape"


# Open pull request

gem install hub # on a mac you can `brew install hub`

hub fork

git push <your name> -your-name--update-docs-ERB--Util-json_escape-for-pr

hub pull-request


# Celebrate!