我“搞不懂”其中的原因。JSON转义了正斜杠,因此哈希{a: "a/b/c"}被序列化为{"a":"a\/b\/c"}而不是{"a":"a/b/c"}。为什么?
{a: "a/b/c"}
{"a":"a\/b\/c"}
{"a":"a/b/c"}
t2a7ltrp1#
JSON并不要求你这么做,它允许你这么做。它也允许你使用“\u0061”来表示“A”,但它不是必需的,就像Harold L指出的那样:JSON规范规定可以转义正斜杠,但实际上并不是必须这样做。
在<script>标签中嵌入JSON时,允许\/是有帮助的,这不允许在字符串中使用</,就像Seb指出的那样:这是因为HTML不允许<script>标签中的字符串包含</,所以如果子字符串在那里,你应该转义每个正斜杠。
<script>
\/
</
一些微软的ASP AJAX /API使用这个漏洞来添加额外的信息,例如,日期时间将被发送为"\/Date(milliseconds)\/"。
"\/Date(milliseconds)\/"
ncgqoxb02#
JSON规范规定可以转义正斜杠,但实际上并不是必须这样做。
i1icjdpr3#
前段时间我问了the same question,不得不自己回答,以下是我的回答:看来,我的第一个想法[* 它来自它的JavaScript roots*]是正确的。JavaScript中的'\/' === '/',JSON * 是 * 有效的JavaScript。但是,为什么JSON中不允许其他被忽略的转义(如\z)?关键是阅读http://www.cs.tut.fi/~jkorpela/www/revsol.html,然后是http://www.w3.org/TR/html4/appendix/notes.html#h-B.3.2。斜杠转义的特性允许JSON嵌入到HTML(作为SGML)和XML中。
'\/' === '/'
\z
nc1teljy4#
PHP escapes forward slashes by default这可能就是为什么它出现的如此普遍。我怀疑这是因为在<script>标签中嵌入字符串"</script>"被认为是不安全的。示例:
"</script>"
<script> var searchData = <?= json_encode(['searchTerm' => $_GET['search'], ...]) ?>; // Do something else with the data... </script>
基于此代码,攻击者可以将此代码附加到页面的URL:
?search=</script> <some attack code here>
如果PHP的保护不到位,将产生以下HTML:
<script> var searchData = {"searchTerm":"</script> <some attack code here>"}; ... </script>
即使结束的script标签是在一个字符串中,它也会导致许多(大多数?)浏览器退出script标签,并将后面的项目解释为有效的HTML。有了PHP的保护,它将显示为这样,它不会打破脚本标记:
<script> var searchData = {"searchTerm":"<\/script> <some attack code here>"}; ... </script>
通过传入JSON_UNESCAPED_SLASHES标志可以禁用此功能,但大多数开发人员不会使用此功能,因为原始结果已经是有效的JSON。
JSON_UNESCAPED_SLASHES
46qrfjad5#
是的,一些JSON实用程序库出于各种好的但主要是遗留的原因这样做。但是他们也应该提供类似setEscapeForwardSlashAlways方法来设置此行为OFF。在Java中,org.codehaus.jettison.json.JSONObject确实提供了一个名为
setEscapeForwardSlashAlways(boolean escapeForwardSlashAlways)
来关闭此默认行为。
5条答案
按热度按时间t2a7ltrp1#
JSON并不要求你这么做,它允许你这么做。它也允许你使用“\u0061”来表示“A”,但它不是必需的,就像Harold L指出的那样:
JSON规范规定可以转义正斜杠,但实际上并不是必须这样做。
在
<script>
标签中嵌入JSON时,允许\/
是有帮助的,这不允许在字符串中使用</
,就像Seb指出的那样:这是因为HTML不允许
<script>
标签中的字符串包含</
,所以如果子字符串在那里,你应该转义每个正斜杠。一些微软的ASP AJAX /API使用这个漏洞来添加额外的信息,例如,日期时间将被发送为
"\/Date(milliseconds)\/"
。ncgqoxb02#
JSON规范规定可以转义正斜杠,但实际上并不是必须这样做。
i1icjdpr3#
前段时间我问了the same question,不得不自己回答,以下是我的回答:
看来,我的第一个想法[* 它来自它的JavaScript roots*]是正确的。
JavaScript中的
'\/' === '/'
,JSON * 是 * 有效的JavaScript。但是,为什么JSON中不允许其他被忽略的转义(如\z
)?关键是阅读http://www.cs.tut.fi/~jkorpela/www/revsol.html,然后是http://www.w3.org/TR/html4/appendix/notes.html#h-B.3.2。斜杠转义的特性允许JSON嵌入到HTML(作为SGML)和XML中。
nc1teljy4#
PHP escapes forward slashes by default这可能就是为什么它出现的如此普遍。我怀疑这是因为在
<script>
标签中嵌入字符串"</script>"
被认为是不安全的。示例:
基于此代码,攻击者可以将此代码附加到页面的URL:
如果PHP的保护不到位,将产生以下HTML:
即使结束的script标签是在一个字符串中,它也会导致许多(大多数?)浏览器退出script标签,并将后面的项目解释为有效的HTML。
有了PHP的保护,它将显示为这样,它不会打破脚本标记:
通过传入
JSON_UNESCAPED_SLASHES
标志可以禁用此功能,但大多数开发人员不会使用此功能,因为原始结果已经是有效的JSON。46qrfjad5#
是的,一些JSON实用程序库出于各种好的但主要是遗留的原因这样做。但是他们也应该提供类似setEscapeForwardSlashAlways方法来设置此行为OFF。
在Java中,org.codehaus.jettison.json.JSONObject确实提供了一个名为
setEscapeForwardSlashAlways(boolean escapeForwardSlashAlways)
来关闭此默认行为。