[javascript] 為什麼Google會在(1)之前提前; 他們的JSON回复?


Answers

它可以防止通過JSON劫持洩露響應。

理論上,HTTP響應的內容受同源策略保護:來自一個域的頁面無法從其他域上的頁面獲取任何信息(除非明確允許)。

攻擊者可以代表您在其他域上請求頁面,例如使用<script src=...><img>標記,但它無法獲取有關結果(標題,內容)的任何信息。

因此,如果您訪問攻擊者的頁面,它無法從gmail.com讀取您的電子郵件。

除了使用腳本標記來請求JSON內容之外,JSON在攻擊者的受控環境中作為Javascript執行。 如果攻擊者可以替換數組或對象構造函數或對象構造期間使用的其他方法,則JSON中的任何內容都將通過攻擊者的代碼並被披露。

請注意,這在JSON作為Javascript執行時發生,而不是在解析時。

有多種對策:

確保JSON永遠不會執行

while(1); 在JSON數據之前的聲明中,Google確保JSON數據永遠不會作為Javascript執行。

只有合法的頁面才能真正獲得整個內容,剝離while(1); ,並將餘數解析為JSON。

for(;;); 例如,在Facebook上看到了相同的結果。

確保JSON無效Javascript

同樣,在JSON之前添加無效標記,例如&&&START&&& ,確保它永遠不會被執行。

始終在外部返回帶有Object的JSON

這是OWASP推薦的防止JSON劫持的方法,並且是一種不那麼具有侵入性的方法。

與之前的反措施類似,它確保JSON永遠不會作為Javascript執行。

有效的JSON對象(未被任何內容包含)在Javascript中無效:

eval('{"foo":"bar"}')
// SyntaxError: Unexpected token :

但這是有效的JSON:

JSON.parse('{"foo":"bar"}')
// Object {foo: "bar"}

因此,確保始終在響應的頂層返回一個Object,確保JSON不是有效的Javascript,同時仍然是有效的JSON。

正如@hvd在評論中所指出的,空對象{}是有效的Javascript,並且知道對像是空的可能本身就是有價值的信息。

比較上述方法

OWASP方式不那麼具有侵入性,因為它不需要更改客戶端庫,並傳輸有效的JSON。 但是,不確定過去或未來的瀏覽器錯誤是否會破壞這一點。 正如@oriadam所指出的,目前還不清楚數據是否可以通過錯誤處理而在解析錯誤中洩露(例如window.onerror)。

谷歌的方式需要客戶端庫,以便它支持自動反序列化,並且可以被認為是更安全的瀏覽器錯誤。

這兩種方法都需要服務器端更改,以避免開發人員意外發送易受攻擊的JSON。

Question

為什麼Google會while(1);提前while(1); 他們的(私人)JSON響應?

例如,這是在Google日曆中打開和關閉日曆時的響應:

while(1);[['u',[['smsSentFlag','false'],['hideInvitations','false'],
  ['remindOnRespondedEventsOnly','true'],
  ['hideInvitations_remindOnRespondedEventsOnly','false_true'],
  ['Calendar ID stripped for privacy','false'],['smsVerifiedFlag','true']]]]

我認為這是為了防止人們對它進行eval() ,但你真正需要做的就是替換while ,然後你就可以了。 我認為eval預防是為了確保人們編寫安全的JSON解析代碼。

我已經在其他幾個地方看到了這種情況,但谷歌(郵件,日曆,聯繫人等)更多地使用了這一點。奇怪的是, 谷歌文檔&&&START&&&開頭,而谷歌聯繫人似乎始於while(1); &&&START&&& while(1); &&&START&&&

這裡發生了什麼?




由於<script >標籤免於同源策略,這是Web環境中的安全必需品,而(1)添加到JSON響應時可防止在<script>標記中濫用它。




這將使第三方難以將JSON響應插入帶有<script>標記的HTML文檔中。 請記住, <script>標記不受同源策略的約束




Related