2017-08-30 170 views
0

在我的網站中,來自用戶輸入的任何html標記都被htmlspecialchars轉義,然後我使用PHP json_encode發送html標記+轉義用戶內容作爲JSON變量,這將轉義所有「as \」,只有我放入因爲用戶輸入已經被轉義了。將JSON格式的HTML編碼爲HEX是必要的嗎?

這工作得很好,我沒有問題,我沒有看到如何XSS攻擊是可能的,我試過了。

但我看到Twitter和facebook將HEX所有的html標籤編碼,所以如果我要做同樣的事情,我會添加選項JSON_HEX_TAG JSON_HEX_AMP JSON_HEX_APOS JSON_HEX_QUOTjson_encode()

那麼,爲什麼Twitter和Facebook這樣做,爲什麼我應該?我無法創建安全錯誤。

+0

'在舊瀏覽器上'... erm,Edge是**不是** onlder瀏覽器 –

+0

@Jaromanda我的意思是它適用於我測試過的所有瀏覽器IE9 + Edge Firefox Chrome Opera。我只是說好奇,如果你看看JSON文件,那麼如果你輸入開發者工具並在網絡選項卡上搜索,那麼瀏覽器不會很好地着色「變成\」的變量。它在Edge上完美地工作,所以我只是作爲一個假設說,也許着色引擎沒有更新,它的工作原理和舊的瀏覽器會讀取JSON文件一樣,只是猜測。 – Vixxs

+0

所以,你的問題不是關於代碼的問題,而是關於開發者工具控制檯漂亮打印? –

回答

0

從XSS的角度來看,您的策略聽起來不錯。十六進制編碼可能支持其他語言/字符集?

+0

這個(多字節Unicode)在PHP 5.4.0之後默認完成,所以我也是這麼做的。他們編碼HTML標籤,因此:< >&「'作爲十六進制,默認的'json_encode'只能轉義爲」as「,它不會對HTML標籤進行編碼 – Vixxs

0

通常,您需要轉義括號和引號,因爲它們可以跳出周圍的html上下文。 json_encode本身僅在輸出到'.js'文件而沒有任何html的情況下才有用。

這兩種方法都可以防止XSS,但不同之處在於它們會產生不同的輸出。 htmlspecialchars將'<'轉換爲'& lt;' (一個html實體)和十六進制編碼將'<'轉換爲'\ u003C'(一個JavaScript字符串文字轉義序列)。如果您要將數據發送到JavaScript變量,那麼您需要使用JavaScript來確保數據的完整性。

假設你想發送消息「一個月的時間」到JavaScript。

用十六進制編碼,你寫的:

<script> 
    var input = <?php 
     $input = "One month's time"; 

     $input = json_encode($input, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT); 

     echo $input; 
    ?>; 
    console.log(input); 
</script> 

,它將輸出「一個月的時間」,只要你想。

隨着htmlspecialchars,你寫的:

<script> 
    var input = <?php 
     $input = "One month's time"; 

     $input = htmlspecialchars($input, ENT_QUOTES, "utf-8"); 
     $input = json_encode($input); 

     echo $input; 
    ?>; 
    console.log(input); 
</script> 

,它會輸出 「一個月&#039;時間」,這已損壞的數據。這是因爲它是HTML編碼的,但沒有直接插入到HTML上下文中。

如果要設置innerHTML屬性或類似屬性,儘管要阻止基於DOM的XSS,但應使用HTML編碼,但這可以使用JavaScript而不是PHP來完成。