簡體   English   中英

json_encode 是否有足夠的 XSS 保護?

[英]Is json_encode Sufficient XSS Protection?

我在 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>    

如果已知這是不安全的,是否有一種標准的、成熟的方法可以將簡單的stdClass對象序列化為 JSON 字符串,以便在 HTML 文檔的<script/>部分中使用。

在期待第一個快速答案時,我意識到去除任何 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);

(在大多數情況下)在功能上是等效的,但后者被認為是更好、更安全的代碼,因為最終程序員用戶不需要擔心轉義方案。

似乎通透這個問題的最佳答案在於另一個問題

總而言之,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的變量確實是一個對象。

XSS 非常廣泛,實際上不可能隨時知道您發出的不受信任的數據是否安全。

答案是真的要視情況而定。 json_encode不會自行轉義 - 您僅將其用於序列化目的。 您要使用的轉義函數是htmlspecialchars

但是,您是否甚至想使用htmlspecialchars取決於。 例如,您會使用innerHTMLtextContent插入o.foo的值嗎? 后者會導致雙重轉義,但前者會插入腳本。 如果您打算使用eval (在 JS 中)呢?

順便說一句, addslashes在功能上並不等同於 mysql 轉義。

我不會以這種方式混合 JavaScript 和 PHP,但那是另一回事了。

這會起作用;)

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

使用 json_encode ...

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

;)

我所做的是在假設它是安全的之前評估 json 對象。 我認為該方法是原型中的 evalJSON(true) 並且 jquery 具有類似的實現。 我不太了解 JSON 的 xss 標准,但這對我有幫助

正如其他答案所說; json_encode 不是為反 xss 保護而構建的。 除非您專門對不安全的字符串進行編碼(或正確清理),否則您將遇到潛在問題。

此外,一旦該字符串從 JSON 對象中提取出來,如果在任何時候注入到頁面中,它仍然存在潛在危險。 例如:

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

不太可能執行(雖然你不能確定)。 但如果你要這樣做:

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

你絕對會遇到一個漏洞。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM