这个问题已经被问过很多次了。参见 here , here和 here
根据这些问题的答案,我做了一些测试,但我不得不再次问同样的问题,因为没有一个答案似乎是正确的(至少对我而言)。如果我对主题的理解不好,请纠正我。
我正在为输出 JSON 响应的网络应用开发 API。服务器端响应由 PHP 中的 json_encode
处理。因为,这将是一个公共(public) API,我想防止任何 XSS 由于开发者使用 API 的客户端实现不正确。
对于我的测试,我在服务器端执行了以下操作:
header("Content-Type: application/json", true);
$bad = array('bad_key' => 'alert("hi");');
echo json_encode($bad);
在客户端,我使用的是自动解析收到的 JSON 的 jQuery AJAX。最初这似乎没有显示任何 XSS 问题。然后我将 response.bad_key
传递给 eval()
。
eval(response.bad_key);
这立即导致执行 bad_key
中的字符串。我知道使用 eval
是不好的,应该避免。但是,这是我所知道的,无法确保其他开发人员遵循相同的做法。为了避免这种情况,一种解决方案是执行服务器端编码。为此,假设我使用 htmlspecialchars
。
header("Content-Type: application/json", true);
$bad = array('bad_key' => htmlspecialchars('alert("hi");'));
echo json_encode($bad);
虽然它不执行 alert("hi");
客户端,但由于 &
的存在而破坏了 JS 代码。 json_encode
与选项 JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS
建议 here也无济于事。
那么在这种情况下我该如何防止XSS呢?
最佳答案
在这种情况下你不需要阻止“XSS”。如果有人愚蠢到执行一些你作为 JavaScript 发送给他的随机数据,那么你无能为力。实际上,如果您确实转义某些东西以防止它发生,他可能会转义它以使其再次起作用。
请注意,使用 eval
来解析 JSON 字符串在某种程度上是安全的(假设您发送有效的 JSON)——尽管在任何具有原生 JSON.parse()
。
但是在您的示例中,您不使用它来解析 JSON,而是执行一些随机的数据字符串!当任何人这样做时,这意味着他希望它作为代码执行 - 所以它不是 XSS,而是“按预期工作”!
关于PHP json_encode 和 XSS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16608873/