The reason for this "escapes" me.
JSON escapes the forward slash, so a hash {a: "a/b/c"}
is serialized as {"a":"a\/b\/c"}
instead of {"a":"a/b/c"}
.
Why?
The reason for this "escapes" me.
JSON escapes the forward slash, so a hash {a: "a/b/c"}
is serialized as {"a":"a\/b\/c"}
instead of {"a":"a/b/c"}
.
Why?
JSON doesn't require you to do that, it allows you to do that. It also allows you to use "\u0061" for "A", but it's not required, like Harold L points out:
The JSON spec says you CAN escape forward slash, but you don't have to.
Allowing \/
helps when embedding JSON in a <script>
tag, which doesn't allow </
inside strings, like Seb points out:
This is because HTML does not allow a string inside a
<script>
tag to contain</
, so in case that substring's there, you should escape every forward slash.
Some of Microsoft's ASP.NET Ajax/JSON API's use this loophole to add extra information, e.g., a datetime will be sent as "\/Date(milliseconds)\/"
. (Yuck)
var f = <= xxx.to_json %>;
. It should definitely not escape all forward slashes--it makes every JSON-encoded URL longer, instead of just the rare edge case. –
Distemper RegExp
for ISO 8601 to a Date
object or needing a separate key to indicate whether the serialized value is a pure string or a Date
. –
Gargan /
is not required, it is allowed, to ease the use of JSON. If you don't want to escape /
, then don't. –
Woodshed </
is just fine within a script
tag. It's only </script>
(perhaps with spaces in there) that terminates them. –
Povertystricken </
inside <script>
(and <style>
). Because, how should a browser treat <div><script>["</div>"]</script>
? You could (should?) interpret this as <div><script>["</script></div><script>"]</script>
. As this is how it should be parsed if you'd change <script>
for <b>
. It was only the HTML 5 spec that changed this to </script
. In the good old days, we even used <script><!-- ... //--></script>
(and other magic incantations) just to be absolutely sure the content of a script tag was not misinterpreted. –
Cartogram </
, without having to look ahead for script
, so why bother. –
Cartogram /
is faster than replacing, say, </
? It would at least minimize bloat. But in any case, it's handling the issue at the wrong level (JSON rather than the point at which you're using JSON in a script
tag, if it happens you are). –
Povertystricken </
is marginally slower than looking for just /
because you need track what the previous character was. Blindly replacing /
is just simpler, and that's what happens for all the reserved characters too. Besides, the JSON spec still allows you to not escape /
. So if you don't like the bloat: use/write a JSON formatter that doesn't escape /
. No-one is forcing you to do either way, as it's an optional encoding feature. –
Cartogram </
just as fast as /
. But it's not particularly important, it's still handling it at the wrong level. –
Povertystricken <script type="text/javascript"><!--//--><![CDATA[//><!--
… //--><!]]></script>
form, which, using a CDATA, escapes (hah!) this problem as well. (To the curious: <style type="text/css"><!--/*--><![CDATA[/*><!--*/
… /*]]>*/--></style>
is the matching “proper” escape for CSS, and both are also XHTML/1.1 clean.) –
Dilettantism json_encode()
and should properly escape JSON embedded in an HTML document to avoid XSS. See Rule #3.1 of the OWASP cheatsheet. –
Monadelphous <
and >
are unsafe characters, and <\/script>
is thus inadequate encoding to prevent XSS. Are you aware of an exploit for this, as I can’t yet see how it might be exploited. –
Amon </
is faster. <
occurs less than /
. It's also likely faster even if <
appears a ton because you don't have to take any action other than setting and unsetting a flag in the vast majority of cases (i.e. unless </
appears instead of just <
or /
). –
Cathiecathleen The JSON spec says you CAN escape forward slash, but you don't have to. A reverse solidus must be escaped, but you do not need to escape a solidus. Section 9 says
"All characters may be placed within the quotation marks except for the characters that must be escaped: quotation mark (U+0022), reverse solidus (U+005C), and the control characters U+0000 to U+001F."
PHP escapes forward slashes by default which is probably why this appears so commonly. I suspect it's because embedding the string "</script>"
inside a <script>
tag is considered unsafe.
Example:
<script>
var searchData = <?= json_encode(['searchTerm' => $_GET['search'], ...]) ?>;
// Do something else with the data...
</script>
Based on this code, an attacker could append this to the page's URL:
?search=</script> <some attack code here>
Which, if PHP's protection was not in place, would produce the following HTML:
<script>
var searchData = {"searchTerm":"</script> <some attack code here>"};
...
</script>
Even though the closing script tag is inside a string, it will cause many (most?) browsers to exit the script tag and interpret the items following as valid HTML.
With PHP's protection in place, it will appear instead like this, which will NOT break out of the script tag:
<script>
var searchData = {"searchTerm":"<\/script> <some attack code here>"};
...
</script>
This functionality can be disabled by passing in the JSON_UNESCAPED_SLASHES
flag but most developers will not use this since the original result is already valid JSON.
<script>let the = "bodies </script><script>alert("the floor");</script>";</script>
Try it, the bodies will alert the floor rather than getting a variable called 'the' with script tags in its value. You can say "then don't embed it in a page", yeah, that's a possible workaround, but a lot of people do this anyway (so let's just make good escape functions because why not) and frankly I understand their point: it would make sense if it were safe to have JSON data with correctly escaped data values in JavaScript. –
Mantinea htmlspecialchars()
will work in this scenario. The slashes are still required.) –
Amon I asked the same question some time ago and had to answer it myself. Here's what I came up with:
It seems, my first thought [that it comes from its JavaScript roots] was correct.
'\/' === '/'
in JavaScript, and JSON is valid JavaScript. However, why are the other ignored escapes (like\z
) not allowed in JSON?The key for this was reading http://www.cs.tut.fi/~jkorpela/www/revsol.html, followed by http://www.w3.org/TR/html4/appendix/notes.html#h-B.3.2. The feature of the slash escape allows JSON to be embedded in HTML (as SGML) and XML.
Yes, some JSON utiltiy libraries do it for various good but mostly legacy reasons. But then they should also offer something like setEscapeForwardSlashAlways method to set this behaviour OFF.
In Java, org.codehaus.jettison.json.JSONObject does offer a method called
setEscapeForwardSlashAlways(boolean escapeForwardSlashAlways)
to switch this default behaviour off.
© 2022 - 2024 — McMap. All rights reserved.
json_encode()
escapes forward slashes by default, but has theJSON_UNESCAPED_SLASHES
option starting from PHP 5.4.0 (March 2012) – Mannered'</'
:echo str_replace('</', '<\/', json_encode($obj, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
– Camilia