json_encode是否有足够的 XSS 保护?

2022-08-30 18:36:10

我在PHP中有一个对象,类似于stdClass

$o = new stdClass;
$o->foo = $bar

该变量包含不受信任的字符串。$bar

以下PHP模板代码是否足以保护XSS

<script type="text/javascript">
    var o = <?php echo json_encode($o); ?>;
</script>

我最初的直觉反应安全的,因为将对象编码为JSON将确保任何潜在的javascript攻击都将通过作为JSON字符串属性对象包含在内而呈现为惰性。类似的东西

$o = new stdClass;
$o->foo = "<script type=\"text/javascript\">alert(document.cookie)</script>";
?>
<script type="text/javascript">
    var o = <?php echo json_encode($o) ?>;    
</script>    

产生这样的输出

<script type="text/javascript">
    var o = {"foo":"<script type=\"text\/javascript\">alert(document.cookie) <\/script>"};    
</script>    

如果这是已知的不安全,是否有一种标准的、成熟的方法可以将简单对象序列化为 JSON 字符串,以便在 HTML 文档的某个部分使用。stdClass<script/>

在期待第一个快速答案时,我意识到剥离任何HTML标签,或者XSS过滤JSON对象的每个元素都会起作用,但我正在寻找一种简洁的方法。与此类似

//$eBar = addslashes($bar);
$sql = sprintf("SELECT * FROM table WHERE foo = '%s'",mysql_real_escape_string($bar));

和这个

$sql = $db->select('SELECT * from table where foo = ?', $bar);

(在大多数情况下)在功能上是等效的,但后者被认为是更好,更安全的代码,因为最终用户程序员用户不需要担心转义方案。


答案 1

似乎通过这个问题的最佳答案在于另一个问题

总而言之,PHP的JSON编码器对所有非ASCII字符进行转义,因此不能插入换行符/回车符来增加JSON属性的Javascript字符串部分。对于其他 JSON 编码器,情况可能并非如此。

但是,将原始字符串传递给 JSON 编码可能会导致通常的一连串 XSS 攻击,建议使用以下常量组合。

var v= <?php echo json_encode($value, JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS); ?>;

或者确保传递给的变量确实是一个对象。json_encode


答案 2

XSS非常广泛,实际上不可能随时知道您发出的不受信任的数据是否安全。

答案是,这取决于具体情况。 它不会自行转义 - 您仅将其用于序列化目的。要使用的转义函数是 。json_encodehtmlspecialchars

但是,您是否要使用取决于。例如,是否将插入 using 或 的值?后者会导致双重转义,但前者会插入脚本。如果您要使用(在JS中)呢?htmlspecialcharso.fooinnerHTMLtextContenteval

顺便说一句,在功能上并不等同于mysql转义。addslashes

我不会以这种方式混合JavaScript和PHP,但那是另一回事了。