22

stdClass在 PHP 中有一个对象,例如

$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>    

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

期待第一个快速答案,我意识到剥离任何 HTML 标记,或者以其他方式过滤 JSON 对象的每个元素的 XSS 都可以,但我正在寻找一种简洁的方法来做到这一点。类似于这个

//$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);

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

4

5 回答 5

10

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

总而言之,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确实是一个对象。

于 2012-08-22T15:34:40.233 回答
2

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

答案真的是视情况而定。 json_encode不会自行转义——您只是将它用于序列化目的。您要使用的转义函数是htmlspecialchars.

但是,您是否甚至要使用htmlspecialchars取决于。例如,您会插入o.foousing innerHTMLor的值textContent吗?后者会导致双重转义,但前者会插入脚本。如果你打算使用eval(在 JS 中)呢?

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

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

于 2012-08-21T20:06:36.587 回答
2

这将工作;)

...?payload=<img%20src=x%20onerror=alert(document.cookie);>

用 json_encode ...

<?php echo json_encode($_GET['payload']); ?>

;)

于 2020-08-27T16:46:17.760 回答
1

我所做的是在假设它是安全的之前评估 json 对象。我认为该方法是原型中的 evalJSON(true) ,而 jquery 具有类似的实现。我对 JSON 的 xss 标准了解不多,但这对我有帮助

于 2012-08-21T20:13:05.797 回答
0

正如其他答案所说;json_encode 不是为反 xss 保护而构建的。除非您专门对不安全的字符串进行编码(或正确清理),否则您将遇到潜在问题。

此外,一旦从 JSON 对象中提取了该字符串,如果在任何时候注入到页面中,它仍然具有潜在的危险。例如:

<?php $a->foo = "<script>alert(1)</script>"; ?>
var v = <?php echo json_encode($a); ?>

不太可能执行(尽管您不能确定)。但如果你这样做:

$('#some-element').html(v.foo);

你绝对会遇到一个漏洞。

于 2015-04-21T22:07:40.593 回答