开发者

JSON: why are forward slashes escaped?

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"} instea开发者_如何学编程d 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.

Harold L answered Oct 16 '09 at 21:59

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.

Seb answered Oct 16 '09 at 22:00 (#1580667)

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)


The JSON spec says you CAN escape forward slash, but you don't have to.


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.


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜