Search code examples
jsonrubyescapingstringifyhtml-safe

HTML Safe JSON generation with Ruby only


I need to embed a JSON object into an HTML data attribute. Using the Ruby to_json

RubyArrayOfHashes.to_json

generates a proper JSON string, but it is not escaped. So I get this in my HTML:

data-track="[{"source_id":7}]"

The above is not valid due to the double quotes not being escaped.

Is there an equivalent to the JS JSON.stringify() function in ruby?

I need this in my data attribute and not in a script tag.


Solution

  • Since you are not using a more common templating framework which automates escaping values, you need to manually ensure that ALL user-provided values you emit into your HTML are properly escaped.

    You can use the CGI module for that which ships with Ruby:

    require 'cgi'
    def h(value)
      CGI.escapeHTML(value)
    end
    
    json = RubyArrayOfHashes.to_json
    html = "<div data-track=\"#{h json}\">something</div>
    

    Note that depending on how the emitted data is interpreted, you might need to use other escaping methods. If you are e.g. emitting Javascript code between <script> tags, you need to escape it differently.

    In general, you should investigate ways to automate the escaping of values similar to what Rails does in recent versions. Having to manually escape all emitted values can quickly lead to bugs when you forgot to escape some data, leading to security issues such as XSS vulnerabilities.