in reply to JSON::XS and escaping literal strings

According to this StackOverflow discussion, forward slash can be escaped, but doesn't have to.

At work, we don't escape it, as we don't include JSON into script tags.

What's wrong with s{([/!])}{\\$1}g?

($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

Replies are listed 'Best First'.
Re^2: JSON::XS and escaping literal strings
by abelard12 (Novice) on Jun 06, 2018 at 23:37 UTC

    Thanks. And yes, this is within the context of embedding the JSON within HTML.

    I had wanted to include a code example, but having troubles getting it to post here. I'll try again. I'm HTML encoding a couple of < characters in the code block below, just to get it to post.

    #!/usr/bin/env perl use strict; use warnings; use JSON; my $untrusted = q{ETAGO problem? </script><script>window.alert('POWNED!');&lt;/scrip +t>}; my %data = ( '@context' => 'http://schema.org', '@type' => 'BlogPosting', description => $untrusted, ); my $json = JSON->new->encode(\%data); print qq{ <html> <body> <h1>Test</h1> <script type="ld+json">$json&lt;/script> </body> </html> };

    That breaks out and triggers the alert for me in Chrome.

        Yes, it does.

        I did some more research on this. I confirmed that the JSON spec does not require escaping of forward slashes.

        Some platforms escape the forward slash by default but allow you to disable that behavior (e.g., php, json-c). I assume that's for safety.

        Others expect you to escape it yourself when using it within the context of HTML. Ruby's ERB provides an escape_json method. Here's the essence of that:

        JSON_ESCAPE = { "&" => '\u0026', ">" => '\u003e', "<" => '\u003c', "\u +2028" => '\u2028', "\u2029" => '\u2029' } JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/u

        I've decided to move to Cpanel::JSON::XS, since it has support for more of the ::PP settings. And I've written a wrapper around it for our app that sets the appropriate defaults (e.g., escape_slash). I wrote a Perl version of the escape_json() from ERB.

        { my %escape = ( "&" => '\u0026', ">" => '\u003E', "<" => '\u003C', '\x{2028}' => '\u2028', '\x{2029}' => '\u2029', ); my $chars = join '', keys %escape; my $regex = qr/[$chars]/; sub escape_for_html { my $class = shift; @_ or croak 'no json supplied'; my @json = @_; foreach (@json) { s/($regex)/$escape{ $1 }/ge if defined; } return wantarray ? @json : join('', @json); } }