Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 我有时看到人们用htmlspecialchars()包装json_encode()。为什么?_Php_Javascript_Json - Fatal编程技术网

Php 我有时看到人们用htmlspecialchars()包装json_encode()。为什么?

Php 我有时看到人们用htmlspecialchars()包装json_encode()。为什么?,php,javascript,json,Php,Javascript,Json,我通常这样做: echo json_encode($result); 但我看到人们有时会这样做: echo htmlspecialchars( json_encode($result), ENT_NOQUOTES ); 为什么要在JSON上使用htmlspecialchars?在JSON中具有特殊含义的字符在HTML中没有特殊含义(除了ENT\u NOQUOTES明确排除的引号字符) 它可以通过innerHTML将数据安全地转储到HTML文档中(只要它不放在属性值中)。自然地,它会使数据在不

我通常这样做:

echo json_encode($result);
但我看到人们有时会这样做:

echo htmlspecialchars( json_encode($result), ENT_NOQUOTES );

为什么要在JSON上使用htmlspecialchars?

在JSON中具有特殊含义的字符在HTML中没有特殊含义(除了
ENT\u NOQUOTES
明确排除的引号字符)

它可以通过
innerHTML
将数据安全地转储到HTML文档中(只要它不放在属性值中)。自然地,它会使数据在不涉及使用字符串构建标记的任何情况下都不安全


我不建议这样做(在一般情况下),转义应该在插入所需数据格式之前的最后一刻完成(以最大限度地提高可重用性,并明确开发人员应该在哪里看到转义代码)。

我不懂php,所以我假设htmlspecialchars转义任何html特殊字符

基于这个假设,用例将json数据直接植入html内容中

echo "<script>"
echo json_encode($result)
echo "</script>"
echo“”
echo json_编码($result)
回声“”
鉴于json编码仅对内容进行编码以避免从JS解析器中转义,此场景将允许有人插入json数据,html解析器将其解释为结束脚本标记

差不多

{"foo": "</script><script>doSomethingEvil()</script>"}
<script>{"foo": "&lt;/script&gt;&lt;script&gt;doSomethingEvil()&lt;/script&gt;"}<script>
{“foo”:“doSomethingEvil()”}
然后将作为

<script>{"foo": "</script><script>doSomethingEvil()</script>"}<script>
{“foo”:“doSomethingEvil()”}
这显然会导致doSomethingEvil()被执行。通过转义任何html标记,您最终会发送如下内容

{"foo": "</script><script>doSomethingEvil()</script>"}
<script>{"foo": "&lt;/script&gt;&lt;script&gt;doSomethingEvil()&lt;/script&gt;"}<script>
{“foo”:/scriptdosomethingevil()/script}
相反,它避免了XSS漏洞


解决这个问题的更好办法是不直接在HTML源代码中发送JSON数据(JSON编码只是让内容安全地嵌入到JS中,而不是HTML中)

olliej的答案很好,但有一个案例他们没有涉及

为什么要在JSON上使用htmlspecialchars

如果要在CDATA部分之外嵌入XHTML中的脚本标记,则应转义XML特殊字符
htmlspecialchars
应该可以很好地实现这一点


这是一个相当边缘化的例子,尽管如此,请接受olliej的建议。

一个简单的字符串替换(
它实际上将其编码为
{“foo”:“doSomethingEvil()”}
(注意转义的斜杠)。所以我认为这是安全的。@Quentin,这还不够。您还需要防止JSON包含可能会阻止浏览器识别合法脚本结束标记的内容。@JW-ah,JSON_相对于ECMAScript中的JSON.stringify进行编码转义(规范规定不转义/)--可以想象,由于它主要针对浏览器json_encode(至少在现代php版本中是这样)“过度转义”所有可能不安全的html内容。事实上,我很确定它也会使数据在属性值中使用时安全。它不会。问题中的代码是
ENT\u NOQUOTES
,因此它会保留引号字符不变。字符串分隔符会破坏用双引号分隔的属性值。作为数据的单引号将reak属性值用单引号分隔。对,我错过了ENT_NOQUOTES.JSON_HEX_标记、JSON_HEX_APOS、JSON_HEX_AMP和JSON_HEX_QUOT,因为PHP 5.3可以使用。Symfony的JsonResponse是这些选项的真实示例之一: