2010-08-25 68 views
2

與許多開發人員一樣,我想通過服務器「A」與服務器「B」上的Web服務對話來提供JavaScript,但受當前版本same origin policy的阻礙。解決這個問題的最安全的方式(我可以找到)是一個服務器腳本,它位於服務器「A」上,充當它與「B」之間的代理。但是,如果我想在各種客戶環境(RoR,PHP,Python,.NET等)中部署此JavaScript,並且無法爲它們編寫代理腳本,我該怎麼做?使用JSONP,some people say。那麼,Doug Crockford指出on his websitein interviews腳本標記hack(由JSONP使用)是一種不安全的方式來繞過相同的原始策略。 「A」服務的腳本無法驗證「B」是否是他們自稱的用戶,並且它返回的數據不是惡意的,或者將捕獲該頁面上的敏感用戶數據(例如信用卡號碼)和傳送給卑鄙的人。這似乎是一個合理的擔憂,但如果我只是使用腳本標記hack本身並嚴格使用JSON進行通信呢?那安全嗎?如果不是,爲什麼不呢?使用HTTPS會更安全嗎?示例場景將不勝感激。腳本標記黑客安全執行XSS?

附錄:需要支持IE6。第三方瀏覽器擴展不是一個選項。讓我們繼續討論腳本標記黑客的優點和風險。

+0

你是什麼意思?如果我只是使用腳本標記本身進行破解,並嚴格使用JSON進行通信? – 2010-08-27 17:03:12

+0

由「A」提供的腳本將包括一個將腳本標記附加到客戶端DOM的語句。該腳本標記將包含一個AJAX調用,該調用將從不同域中的「B」獲取純JSON數據。如果由「A」提供的腳本將響應解析爲JSON,那麼是否有任何JavaScript填充(又名JSONP,惡意或其他)會導致解析錯誤? – Adam 2010-08-27 19:38:27

回答

0

向所有試圖回答我的問題的人道歉。它在假設腳本標記如何工作​​的假設下進行。假設可以簡單地將一個腳本標籤附加到DOM,並且該附加腳本標籤的內容不會受到相同的源策略的限制。

如果我在發佈問題之前試圖測試我的假設,我會知道它是源屬性的附加標籤是不受限制的。 JSONP通過建立一個將傳統JSON Web服務響應封裝在回調函數中的協議,進一步推進了這一進程。

但是,無論如何使用腳本標記黑客,都無法篩選惡意代碼的響應,因爲瀏覽器會執行任何返回的JavaScript。在這種情況下,IE,Firefox和Webkit瀏覽器都不檢查SSL證書。據我所知,Doug Crockford是正確的。從JavaScript 1.8.5開始,沒有安全的跨域腳本編寫方法。

2

目前瀏覽器供應商是如何跨域JavaScript應該如何工作。 Flash的Crossdomain.xml file是一款安全易用的optoin。大多數語言都有爲他們編寫的Cross Domain Proxies,它們是開源的。

更惡毒的解決方案將是使用xss如何Sammy Worm傳播。 XSS可用於使用xmlhttprequest「讀取」遠程域。如果其他域添加了<script src="https://YOUR_DOMAIN"></script>,則不需要XSS。這樣的腳本標籤允許您在另一個域的上下文中評估自己的JavaScript,這與XSS完全相同。

同樣重要的是要注意,即使對同一起源策略有限制,您可以讓瀏覽器向任何域傳輸請求,但您無法讀取響應。這是CSRF的基礎。您可以動態地將不可見的圖像標籤寫入頁面,以使瀏覽器發出無限數量的GET請求。這種圖像標籤的使用是攻擊者在另一個域上使用XSS獲得documnet.cookie的方式。 CSRF POST通過構建表單並在表單對象上調用.submit()來開發工作。

要理解相同的訂單政策,CSRF和XSS更好,您必須閱讀Google Browser Security Handbook

0

如果我只是使用腳本標記hack本身並嚴格使用JSON進行通信,該怎麼辦?那安全嗎?如果不是,爲什麼不呢?

假設你有兩臺服務器--frontend.com和backend.com。 frontend.com包含一個<script>這樣的標籤 - <script src="http://backend.com/code.js"></script>

當瀏覽器評估code.js被認爲是frontend.com的一部分而不是backend.com的一部分。因此,如果code.js包含XHR代碼與backend.com進行通信,則將失敗

使用HTTPS會更安全嗎?示例場景將不勝感激。

如果你只是轉換了您<script src="https://backend.com/code.js>爲https,這將是任何安全。如果頁面的其餘部分是http,那麼攻擊者可以輕鬆地在頁面的中間位置修改https,甚至包括他自己的JavaScript文件。

如果將整個頁面及其所有組件轉換爲https,則會更安全。但是,如果你足夠偏執,那麼你也應該偏執於不依靠外部服務器來爲你提供數據。如果攻擊者損害了backend.com,他已經在frontend.com,frontend2.com和所有網站上獲得了足夠的優勢。

簡而言之,https是有用的,但如果您的後端服務器受到攻擊,它無法幫助您一點。

那麼,我的選擇是什麼?

  1. 在每個客戶端應用程序中添加代理服務器。你不需要編寫任何代碼,你的web服務器可以自動爲你做。如果您使用的是Apache,請查看mod_rewrite
  2. 如果您的用戶使用最新的瀏覽器,則可以考慮使用Cross Origin Resource Sharing
  3. 正如Rook指出的,你也可以使用Flash + Crossdomain。或者你可以使用Silverlight及其等效的Crossdomain。這兩種技術都可以讓你與javascript通信 - 所以你只需要編寫一個實用程序函數,然後正常的js代碼就可以工作。我相信YUI已經爲此提供了一個閃存封裝 - 檢查YUI3 IO

你有什麼建議?

我的建議是創建一個代理服務器,並在整個網站中使用https。

1

看一看easyXDM,它是一個乾淨的JavaScript庫,允許您跨域邊界進行通信而無需任何服務器端交互。它甚至支持RPC開箱即用。
它支持所有'現代'瀏覽器,以及IE6與運輸時間< 15毫秒。

一個常見的用例是使用它來公開一個ajax端點,使您可以輕鬆地完成跨域ajax(查看首頁上的小樣本)。