PHP json_encode和XSS

Joh*_*ohn 1 javascript php xss json

这个问题已被多次询问.看到这里,这里这里

基于这些问题的答案,我做了一些测试,我不得不再次提出同样的问题,因为没有一个答案看起来是正确的(至少对我而言).如果我对主题的理解不好,请纠正我.

我正在为一个输出JSON响应的Web应用程序开发API.服务器端响应由json_encodePHP 处理.因为,这将是一个公共API,我希望通过使用API​​的开发者不正确的客户端实现来阻止任何XSS.

对于我的测试,我在服务器端执行了以下操作:

header("Content-Type: application/json", true);
$bad = array('bad_key' => 'alert("hi");');
echo json_encode($bad);
Run Code Online (Sandbox Code Playgroud)

在客户端,我使用jQuery AJAX自动解析收到的JSON.最初这似乎没有显示任何XSS问题.然后我response.bad_key去了eval().

eval(response.bad_key);
Run Code Online (Sandbox Code Playgroud)

这立即导致执行字符串bad_key.我知道使用eval不好,应该避免.但是,这是我所知道的,并不能确保其他开发人员遵循相同的做法.为了避免这种情况,解决方案是执行服务器端编码.为此,让我说我用htmlspecialchars.

header("Content-Type: application/json", true);
$bad = array('bad_key' => htmlspecialchars('alert("hi");'));
echo json_encode($bad);
Run Code Online (Sandbox Code Playgroud)

这虽然它不执行alert("hi");客户端但由于存在而破坏了JS代码&.json_encode使用此处JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS建议的选项也无济于事.

那么如何在这种情况下阻止XSS呢?

Thi*_*ter 9

在这种情况下,您无需阻止"XSS".如果有人愚蠢地执行一些随机数据,你将其作为JavaScript发送,那么你无法对付它.实际上,如果你确实逃脱了某些东西以防止它,他可能会不再使它再次起作用.

请注意,使用eval解析 JSON字符串是偏于安全(假设你发送有效的JSON) -尽管它在任何现代的浏览器,有一个我们native气馁JSON.parse().但在您的示例中,您不使用它来解析JSON,而是执行一些随机数据串!当任何人这样做时,这意味着他希望它作为代码执行 - 所以它不是XSS而是"按预期工作"!