简体   繁体   English

json_encode 是否有足够的 XSS 保护?

[英]Is json_encode Sufficient XSS Protection?

I have a stdClass object in PHP, something like我在 PHP 中有一个stdClass对象,类似于

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

The variable $bar contains an untrusted string.变量$bar包含一个不受信任的字符串。

Is the following PHP template code sufficient XSS protection以下 PHP 模板代码是否足够 XSS 保护

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

My initial gut reaction is that is is safe, as encoding an object as JSON will ensure any potential javascript exploits will be rendered inert by being included as JSON string property objects.我的初始直觉反应是是安全的,因为编码对象作为JSON将确保任何潜在的javascript漏洞将通过被包括作为JSON串属性的对象被赋予惰性。 Something like this像这样的东西

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

Resulting in output like this导致这样的输出

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

If this is known unsafe, is there's a standard, mature way of serializing a simple stdClass object to a JSON string for use in a the <script/> portion of an HTML document.如果已知这是不安全的,是否有一种标准的、成熟的方法可以将简单的stdClass对象序列化为 JSON 字符串,以便在 HTML 文档的<script/>部分中使用。

In anticipation of the first quick answer, I realize that stripping out any HTML tags, or otherwise XSS filtering each element of the JSON object would work, but I'm looking for a concise way of doing this.在期待第一个快速答案时,我意识到去除任何 HTML 标签或以其他方式对 JSON 对象的每个元素进行 XSS 过滤都是可行的,但我正在寻找一种简洁的方法来做到这一点。 Similar to how this类似于这个

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

and this还有这个

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

are (in most contexts) functionally equivalent, but the later is considered better, more secure code since the end programmer user doesn't need to worry about escaping schemes. (在大多数情况下)在功能上是等效的,但后者被认为是更好、更安全的代码,因为最终程序员用户不需要担心转义方案。

Seems as through the best answer to this question lies in another question .似乎通透这个问题的最佳答案在于另一个问题

To sum up, PHP's JSON encoder escapes all non ASCII characters, so newlines/carriage returns can't be inserted to bollacks up the Javascript string portion of the JSON property.总而言之,PHP 的 JSON 编码器会转义所有非 ASCII 字符,因此无法插入换行符/回车符来对 JSON 属性的 Javascript 字符串部分进行加注。 This may not be true of other JSON encoders.其他 JSON 编码器可能并非如此。

However, passing in a raw string to JSON encode can lead to the usual litany of XSS attacks, the following combination of constants is suggested.但是,将原始字符串传递给 JSON 编码会导致常见的 XSS 攻击,建议使用以下常量组合。

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

or ensure the variable passed to json_encode is really an object.或者确保传递给json_encode的变量确实是一个对象。

XSS is very broad and it's actually impossible to know at any time whether untrusted data you are emitting is safe. XSS 非常广泛,实际上不可能随时知道您发出的不受信任的数据是否安全。

The answer is really that it depends on the situation.答案是真的要视情况而定。 json_encode does no escaping on its own whatsoever -- you're only using it for serialization purposes. json_encode不会自行转义 - 您仅将其用于序列化目的。 The escape function you want to use would be htmlspecialchars .您要使用的转义函数是htmlspecialchars

However , whether or not you even want to use htmlspecialchars depends.但是,您是否甚至想使用htmlspecialchars取决于。 For example, will you insert the value of o.foo using innerHTML or textContent ?例如,您会使用innerHTMLtextContent插入o.foo的值吗? The latter would lead to a double-escape, but the former would insert a script.后者会导致双重转义,但前者会插入脚本。 What about if you were going to use eval (in JS)?如果您打算使用eval (在 JS 中)呢?

By the way addslashes is not functionally equivalent to mysql escaping.顺便说一句, addslashes在功能上并不等同于 mysql 转义。

I wouldn't mix JavaScript and PHP in this way to begin with, but that's another story.我不会以这种方式混合 JavaScript 和 PHP,但那是另一回事了。

this will work ;)这会起作用;)

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

with json_encode ...使用 json_encode ...

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

;) ;)

What I do is to evaluate the json object before assuming its safe.我所做的是在假设它是安全的之前评估 json 对象。 I think the method is evalJSON(true) in prototype and jquery has a similar implementation.我认为该方法是原型中的 evalJSON(true) 并且 jquery 具有类似的实现。 I don't know much about xss standards with JSON but this helps me我不太了解 JSON 的 xss 标准,但这对我有帮助

As other answers have said;正如其他答案所说; json_encode is not built for anti-xss protections. json_encode 不是为反 xss 保护而构建的。 Unless you specifically encode the unsafe string (or sanitize properly) you're going to have a potential issue.除非您专门对不安全的字符串进行编码(或正确清理),否则您将遇到潜在问题。

Furthermore, once that string is extracted from the JSON object, it is still potentially hazardous if injected into the page at any point.此外,一旦该字符串从 JSON 对象中提取出来,如果在任何时候注入到页面中,它仍然存在潜在危险。 For example:例如:

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

isn't likely to execute (although you can't be certain).不太可能执行(虽然你不能确定)。 But if you were to do:但如果你要这样做:

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

you would absolutely encounter a vulnerability.你绝对会遇到一个漏洞。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM